kankan-sdk-deps.js 2.5 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879498804988149882498834988449885498864988749888498894989049891498924989349894498954989649897498984989949900499014990249903499044990549906499074990849909499104991149912499134991449915499164991749918499194992049921499224992349924499254992649927499284992949930499314993249933499344993549936499374993849939499404994149942499434994449945499464994749948499494995049951499524995349954499554995649957499584995949960499614996249963499644996549966499674996849969499704997149972499734997449975499764997749978499794998049981499824998349984499854998649987499884998949990499914999249993499944999549996499974999849999500005000150002500035000450005500065000750008500095001050011500125001350014500155001650017500185001950020500215002250023500245002550026500275002850029500305003150032500335003450035500365003750038500395004050041500425004350044500455004650047500485004950050500515005250053500545005550056500575005850059500605006150062500635006450065500665006750068500695007050071500725007350074500755007650077500785007950080500815008250083500845008550086500875008850089500905009150092500935009450095500965009750098500995010050101501025010350104501055010650107501085010950110501115011250113501145011550116501175011850119501205012150122501235012450125501265012750128501295013050131501325013350134501355013650137501385013950140501415014250143501445014550146501475014850149501505015150152501535015450155501565015750158501595016050161501625016350164501655016650167501685016950170501715017250173501745017550176501775017850179501805018150182501835018450185501865018750188501895019050191501925019350194501955019650197501985019950200502015020250203502045020550206502075020850209502105021150212502135021450215502165021750218502195022050221502225022350224502255022650227502285022950230502315023250233502345023550236502375023850239502405024150242502435024450245502465024750248502495025050251502525025350254502555025650257502585025950260502615026250263502645026550266502675026850269502705027150272502735027450275502765027750278502795028050281502825028350284502855028650287502885028950290502915029250293502945029550296502975029850299503005030150302503035030450305503065030750308503095031050311503125031350314503155031650317503185031950320503215032250323503245032550326503275032850329503305033150332503335033450335503365033750338503395034050341503425034350344503455034650347503485034950350503515035250353503545035550356503575035850359503605036150362503635036450365503665036750368503695037050371503725037350374503755037650377503785037950380503815038250383503845038550386503875038850389503905039150392503935039450395503965039750398503995040050401504025040350404504055040650407504085040950410504115041250413504145041550416504175041850419504205042150422504235042450425504265042750428504295043050431504325043350434504355043650437504385043950440504415044250443504445044550446504475044850449504505045150452504535045450455504565045750458504595046050461504625046350464504655046650467504685046950470504715047250473504745047550476504775047850479504805048150482504835048450485504865048750488504895049050491504925049350494504955049650497504985049950500505015050250503505045050550506505075050850509505105051150512505135051450515505165051750518505195052050521505225052350524505255052650527505285052950530505315053250533505345053550536505375053850539505405054150542505435054450545505465054750548505495055050551505525055350554505555055650557505585055950560505615056250563505645056550566505675056850569505705057150572505735057450575505765057750578505795058050581505825058350584505855058650587505885058950590505915059250593505945059550596505975059850599506005060150602506035060450605506065060750608506095061050611506125061350614506155061650617506185061950620506215062250623506245062550626506275062850629506305063150632506335063450635506365063750638506395064050641506425064350644506455064650647506485064950650506515065250653506545065550656506575065850659506605066150662506635066450665506665066750668506695067050671506725067350674506755067650677506785067950680506815068250683506845068550686506875068850689506905069150692506935069450695506965069750698506995070050701507025070350704507055070650707507085070950710507115071250713507145071550716507175071850719507205072150722507235072450725507265072750728507295073050731507325073350734507355073650737507385073950740507415074250743507445074550746507475074850749507505075150752507535075450755507565075750758507595076050761507625076350764507655076650767507685076950770507715077250773507745077550776507775077850779507805078150782507835078450785507865078750788507895079050791507925079350794507955079650797507985079950800508015080250803508045080550806508075080850809508105081150812508135081450815508165081750818508195082050821508225082350824508255082650827508285082950830508315083250833508345083550836508375083850839508405084150842508435084450845508465084750848508495085050851508525085350854508555085650857508585085950860508615086250863508645086550866508675086850869508705087150872508735087450875508765087750878508795088050881508825088350884508855088650887508885088950890508915089250893508945089550896508975089850899509005090150902509035090450905509065090750908509095091050911509125091350914509155091650917509185091950920509215092250923509245092550926509275092850929509305093150932509335093450935509365093750938509395094050941509425094350944509455094650947509485094950950509515095250953509545095550956509575095850959509605096150962509635096450965509665096750968509695097050971509725097350974509755097650977509785097950980509815098250983509845098550986509875098850989509905099150992509935099450995509965099750998509995100051001510025100351004510055100651007510085100951010510115101251013510145101551016510175101851019510205102151022510235102451025510265102751028510295103051031510325103351034510355103651037510385103951040510415104251043510445104551046510475104851049510505105151052510535105451055510565105751058510595106051061510625106351064510655106651067510685106951070510715107251073510745107551076510775107851079510805108151082510835108451085510865108751088510895109051091510925109351094510955109651097510985109951100511015110251103511045110551106511075110851109511105111151112511135111451115511165111751118511195112051121511225112351124511255112651127511285112951130511315113251133511345113551136511375113851139511405114151142511435114451145511465114751148511495115051151511525115351154511555115651157511585115951160511615116251163511645116551166511675116851169511705117151172511735117451175511765117751178511795118051181511825118351184511855118651187511885118951190511915119251193511945119551196511975119851199512005120151202512035120451205512065120751208512095121051211512125121351214512155121651217512185121951220512215122251223512245122551226512275122851229512305123151232512335123451235512365123751238512395124051241512425124351244512455124651247512485124951250512515125251253512545125551256512575125851259512605126151262512635126451265512665126751268512695127051271512725127351274512755127651277512785127951280512815128251283512845128551286512875128851289512905129151292512935129451295512965129751298512995130051301513025130351304513055130651307513085130951310513115131251313513145131551316513175131851319513205132151322513235132451325513265132751328513295133051331513325133351334513355133651337513385133951340513415134251343513445134551346513475134851349513505135151352513535135451355513565135751358513595136051361513625136351364513655136651367513685136951370513715137251373513745137551376513775137851379513805138151382513835138451385513865138751388513895139051391513925139351394513955139651397513985139951400514015140251403514045140551406514075140851409514105141151412514135141451415514165141751418514195142051421514225142351424514255142651427514285142951430514315143251433514345143551436514375143851439514405144151442514435144451445514465144751448514495145051451514525145351454514555145651457514585145951460514615146251463514645146551466514675146851469514705147151472514735147451475514765147751478514795148051481514825148351484514855148651487514885148951490514915149251493514945149551496514975149851499515005150151502515035150451505515065150751508515095151051511515125151351514515155151651517515185151951520515215152251523515245152551526515275152851529515305153151532515335153451535515365153751538515395154051541515425154351544515455154651547515485154951550515515155251553515545155551556515575155851559515605156151562515635156451565515665156751568515695157051571515725157351574515755157651577515785157951580515815158251583515845158551586515875158851589515905159151592515935159451595515965159751598515995160051601516025160351604516055160651607516085160951610516115161251613516145161551616516175161851619516205162151622516235162451625516265162751628516295163051631516325163351634516355163651637516385163951640516415164251643516445164551646516475164851649516505165151652516535165451655516565165751658516595166051661516625166351664516655166651667516685166951670516715167251673516745167551676516775167851679516805168151682516835168451685516865168751688516895169051691516925169351694516955169651697516985169951700517015170251703517045170551706517075170851709517105171151712517135171451715517165171751718517195172051721517225172351724517255172651727517285172951730517315173251733517345173551736517375173851739517405174151742517435174451745517465174751748517495175051751517525175351754517555175651757517585175951760517615176251763517645176551766517675176851769517705177151772517735177451775517765177751778517795178051781517825178351784517855178651787517885178951790517915179251793517945179551796517975179851799518005180151802518035180451805518065180751808518095181051811518125181351814518155181651817518185181951820518215182251823518245182551826518275182851829518305183151832518335183451835518365183751838518395184051841518425184351844518455184651847518485184951850518515185251853518545185551856518575185851859518605186151862518635186451865518665186751868518695187051871518725187351874518755187651877518785187951880518815188251883518845188551886518875188851889518905189151892518935189451895518965189751898518995190051901519025190351904519055190651907519085190951910519115191251913519145191551916519175191851919519205192151922519235192451925519265192751928519295193051931519325193351934519355193651937519385193951940519415194251943519445194551946519475194851949519505195151952519535195451955519565195751958519595196051961519625196351964519655196651967519685196951970519715197251973519745197551976519775197851979519805198151982519835198451985519865198751988519895199051991519925199351994519955199651997519985199952000520015200252003520045200552006520075200852009520105201152012520135201452015520165201752018520195202052021520225202352024520255202652027520285202952030520315203252033520345203552036520375203852039520405204152042520435204452045520465204752048520495205052051520525205352054520555205652057520585205952060520615206252063520645206552066520675206852069520705207152072520735207452075520765207752078520795208052081520825208352084520855208652087520885208952090520915209252093520945209552096520975209852099521005210152102521035210452105521065210752108521095211052111521125211352114521155211652117521185211952120521215212252123521245212552126521275212852129521305213152132521335213452135521365213752138521395214052141521425214352144521455214652147521485214952150521515215252153521545215552156521575215852159521605216152162521635216452165521665216752168521695217052171521725217352174521755217652177521785217952180521815218252183521845218552186521875218852189521905219152192521935219452195521965219752198521995220052201522025220352204522055220652207522085220952210522115221252213522145221552216522175221852219522205222152222522235222452225522265222752228522295223052231522325223352234522355223652237522385223952240522415224252243522445224552246522475224852249522505225152252522535225452255522565225752258522595226052261522625226352264522655226652267522685226952270522715227252273522745227552276522775227852279522805228152282522835228452285522865228752288522895229052291522925229352294522955229652297522985229952300523015230252303523045230552306523075230852309523105231152312523135231452315523165231752318523195232052321523225232352324523255232652327523285232952330523315233252333523345233552336523375233852339523405234152342523435234452345523465234752348523495235052351523525235352354523555235652357523585235952360523615236252363523645236552366523675236852369523705237152372523735237452375523765237752378523795238052381523825238352384523855238652387523885238952390523915239252393523945239552396523975239852399524005240152402524035240452405524065240752408524095241052411524125241352414524155241652417524185241952420524215242252423524245242552426524275242852429524305243152432524335243452435524365243752438524395244052441524425244352444524455244652447524485244952450524515245252453524545245552456524575245852459524605246152462524635246452465524665246752468524695247052471524725247352474524755247652477524785247952480524815248252483524845248552486524875248852489524905249152492524935249452495524965249752498524995250052501525025250352504525055250652507525085250952510525115251252513525145251552516525175251852519525205252152522525235252452525525265252752528525295253052531525325253352534525355253652537525385253952540525415254252543525445254552546525475254852549525505255152552525535255452555525565255752558525595256052561525625256352564525655256652567525685256952570525715257252573525745257552576525775257852579525805258152582525835258452585525865258752588525895259052591525925259352594525955259652597525985259952600526015260252603526045260552606526075260852609526105261152612526135261452615526165261752618526195262052621526225262352624526255262652627526285262952630526315263252633526345263552636526375263852639526405264152642526435264452645526465264752648526495265052651526525265352654526555265652657526585265952660526615266252663526645266552666526675266852669526705267152672526735267452675526765267752678526795268052681526825268352684526855268652687526885268952690526915269252693526945269552696526975269852699527005270152702527035270452705527065270752708527095271052711527125271352714527155271652717527185271952720527215272252723527245272552726527275272852729527305273152732527335273452735527365273752738527395274052741527425274352744527455274652747527485274952750527515275252753527545275552756527575275852759527605276152762527635276452765527665276752768527695277052771527725277352774527755277652777527785277952780527815278252783527845278552786527875278852789527905279152792527935279452795527965279752798527995280052801528025280352804528055280652807528085280952810528115281252813528145281552816528175281852819528205282152822528235282452825528265282752828528295283052831528325283352834528355283652837528385283952840528415284252843528445284552846528475284852849528505285152852528535285452855528565285752858528595286052861528625286352864528655286652867528685286952870528715287252873528745287552876528775287852879528805288152882528835288452885528865288752888528895289052891528925289352894528955289652897528985289952900529015290252903529045290552906529075290852909529105291152912529135291452915529165291752918529195292052921529225292352924529255292652927529285292952930529315293252933529345293552936529375293852939529405294152942529435294452945529465294752948529495295052951529525295352954529555295652957529585295952960529615296252963529645296552966529675296852969529705297152972529735297452975529765297752978529795298052981529825298352984529855298652987529885298952990529915299252993529945299552996529975299852999530005300153002530035300453005530065300753008530095301053011530125301353014530155301653017530185301953020530215302253023530245302553026530275302853029530305303153032530335303453035530365303753038530395304053041530425304353044530455304653047530485304953050530515305253053530545305553056530575305853059530605306153062530635306453065530665306753068530695307053071530725307353074530755307653077530785307953080530815308253083530845308553086530875308853089530905309153092530935309453095530965309753098530995310053101531025310353104531055310653107531085310953110531115311253113531145311553116531175311853119531205312153122531235312453125531265312753128531295313053131531325313353134531355313653137531385313953140531415314253143531445314553146531475314853149531505315153152531535315453155531565315753158531595316053161531625316353164531655316653167531685316953170531715317253173531745317553176531775317853179531805318153182531835318453185531865318753188531895319053191531925319353194531955319653197531985319953200532015320253203532045320553206532075320853209532105321153212532135321453215532165321753218532195322053221532225322353224532255322653227532285322953230532315323253233532345323553236532375323853239532405324153242532435324453245532465324753248532495325053251532525325353254532555325653257532585325953260532615326253263532645326553266532675326853269532705327153272532735327453275532765327753278532795328053281532825328353284532855328653287532885328953290532915329253293532945329553296532975329853299533005330153302533035330453305533065330753308533095331053311533125331353314533155331653317533185331953320533215332253323533245332553326533275332853329533305333153332533335333453335533365333753338533395334053341533425334353344533455334653347533485334953350533515335253353533545335553356533575335853359533605336153362533635336453365533665336753368533695337053371533725337353374533755337653377533785337953380533815338253383533845338553386533875338853389533905339153392533935339453395533965339753398533995340053401534025340353404534055340653407534085340953410534115341253413534145341553416534175341853419534205342153422534235342453425534265342753428534295343053431534325343353434534355343653437534385343953440534415344253443534445344553446534475344853449534505345153452534535345453455534565345753458534595346053461534625346353464534655346653467534685346953470534715347253473534745347553476534775347853479534805348153482534835348453485534865348753488534895349053491534925349353494534955349653497534985349953500535015350253503535045350553506535075350853509535105351153512535135351453515535165351753518535195352053521535225352353524535255352653527535285352953530535315353253533535345353553536535375353853539535405354153542535435354453545535465354753548535495355053551535525355353554535555355653557535585355953560535615356253563535645356553566535675356853569535705357153572535735357453575535765357753578535795358053581535825358353584535855358653587535885358953590535915359253593535945359553596535975359853599536005360153602536035360453605536065360753608536095361053611536125361353614536155361653617536185361953620536215362253623536245362553626536275362853629536305363153632536335363453635536365363753638536395364053641536425364353644536455364653647536485364953650536515365253653536545365553656536575365853659536605366153662536635366453665536665366753668536695367053671536725367353674536755367653677536785367953680536815368253683536845368553686536875368853689536905369153692536935369453695536965369753698536995370053701537025370353704537055370653707537085370953710537115371253713537145371553716537175371853719537205372153722537235372453725537265372753728537295373053731537325373353734537355373653737537385373953740537415374253743537445374553746537475374853749537505375153752537535375453755537565375753758537595376053761537625376353764537655376653767537685376953770537715377253773537745377553776537775377853779537805378153782537835378453785537865378753788537895379053791537925379353794537955379653797537985379953800538015380253803538045380553806538075380853809538105381153812538135381453815538165381753818538195382053821538225382353824538255382653827538285382953830538315383253833538345383553836538375383853839538405384153842538435384453845538465384753848538495385053851538525385353854538555385653857538585385953860538615386253863538645386553866538675386853869538705387153872538735387453875538765387753878538795388053881538825388353884538855388653887538885388953890538915389253893538945389553896538975389853899539005390153902539035390453905539065390753908539095391053911539125391353914539155391653917539185391953920539215392253923539245392553926539275392853929539305393153932539335393453935539365393753938539395394053941539425394353944539455394653947539485394953950539515395253953539545395553956539575395853959539605396153962539635396453965539665396753968539695397053971539725397353974539755397653977539785397953980539815398253983539845398553986539875398853989539905399153992539935399453995539965399753998539995400054001540025400354004540055400654007540085400954010540115401254013540145401554016540175401854019540205402154022540235402454025540265402754028540295403054031540325403354034540355403654037540385403954040540415404254043540445404554046540475404854049540505405154052540535405454055540565405754058540595406054061540625406354064540655406654067540685406954070540715407254073540745407554076540775407854079540805408154082540835408454085540865408754088540895409054091540925409354094540955409654097540985409954100541015410254103541045410554106541075410854109541105411154112541135411454115541165411754118541195412054121541225412354124541255412654127541285412954130541315413254133541345413554136541375413854139541405414154142541435414454145541465414754148541495415054151541525415354154541555415654157541585415954160541615416254163541645416554166541675416854169541705417154172541735417454175541765417754178541795418054181541825418354184541855418654187541885418954190541915419254193541945419554196541975419854199542005420154202542035420454205542065420754208542095421054211542125421354214542155421654217542185421954220542215422254223542245422554226542275422854229542305423154232542335423454235542365423754238542395424054241542425424354244542455424654247542485424954250542515425254253542545425554256542575425854259542605426154262542635426454265542665426754268542695427054271542725427354274542755427654277542785427954280542815428254283542845428554286542875428854289542905429154292542935429454295542965429754298542995430054301543025430354304543055430654307543085430954310543115431254313543145431554316543175431854319543205432154322543235432454325543265432754328543295433054331543325433354334543355433654337543385433954340543415434254343543445434554346543475434854349543505435154352543535435454355543565435754358543595436054361543625436354364543655436654367543685436954370543715437254373543745437554376543775437854379543805438154382543835438454385543865438754388543895439054391543925439354394543955439654397543985439954400544015440254403544045440554406544075440854409544105441154412544135441454415544165441754418544195442054421544225442354424544255442654427544285442954430544315443254433544345443554436544375443854439544405444154442544435444454445544465444754448544495445054451544525445354454544555445654457544585445954460544615446254463544645446554466544675446854469544705447154472544735447454475544765447754478544795448054481544825448354484544855448654487544885448954490544915449254493544945449554496544975449854499545005450154502545035450454505545065450754508545095451054511545125451354514545155451654517545185451954520545215452254523545245452554526545275452854529545305453154532545335453454535545365453754538545395454054541545425454354544545455454654547545485454954550545515455254553545545455554556545575455854559545605456154562545635456454565545665456754568545695457054571545725457354574545755457654577545785457954580545815458254583545845458554586545875458854589545905459154592545935459454595545965459754598545995460054601546025460354604546055460654607546085460954610546115461254613546145461554616546175461854619546205462154622546235462454625546265462754628546295463054631546325463354634546355463654637546385463954640546415464254643546445464554646546475464854649546505465154652546535465454655546565465754658546595466054661546625466354664546655466654667546685466954670546715467254673546745467554676546775467854679546805468154682546835468454685546865468754688546895469054691546925469354694546955469654697546985469954700547015470254703547045470554706547075470854709547105471154712547135471454715547165471754718547195472054721547225472354724547255472654727547285472954730547315473254733547345473554736547375473854739547405474154742547435474454745547465474754748547495475054751547525475354754547555475654757547585475954760547615476254763547645476554766547675476854769547705477154772547735477454775547765477754778547795478054781547825478354784547855478654787547885478954790547915479254793547945479554796547975479854799548005480154802548035480454805548065480754808548095481054811548125481354814548155481654817548185481954820548215482254823548245482554826548275482854829548305483154832548335483454835548365483754838548395484054841548425484354844548455484654847548485484954850548515485254853548545485554856548575485854859548605486154862548635486454865548665486754868548695487054871548725487354874548755487654877548785487954880548815488254883548845488554886548875488854889548905489154892548935489454895548965489754898548995490054901549025490354904549055490654907549085490954910549115491254913549145491554916549175491854919549205492154922549235492454925549265492754928549295493054931549325493354934549355493654937549385493954940549415494254943549445494554946549475494854949549505495154952549535495454955549565495754958549595496054961549625496354964549655496654967549685496954970549715497254973549745497554976549775497854979549805498154982549835498454985549865498754988549895499054991549925499354994549955499654997549985499955000550015500255003550045500555006550075500855009550105501155012550135501455015550165501755018550195502055021550225502355024550255502655027550285502955030550315503255033550345503555036550375503855039550405504155042550435504455045550465504755048550495505055051550525505355054550555505655057550585505955060550615506255063550645506555066550675506855069550705507155072550735507455075550765507755078550795508055081550825508355084550855508655087550885508955090550915509255093550945509555096550975509855099551005510155102551035510455105551065510755108551095511055111551125511355114551155511655117551185511955120551215512255123551245512555126551275512855129551305513155132551335513455135551365513755138551395514055141551425514355144551455514655147551485514955150551515515255153551545515555156551575515855159551605516155162551635516455165551665516755168551695517055171551725517355174551755517655177551785517955180551815518255183551845518555186551875518855189551905519155192551935519455195551965519755198551995520055201552025520355204552055520655207552085520955210552115521255213552145521555216552175521855219552205522155222552235522455225552265522755228552295523055231552325523355234552355523655237552385523955240552415524255243552445524555246552475524855249552505525155252552535525455255552565525755258552595526055261552625526355264552655526655267552685526955270552715527255273552745527555276552775527855279552805528155282552835528455285552865528755288552895529055291552925529355294552955529655297552985529955300553015530255303553045530555306553075530855309553105531155312553135531455315553165531755318553195532055321553225532355324553255532655327553285532955330553315533255333553345533555336553375533855339553405534155342553435534455345553465534755348553495535055351553525535355354553555535655357553585535955360553615536255363553645536555366553675536855369553705537155372553735537455375553765537755378553795538055381553825538355384553855538655387553885538955390553915539255393553945539555396553975539855399554005540155402554035540455405554065540755408554095541055411554125541355414554155541655417554185541955420554215542255423554245542555426554275542855429554305543155432554335543455435554365543755438554395544055441554425544355444554455544655447554485544955450554515545255453554545545555456554575545855459554605546155462554635546455465554665546755468554695547055471554725547355474554755547655477554785547955480554815548255483554845548555486554875548855489554905549155492554935549455495554965549755498554995550055501555025550355504555055550655507555085550955510555115551255513555145551555516555175551855519555205552155522555235552455525555265552755528555295553055531555325553355534555355553655537555385553955540555415554255543555445554555546555475554855549555505555155552555535555455555555565555755558555595556055561555625556355564555655556655567555685556955570555715557255573555745557555576555775557855579555805558155582555835558455585555865558755588555895559055591555925559355594555955559655597555985559955600556015560255603556045560555606556075560855609556105561155612556135561455615556165561755618556195562055621556225562355624556255562655627556285562955630556315563255633556345563555636556375563855639556405564155642556435564455645556465564755648556495565055651556525565355654556555565655657556585565955660556615566255663556645566555666556675566855669556705567155672556735567455675556765567755678556795568055681556825568355684556855568655687556885568955690556915569255693556945569555696556975569855699557005570155702557035570455705557065570755708557095571055711557125571355714557155571655717557185571955720557215572255723557245572555726557275572855729557305573155732557335573455735557365573755738557395574055741557425574355744557455574655747557485574955750557515575255753557545575555756557575575855759557605576155762557635576455765557665576755768557695577055771557725577355774557755577655777557785577955780557815578255783557845578555786557875578855789557905579155792557935579455795557965579755798557995580055801558025580355804558055580655807558085580955810558115581255813558145581555816558175581855819558205582155822558235582455825558265582755828558295583055831558325583355834558355583655837558385583955840558415584255843558445584555846558475584855849558505585155852558535585455855558565585755858558595586055861558625586355864558655586655867558685586955870558715587255873558745587555876558775587855879558805588155882558835588455885558865588755888558895589055891558925589355894558955589655897558985589955900559015590255903559045590555906559075590855909559105591155912559135591455915559165591755918559195592055921559225592355924559255592655927559285592955930559315593255933559345593555936559375593855939559405594155942559435594455945559465594755948559495595055951559525595355954559555595655957559585595955960559615596255963559645596555966559675596855969559705597155972559735597455975559765597755978559795598055981559825598355984559855598655987559885598955990559915599255993559945599555996559975599855999560005600156002560035600456005560065600756008560095601056011560125601356014560155601656017560185601956020560215602256023560245602556026560275602856029560305603156032560335603456035560365603756038560395604056041560425604356044560455604656047560485604956050560515605256053560545605556056560575605856059560605606156062560635606456065560665606756068560695607056071560725607356074560755607656077560785607956080560815608256083560845608556086560875608856089560905609156092560935609456095560965609756098560995610056101561025610356104561055610656107561085610956110561115611256113561145611556116561175611856119561205612156122561235612456125561265612756128561295613056131561325613356134561355613656137561385613956140561415614256143561445614556146561475614856149561505615156152561535615456155561565615756158561595616056161561625616356164561655616656167561685616956170561715617256173561745617556176561775617856179561805618156182561835618456185561865618756188561895619056191561925619356194561955619656197561985619956200562015620256203562045620556206562075620856209562105621156212562135621456215562165621756218562195622056221562225622356224562255622656227562285622956230562315623256233562345623556236562375623856239562405624156242562435624456245562465624756248562495625056251562525625356254562555625656257562585625956260562615626256263562645626556266562675626856269562705627156272562735627456275562765627756278562795628056281562825628356284562855628656287562885628956290562915629256293562945629556296562975629856299563005630156302563035630456305563065630756308563095631056311563125631356314563155631656317563185631956320563215632256323563245632556326563275632856329563305633156332563335633456335563365633756338563395634056341563425634356344563455634656347563485634956350563515635256353563545635556356563575635856359563605636156362563635636456365563665636756368563695637056371563725637356374563755637656377563785637956380563815638256383563845638556386563875638856389563905639156392563935639456395563965639756398563995640056401564025640356404564055640656407564085640956410564115641256413564145641556416564175641856419564205642156422564235642456425564265642756428564295643056431564325643356434564355643656437564385643956440564415644256443564445644556446564475644856449564505645156452564535645456455564565645756458564595646056461564625646356464564655646656467564685646956470564715647256473564745647556476564775647856479564805648156482564835648456485564865648756488564895649056491564925649356494564955649656497564985649956500565015650256503565045650556506565075650856509565105651156512565135651456515565165651756518565195652056521565225652356524565255652656527565285652956530565315653256533565345653556536565375653856539565405654156542565435654456545565465654756548565495655056551565525655356554565555655656557565585655956560565615656256563565645656556566565675656856569565705657156572565735657456575565765657756578565795658056581565825658356584565855658656587565885658956590565915659256593565945659556596565975659856599566005660156602566035660456605566065660756608566095661056611566125661356614566155661656617566185661956620566215662256623566245662556626566275662856629566305663156632566335663456635566365663756638566395664056641566425664356644566455664656647566485664956650566515665256653566545665556656566575665856659566605666156662566635666456665566665666756668566695667056671566725667356674566755667656677566785667956680566815668256683566845668556686566875668856689566905669156692566935669456695566965669756698566995670056701567025670356704567055670656707567085670956710567115671256713567145671556716567175671856719567205672156722567235672456725567265672756728567295673056731567325673356734567355673656737567385673956740567415674256743567445674556746567475674856749567505675156752567535675456755567565675756758567595676056761567625676356764567655676656767567685676956770567715677256773567745677556776567775677856779567805678156782567835678456785567865678756788567895679056791567925679356794567955679656797567985679956800568015680256803568045680556806568075680856809568105681156812568135681456815568165681756818568195682056821568225682356824568255682656827568285682956830568315683256833568345683556836568375683856839568405684156842568435684456845568465684756848568495685056851568525685356854568555685656857568585685956860568615686256863568645686556866568675686856869568705687156872568735687456875568765687756878568795688056881568825688356884568855688656887568885688956890568915689256893568945689556896568975689856899569005690156902569035690456905569065690756908569095691056911569125691356914569155691656917569185691956920569215692256923569245692556926569275692856929569305693156932569335693456935569365693756938569395694056941569425694356944569455694656947569485694956950569515695256953569545695556956569575695856959569605696156962569635696456965569665696756968569695697056971569725697356974569755697656977569785697956980569815698256983569845698556986569875698856989569905699156992569935699456995569965699756998569995700057001570025700357004570055700657007570085700957010570115701257013570145701557016570175701857019570205702157022570235702457025570265702757028570295703057031570325703357034570355703657037570385703957040570415704257043570445704557046570475704857049570505705157052570535705457055570565705757058570595706057061570625706357064570655706657067570685706957070570715707257073570745707557076570775707857079570805708157082570835708457085570865708757088570895709057091570925709357094570955709657097570985709957100571015710257103571045710557106571075710857109571105711157112571135711457115571165711757118571195712057121571225712357124571255712657127571285712957130571315713257133571345713557136571375713857139571405714157142571435714457145571465714757148571495715057151571525715357154571555715657157571585715957160571615716257163571645716557166571675716857169571705717157172571735717457175571765717757178571795718057181571825718357184571855718657187571885718957190571915719257193571945719557196571975719857199572005720157202572035720457205572065720757208572095721057211572125721357214572155721657217572185721957220572215722257223572245722557226572275722857229572305723157232572335723457235572365723757238572395724057241572425724357244572455724657247572485724957250572515725257253572545725557256572575725857259572605726157262572635726457265572665726757268572695727057271572725727357274572755727657277572785727957280572815728257283572845728557286572875728857289572905729157292572935729457295572965729757298572995730057301573025730357304573055730657307573085730957310573115731257313573145731557316573175731857319573205732157322573235732457325573265732757328573295733057331573325733357334573355733657337573385733957340573415734257343573445734557346573475734857349573505735157352573535735457355573565735757358573595736057361573625736357364573655736657367573685736957370573715737257373573745737557376573775737857379573805738157382573835738457385573865738757388573895739057391573925739357394573955739657397573985739957400574015740257403574045740557406574075740857409574105741157412574135741457415574165741757418574195742057421574225742357424574255742657427574285742957430574315743257433574345743557436574375743857439574405744157442574435744457445574465744757448574495745057451574525745357454574555745657457574585745957460574615746257463574645746557466574675746857469574705747157472574735747457475574765747757478574795748057481574825748357484574855748657487574885748957490574915749257493574945749557496574975749857499575005750157502575035750457505575065750757508575095751057511575125751357514575155751657517575185751957520575215752257523575245752557526575275752857529575305753157532575335753457535575365753757538575395754057541575425754357544575455754657547575485754957550575515755257553575545755557556575575755857559575605756157562575635756457565575665756757568575695757057571575725757357574575755757657577575785757957580575815758257583575845758557586575875758857589575905759157592575935759457595575965759757598575995760057601576025760357604576055760657607576085760957610576115761257613576145761557616576175761857619576205762157622576235762457625576265762757628576295763057631576325763357634576355763657637576385763957640576415764257643576445764557646576475764857649576505765157652576535765457655576565765757658576595766057661576625766357664576655766657667576685766957670576715767257673576745767557676576775767857679576805768157682576835768457685576865768757688576895769057691576925769357694576955769657697576985769957700577015770257703577045770557706577075770857709577105771157712577135771457715577165771757718577195772057721577225772357724577255772657727577285772957730577315773257733577345773557736577375773857739577405774157742577435774457745577465774757748577495775057751577525775357754577555775657757577585775957760577615776257763577645776557766577675776857769577705777157772577735777457775577765777757778577795778057781577825778357784577855778657787577885778957790577915779257793577945779557796577975779857799578005780157802578035780457805578065780757808578095781057811578125781357814578155781657817578185781957820578215782257823578245782557826578275782857829578305783157832578335783457835578365783757838578395784057841578425784357844578455784657847578485784957850578515785257853578545785557856578575785857859578605786157862578635786457865578665786757868578695787057871578725787357874578755787657877578785787957880578815788257883578845788557886578875788857889578905789157892578935789457895578965789757898578995790057901579025790357904579055790657907579085790957910579115791257913579145791557916579175791857919579205792157922579235792457925579265792757928579295793057931579325793357934579355793657937579385793957940579415794257943579445794557946579475794857949579505795157952579535795457955579565795757958579595796057961579625796357964579655796657967579685796957970579715797257973579745797557976579775797857979579805798157982579835798457985579865798757988579895799057991579925799357994579955799657997579985799958000580015800258003580045800558006580075800858009580105801158012580135801458015580165801758018580195802058021580225802358024580255802658027580285802958030580315803258033580345803558036580375803858039580405804158042580435804458045580465804758048580495805058051580525805358054580555805658057580585805958060580615806258063580645806558066580675806858069580705807158072580735807458075580765807758078580795808058081580825808358084580855808658087580885808958090580915809258093580945809558096580975809858099581005810158102581035810458105581065810758108581095811058111581125811358114581155811658117581185811958120581215812258123581245812558126581275812858129581305813158132581335813458135581365813758138581395814058141581425814358144581455814658147581485814958150581515815258153581545815558156581575815858159581605816158162581635816458165581665816758168581695817058171581725817358174581755817658177581785817958180581815818258183581845818558186581875818858189581905819158192581935819458195581965819758198581995820058201582025820358204582055820658207582085820958210582115821258213582145821558216582175821858219582205822158222582235822458225582265822758228582295823058231582325823358234582355823658237582385823958240582415824258243582445824558246582475824858249582505825158252582535825458255582565825758258582595826058261582625826358264582655826658267582685826958270582715827258273582745827558276582775827858279582805828158282582835828458285582865828758288582895829058291582925829358294582955829658297582985829958300583015830258303583045830558306583075830858309583105831158312583135831458315583165831758318583195832058321583225832358324583255832658327583285832958330583315833258333583345833558336583375833858339583405834158342583435834458345583465834758348583495835058351583525835358354583555835658357583585835958360583615836258363583645836558366583675836858369583705837158372583735837458375583765837758378583795838058381583825838358384583855838658387583885838958390583915839258393583945839558396583975839858399584005840158402584035840458405584065840758408584095841058411584125841358414584155841658417584185841958420584215842258423584245842558426584275842858429584305843158432584335843458435584365843758438584395844058441584425844358444584455844658447584485844958450584515845258453584545845558456584575845858459584605846158462584635846458465584665846758468584695847058471584725847358474584755847658477584785847958480584815848258483584845848558486584875848858489584905849158492584935849458495584965849758498584995850058501585025850358504585055850658507585085850958510585115851258513585145851558516585175851858519585205852158522585235852458525585265852758528585295853058531585325853358534585355853658537585385853958540585415854258543585445854558546585475854858549585505855158552585535855458555585565855758558585595856058561585625856358564585655856658567585685856958570585715857258573585745857558576585775857858579585805858158582585835858458585585865858758588585895859058591585925859358594585955859658597585985859958600586015860258603586045860558606586075860858609586105861158612586135861458615586165861758618586195862058621586225862358624586255862658627586285862958630586315863258633586345863558636586375863858639586405864158642586435864458645586465864758648586495865058651586525865358654586555865658657586585865958660586615866258663586645866558666586675866858669586705867158672586735867458675586765867758678586795868058681586825868358684586855868658687586885868958690586915869258693586945869558696586975869858699587005870158702587035870458705587065870758708587095871058711587125871358714587155871658717587185871958720587215872258723587245872558726587275872858729587305873158732587335873458735587365873758738587395874058741587425874358744587455874658747587485874958750587515875258753587545875558756587575875858759587605876158762587635876458765587665876758768587695877058771587725877358774587755877658777587785877958780587815878258783587845878558786587875878858789587905879158792587935879458795587965879758798587995880058801588025880358804588055880658807588085880958810588115881258813588145881558816588175881858819588205882158822588235882458825588265882758828588295883058831588325883358834588355883658837588385883958840588415884258843588445884558846588475884858849588505885158852588535885458855588565885758858588595886058861588625886358864588655886658867588685886958870588715887258873588745887558876588775887858879588805888158882588835888458885588865888758888588895889058891588925889358894588955889658897588985889958900589015890258903589045890558906589075890858909589105891158912589135891458915589165891758918589195892058921589225892358924589255892658927589285892958930589315893258933589345893558936589375893858939589405894158942589435894458945589465894758948589495895058951589525895358954589555895658957589585895958960589615896258963589645896558966589675896858969589705897158972589735897458975589765897758978589795898058981589825898358984589855898658987589885898958990589915899258993589945899558996589975899858999590005900159002590035900459005590065900759008590095901059011590125901359014590155901659017590185901959020590215902259023590245902559026590275902859029590305903159032590335903459035590365903759038590395904059041590425904359044590455904659047590485904959050590515905259053590545905559056590575905859059590605906159062590635906459065590665906759068590695907059071590725907359074590755907659077590785907959080590815908259083590845908559086590875908859089590905909159092590935909459095590965909759098590995910059101591025910359104591055910659107591085910959110591115911259113591145911559116591175911859119591205912159122591235912459125591265912759128591295913059131591325913359134591355913659137591385913959140591415914259143591445914559146591475914859149591505915159152591535915459155591565915759158591595916059161591625916359164591655916659167591685916959170591715917259173591745917559176591775917859179591805918159182591835918459185591865918759188591895919059191591925919359194591955919659197591985919959200592015920259203592045920559206592075920859209592105921159212592135921459215592165921759218592195922059221592225922359224592255922659227592285922959230592315923259233592345923559236592375923859239592405924159242592435924459245592465924759248592495925059251592525925359254592555925659257592585925959260592615926259263592645926559266592675926859269592705927159272592735927459275592765927759278592795928059281592825928359284592855928659287592885928959290592915929259293592945929559296592975929859299593005930159302593035930459305593065930759308593095931059311593125931359314593155931659317593185931959320593215932259323593245932559326593275932859329593305933159332593335933459335593365933759338593395934059341593425934359344593455934659347593485934959350593515935259353593545935559356593575935859359593605936159362593635936459365593665936759368593695937059371593725937359374593755937659377593785937959380593815938259383593845938559386593875938859389593905939159392593935939459395593965939759398593995940059401594025940359404594055940659407594085940959410594115941259413594145941559416594175941859419594205942159422594235942459425594265942759428594295943059431594325943359434594355943659437594385943959440594415944259443594445944559446594475944859449594505945159452594535945459455594565945759458594595946059461594625946359464594655946659467594685946959470594715947259473594745947559476594775947859479594805948159482594835948459485594865948759488594895949059491594925949359494594955949659497594985949959500595015950259503595045950559506595075950859509595105951159512595135951459515595165951759518595195952059521595225952359524595255952659527595285952959530595315953259533595345953559536595375953859539595405954159542595435954459545595465954759548595495955059551595525955359554595555955659557595585955959560595615956259563595645956559566595675956859569595705957159572595735957459575595765957759578595795958059581595825958359584595855958659587595885958959590595915959259593595945959559596595975959859599596005960159602596035960459605596065960759608596095961059611596125961359614596155961659617596185961959620596215962259623596245962559626596275962859629596305963159632596335963459635596365963759638596395964059641596425964359644596455964659647596485964959650596515965259653596545965559656596575965859659596605966159662596635966459665596665966759668596695967059671596725967359674596755967659677596785967959680596815968259683596845968559686596875968859689596905969159692596935969459695596965969759698596995970059701597025970359704597055970659707597085970959710597115971259713597145971559716597175971859719597205972159722597235972459725597265972759728597295973059731597325973359734597355973659737597385973959740597415974259743597445974559746597475974859749597505975159752597535975459755597565975759758597595976059761597625976359764597655976659767597685976959770597715977259773597745977559776597775977859779597805978159782597835978459785597865978759788597895979059791597925979359794597955979659797597985979959800598015980259803598045980559806598075980859809598105981159812598135981459815598165981759818598195982059821598225982359824598255982659827598285982959830598315983259833598345983559836598375983859839598405984159842598435984459845598465984759848598495985059851598525985359854598555985659857598585985959860598615986259863598645986559866598675986859869598705987159872598735987459875598765987759878598795988059881598825988359884598855988659887598885988959890598915989259893598945989559896598975989859899599005990159902599035990459905599065990759908599095991059911599125991359914599155991659917599185991959920599215992259923599245992559926599275992859929599305993159932599335993459935599365993759938599395994059941599425994359944599455994659947599485994959950599515995259953599545995559956599575995859959599605996159962599635996459965599665996759968599695997059971599725997359974599755997659977599785997959980599815998259983599845998559986599875998859989599905999159992599935999459995599965999759998599996000060001600026000360004600056000660007600086000960010600116001260013600146001560016600176001860019600206002160022600236002460025600266002760028600296003060031600326003360034600356003660037600386003960040600416004260043600446004560046600476004860049600506005160052600536005460055600566005760058600596006060061600626006360064600656006660067600686006960070600716007260073600746007560076600776007860079600806008160082600836008460085600866008760088600896009060091600926009360094600956009660097600986009960100601016010260103601046010560106601076010860109601106011160112601136011460115601166011760118601196012060121601226012360124601256012660127601286012960130601316013260133601346013560136601376013860139601406014160142601436014460145601466014760148601496015060151601526015360154601556015660157601586015960160601616016260163601646016560166601676016860169601706017160172601736017460175601766017760178601796018060181601826018360184601856018660187601886018960190601916019260193601946019560196601976019860199602006020160202602036020460205602066020760208602096021060211602126021360214602156021660217602186021960220602216022260223602246022560226602276022860229602306023160232602336023460235602366023760238602396024060241602426024360244602456024660247602486024960250602516025260253602546025560256602576025860259602606026160262602636026460265602666026760268602696027060271602726027360274602756027660277602786027960280602816028260283602846028560286602876028860289602906029160292602936029460295602966029760298602996030060301603026030360304603056030660307603086030960310603116031260313603146031560316603176031860319603206032160322603236032460325603266032760328603296033060331603326033360334603356033660337603386033960340603416034260343603446034560346603476034860349603506035160352603536035460355603566035760358603596036060361603626036360364603656036660367603686036960370603716037260373603746037560376603776037860379603806038160382603836038460385603866038760388603896039060391603926039360394603956039660397603986039960400604016040260403604046040560406604076040860409604106041160412604136041460415604166041760418604196042060421604226042360424604256042660427604286042960430604316043260433604346043560436604376043860439604406044160442604436044460445604466044760448604496045060451604526045360454604556045660457604586045960460604616046260463604646046560466604676046860469604706047160472604736047460475604766047760478604796048060481604826048360484604856048660487604886048960490604916049260493604946049560496604976049860499605006050160502605036050460505605066050760508605096051060511605126051360514605156051660517605186051960520605216052260523605246052560526605276052860529605306053160532605336053460535605366053760538605396054060541605426054360544605456054660547605486054960550605516055260553605546055560556605576055860559605606056160562605636056460565605666056760568605696057060571605726057360574605756057660577605786057960580605816058260583605846058560586605876058860589605906059160592605936059460595605966059760598605996060060601606026060360604606056060660607606086060960610606116061260613606146061560616606176061860619606206062160622606236062460625606266062760628606296063060631606326063360634606356063660637606386063960640606416064260643606446064560646606476064860649606506065160652606536065460655606566065760658606596066060661606626066360664606656066660667606686066960670606716067260673606746067560676606776067860679606806068160682606836068460685606866068760688606896069060691606926069360694606956069660697606986069960700607016070260703607046070560706607076070860709607106071160712607136071460715607166071760718607196072060721607226072360724607256072660727607286072960730607316073260733607346073560736607376073860739607406074160742607436074460745607466074760748607496075060751607526075360754607556075660757607586075960760607616076260763607646076560766607676076860769607706077160772607736077460775607766077760778607796078060781607826078360784607856078660787607886078960790607916079260793607946079560796607976079860799608006080160802608036080460805608066080760808608096081060811608126081360814608156081660817608186081960820608216082260823608246082560826608276082860829608306083160832608336083460835608366083760838608396084060841608426084360844608456084660847608486084960850608516085260853608546085560856608576085860859608606086160862608636086460865608666086760868608696087060871608726087360874608756087660877608786087960880608816088260883608846088560886608876088860889608906089160892608936089460895608966089760898608996090060901609026090360904609056090660907609086090960910609116091260913609146091560916609176091860919609206092160922609236092460925609266092760928609296093060931609326093360934609356093660937609386093960940609416094260943609446094560946609476094860949609506095160952609536095460955609566095760958609596096060961609626096360964609656096660967609686096960970609716097260973609746097560976609776097860979609806098160982609836098460985609866098760988609896099060991609926099360994609956099660997609986099961000610016100261003610046100561006610076100861009610106101161012610136101461015610166101761018610196102061021610226102361024610256102661027610286102961030610316103261033610346103561036610376103861039610406104161042610436104461045610466104761048610496105061051610526105361054610556105661057610586105961060610616106261063610646106561066610676106861069610706107161072610736107461075610766107761078610796108061081610826108361084610856108661087610886108961090610916109261093610946109561096610976109861099611006110161102611036110461105611066110761108611096111061111611126111361114611156111661117611186111961120611216112261123611246112561126611276112861129611306113161132611336113461135611366113761138611396114061141611426114361144611456114661147611486114961150611516115261153611546115561156611576115861159611606116161162611636116461165611666116761168611696117061171611726117361174611756117661177611786117961180611816118261183611846118561186611876118861189611906119161192611936119461195611966119761198611996120061201612026120361204612056120661207612086120961210612116121261213612146121561216612176121861219612206122161222612236122461225612266122761228612296123061231612326123361234612356123661237612386123961240612416124261243612446124561246612476124861249612506125161252612536125461255612566125761258612596126061261612626126361264612656126661267612686126961270612716127261273612746127561276612776127861279612806128161282612836128461285612866128761288612896129061291612926129361294612956129661297612986129961300613016130261303613046130561306613076130861309613106131161312613136131461315613166131761318613196132061321613226132361324613256132661327613286132961330613316133261333613346133561336613376133861339613406134161342613436134461345613466134761348613496135061351613526135361354613556135661357613586135961360613616136261363613646136561366613676136861369613706137161372613736137461375613766137761378613796138061381613826138361384613856138661387613886138961390613916139261393613946139561396613976139861399614006140161402614036140461405614066140761408614096141061411614126141361414614156141661417614186141961420614216142261423614246142561426614276142861429614306143161432614336143461435614366143761438614396144061441614426144361444614456144661447614486144961450614516145261453614546145561456614576145861459614606146161462614636146461465614666146761468614696147061471614726147361474614756147661477614786147961480614816148261483614846148561486614876148861489614906149161492614936149461495614966149761498614996150061501615026150361504615056150661507615086150961510615116151261513615146151561516615176151861519615206152161522615236152461525615266152761528615296153061531615326153361534615356153661537615386153961540615416154261543615446154561546615476154861549615506155161552615536155461555615566155761558615596156061561615626156361564615656156661567615686156961570615716157261573615746157561576615776157861579615806158161582615836158461585615866158761588615896159061591615926159361594615956159661597615986159961600616016160261603616046160561606616076160861609616106161161612616136161461615616166161761618616196162061621616226162361624616256162661627616286162961630616316163261633616346163561636616376163861639616406164161642616436164461645616466164761648616496165061651616526165361654616556165661657616586165961660616616166261663616646166561666616676166861669616706167161672616736167461675616766167761678616796168061681616826168361684616856168661687616886168961690616916169261693616946169561696616976169861699617006170161702617036170461705617066170761708617096171061711617126171361714617156171661717617186171961720617216172261723617246172561726617276172861729617306173161732617336173461735617366173761738617396174061741617426174361744617456174661747617486174961750617516175261753617546175561756617576175861759617606176161762617636176461765617666176761768617696177061771617726177361774617756177661777617786177961780617816178261783617846178561786617876178861789617906179161792617936179461795617966179761798617996180061801618026180361804618056180661807618086180961810618116181261813618146181561816618176181861819618206182161822618236182461825618266182761828618296183061831618326183361834618356183661837618386183961840618416184261843618446184561846618476184861849618506185161852618536185461855618566185761858618596186061861618626186361864618656186661867618686186961870618716187261873618746187561876618776187861879618806188161882618836188461885618866188761888618896189061891618926189361894618956189661897618986189961900619016190261903619046190561906619076190861909619106191161912619136191461915619166191761918619196192061921619226192361924619256192661927619286192961930619316193261933619346193561936619376193861939619406194161942619436194461945619466194761948619496195061951619526195361954619556195661957619586195961960619616196261963619646196561966619676196861969619706197161972619736197461975619766197761978619796198061981619826198361984619856198661987619886198961990619916199261993619946199561996619976199861999620006200162002620036200462005620066200762008620096201062011620126201362014620156201662017620186201962020620216202262023620246202562026620276202862029620306203162032620336203462035620366203762038620396204062041620426204362044620456204662047620486204962050620516205262053620546205562056620576205862059620606206162062620636206462065620666206762068620696207062071620726207362074620756207662077620786207962080620816208262083620846208562086620876208862089620906209162092620936209462095620966209762098620996210062101621026210362104621056210662107621086210962110621116211262113621146211562116621176211862119621206212162122621236212462125621266212762128621296213062131621326213362134621356213662137621386213962140621416214262143621446214562146621476214862149621506215162152621536215462155621566215762158621596216062161621626216362164621656216662167621686216962170621716217262173621746217562176621776217862179621806218162182621836218462185621866218762188621896219062191621926219362194621956219662197621986219962200622016220262203622046220562206622076220862209622106221162212622136221462215622166221762218622196222062221622226222362224622256222662227622286222962230622316223262233622346223562236622376223862239622406224162242622436224462245622466224762248622496225062251622526225362254622556225662257622586225962260622616226262263622646226562266622676226862269622706227162272622736227462275622766227762278622796228062281622826228362284622856228662287622886228962290622916229262293622946229562296622976229862299623006230162302623036230462305623066230762308623096231062311623126231362314623156231662317623186231962320623216232262323623246232562326623276232862329623306233162332623336233462335623366233762338623396234062341623426234362344623456234662347623486234962350623516235262353623546235562356623576235862359623606236162362623636236462365623666236762368623696237062371623726237362374623756237662377623786237962380623816238262383623846238562386623876238862389623906239162392623936239462395623966239762398623996240062401624026240362404624056240662407624086240962410624116241262413624146241562416624176241862419624206242162422624236242462425624266242762428624296243062431624326243362434624356243662437624386243962440624416244262443624446244562446624476244862449624506245162452624536245462455624566245762458624596246062461624626246362464624656246662467624686246962470624716247262473624746247562476624776247862479624806248162482624836248462485624866248762488624896249062491624926249362494624956249662497624986249962500625016250262503625046250562506625076250862509625106251162512625136251462515625166251762518625196252062521625226252362524625256252662527625286252962530625316253262533625346253562536625376253862539625406254162542625436254462545625466254762548625496255062551625526255362554625556255662557625586255962560625616256262563625646256562566625676256862569625706257162572625736257462575625766257762578625796258062581625826258362584625856258662587625886258962590625916259262593625946259562596625976259862599626006260162602626036260462605626066260762608626096261062611626126261362614626156261662617626186261962620626216262262623626246262562626626276262862629626306263162632626336263462635626366263762638626396264062641626426264362644626456264662647626486264962650626516265262653626546265562656626576265862659626606266162662626636266462665626666266762668626696267062671626726267362674626756267662677626786267962680626816268262683626846268562686626876268862689626906269162692626936269462695626966269762698626996270062701627026270362704627056270662707627086270962710627116271262713627146271562716627176271862719627206272162722627236272462725627266272762728627296273062731627326273362734627356273662737627386273962740627416274262743627446274562746627476274862749627506275162752627536275462755627566275762758627596276062761627626276362764627656276662767627686276962770627716277262773627746277562776627776277862779627806278162782627836278462785627866278762788627896279062791627926279362794627956279662797627986279962800628016280262803628046280562806628076280862809628106281162812628136281462815628166281762818628196282062821628226282362824628256282662827628286282962830628316283262833628346283562836628376283862839628406284162842628436284462845628466284762848628496285062851628526285362854628556285662857628586285962860628616286262863628646286562866628676286862869628706287162872628736287462875628766287762878628796288062881628826288362884628856288662887628886288962890628916289262893628946289562896628976289862899629006290162902629036290462905629066290762908629096291062911629126291362914629156291662917629186291962920629216292262923629246292562926629276292862929629306293162932629336293462935629366293762938629396294062941629426294362944629456294662947629486294962950629516295262953629546295562956629576295862959629606296162962629636296462965629666296762968629696297062971629726297362974629756297662977629786297962980629816298262983629846298562986629876298862989629906299162992629936299462995629966299762998629996300063001630026300363004630056300663007630086300963010630116301263013630146301563016630176301863019630206302163022630236302463025630266302763028630296303063031630326303363034630356303663037630386303963040630416304263043630446304563046630476304863049630506305163052630536305463055630566305763058630596306063061630626306363064630656306663067630686306963070630716307263073630746307563076630776307863079630806308163082630836308463085630866308763088630896309063091630926309363094630956309663097630986309963100631016310263103631046310563106631076310863109631106311163112631136311463115631166311763118631196312063121631226312363124631256312663127631286312963130631316313263133631346313563136631376313863139631406314163142631436314463145631466314763148631496315063151631526315363154631556315663157631586315963160631616316263163631646316563166631676316863169631706317163172631736317463175631766317763178631796318063181631826318363184631856318663187631886318963190631916319263193631946319563196631976319863199632006320163202632036320463205632066320763208632096321063211632126321363214632156321663217632186321963220632216322263223632246322563226632276322863229632306323163232632336323463235632366323763238632396324063241632426324363244632456324663247632486324963250632516325263253632546325563256632576325863259632606326163262632636326463265632666326763268632696327063271632726327363274632756327663277632786327963280632816328263283632846328563286632876328863289632906329163292632936329463295632966329763298632996330063301633026330363304633056330663307633086330963310633116331263313633146331563316633176331863319633206332163322633236332463325633266332763328633296333063331633326333363334633356333663337633386333963340633416334263343633446334563346633476334863349633506335163352633536335463355633566335763358633596336063361633626336363364633656336663367633686336963370633716337263373633746337563376633776337863379633806338163382633836338463385633866338763388633896339063391633926339363394633956339663397633986339963400634016340263403634046340563406634076340863409634106341163412634136341463415634166341763418634196342063421634226342363424634256342663427634286342963430634316343263433634346343563436634376343863439634406344163442634436344463445634466344763448634496345063451634526345363454634556345663457634586345963460634616346263463634646346563466634676346863469634706347163472634736347463475634766347763478634796348063481634826348363484634856348663487634886348963490634916349263493634946349563496634976349863499635006350163502635036350463505635066350763508635096351063511635126351363514635156351663517635186351963520635216352263523635246352563526635276352863529635306353163532635336353463535635366353763538635396354063541635426354363544635456354663547635486354963550635516355263553635546355563556635576355863559635606356163562635636356463565635666356763568635696357063571635726357363574635756357663577635786357963580635816358263583635846358563586635876358863589635906359163592635936359463595635966359763598635996360063601636026360363604636056360663607636086360963610636116361263613636146361563616636176361863619636206362163622636236362463625636266362763628636296363063631636326363363634636356363663637636386363963640636416364263643636446364563646636476364863649636506365163652636536365463655636566365763658636596366063661636626366363664636656366663667636686366963670636716367263673636746367563676636776367863679636806368163682636836368463685636866368763688636896369063691636926369363694636956369663697636986369963700637016370263703637046370563706637076370863709637106371163712637136371463715637166371763718637196372063721637226372363724637256372663727637286372963730637316373263733637346373563736637376373863739637406374163742637436374463745637466374763748637496375063751637526375363754637556375663757637586375963760637616376263763637646376563766637676376863769637706377163772637736377463775637766377763778637796378063781637826378363784637856378663787637886378963790637916379263793637946379563796637976379863799638006380163802638036380463805638066380763808638096381063811638126381363814638156381663817638186381963820638216382263823638246382563826638276382863829638306383163832638336383463835638366383763838638396384063841638426384363844638456384663847638486384963850638516385263853638546385563856638576385863859638606386163862638636386463865638666386763868638696387063871638726387363874638756387663877638786387963880638816388263883638846388563886638876388863889638906389163892638936389463895638966389763898638996390063901639026390363904639056390663907639086390963910639116391263913639146391563916639176391863919639206392163922639236392463925639266392763928639296393063931639326393363934639356393663937639386393963940639416394263943639446394563946639476394863949639506395163952639536395463955639566395763958639596396063961639626396363964639656396663967639686396963970639716397263973639746397563976639776397863979639806398163982639836398463985639866398763988639896399063991639926399363994639956399663997639986399964000640016400264003640046400564006640076400864009640106401164012640136401464015640166401764018640196402064021640226402364024640256402664027640286402964030640316403264033640346403564036640376403864039640406404164042640436404464045640466404764048640496405064051640526405364054640556405664057640586405964060640616406264063640646406564066640676406864069640706407164072640736407464075640766407764078640796408064081640826408364084640856408664087640886408964090640916409264093640946409564096640976409864099641006410164102641036410464105641066410764108641096411064111641126411364114641156411664117641186411964120641216412264123641246412564126641276412864129641306413164132641336413464135641366413764138641396414064141641426414364144641456414664147641486414964150641516415264153641546415564156641576415864159641606416164162641636416464165641666416764168641696417064171641726417364174641756417664177641786417964180641816418264183641846418564186641876418864189641906419164192641936419464195641966419764198641996420064201642026420364204642056420664207642086420964210642116421264213642146421564216642176421864219642206422164222642236422464225642266422764228642296423064231642326423364234642356423664237642386423964240642416424264243642446424564246642476424864249642506425164252642536425464255642566425764258642596426064261642626426364264642656426664267642686426964270642716427264273642746427564276642776427864279642806428164282642836428464285642866428764288642896429064291642926429364294642956429664297642986429964300643016430264303643046430564306643076430864309643106431164312643136431464315643166431764318643196432064321643226432364324643256432664327643286432964330643316433264333643346433564336643376433864339643406434164342643436434464345643466434764348643496435064351643526435364354643556435664357643586435964360643616436264363643646436564366643676436864369643706437164372643736437464375643766437764378643796438064381643826438364384643856438664387643886438964390643916439264393643946439564396643976439864399644006440164402644036440464405644066440764408644096441064411644126441364414644156441664417644186441964420644216442264423644246442564426644276442864429644306443164432644336443464435644366443764438644396444064441644426444364444644456444664447644486444964450644516445264453644546445564456644576445864459644606446164462644636446464465644666446764468644696447064471644726447364474644756447664477644786447964480644816448264483644846448564486644876448864489644906449164492644936449464495644966449764498644996450064501645026450364504645056450664507645086450964510645116451264513645146451564516645176451864519645206452164522645236452464525645266452764528645296453064531645326453364534645356453664537645386453964540645416454264543645446454564546645476454864549645506455164552645536455464555645566455764558645596456064561645626456364564645656456664567645686456964570645716457264573645746457564576645776457864579645806458164582645836458464585645866458764588645896459064591645926459364594645956459664597645986459964600646016460264603646046460564606646076460864609646106461164612646136461464615646166461764618646196462064621646226462364624646256462664627646286462964630646316463264633646346463564636646376463864639646406464164642646436464464645646466464764648646496465064651646526465364654646556465664657646586465964660646616466264663646646466564666646676466864669646706467164672646736467464675646766467764678646796468064681646826468364684646856468664687646886468964690646916469264693646946469564696646976469864699647006470164702647036470464705647066470764708647096471064711647126471364714647156471664717647186471964720647216472264723647246472564726647276472864729647306473164732647336473464735647366473764738647396474064741647426474364744647456474664747647486474964750647516475264753647546475564756647576475864759647606476164762647636476464765647666476764768647696477064771647726477364774647756477664777647786477964780647816478264783647846478564786647876478864789647906479164792647936479464795647966479764798647996480064801648026480364804648056480664807648086480964810648116481264813648146481564816648176481864819648206482164822648236482464825648266482764828648296483064831648326483364834648356483664837648386483964840648416484264843648446484564846648476484864849648506485164852648536485464855648566485764858648596486064861648626486364864648656486664867648686486964870648716487264873648746487564876648776487864879648806488164882648836488464885648866488764888648896489064891648926489364894648956489664897648986489964900649016490264903649046490564906649076490864909649106491164912649136491464915649166491764918649196492064921649226492364924649256492664927649286492964930649316493264933649346493564936649376493864939649406494164942649436494464945649466494764948649496495064951649526495364954649556495664957649586495964960649616496264963649646496564966649676496864969649706497164972649736497464975649766497764978649796498064981649826498364984649856498664987649886498964990649916499264993649946499564996649976499864999650006500165002650036500465005650066500765008650096501065011650126501365014650156501665017650186501965020650216502265023650246502565026650276502865029650306503165032650336503465035650366503765038650396504065041650426504365044650456504665047650486504965050650516505265053650546505565056650576505865059650606506165062650636506465065650666506765068650696507065071650726507365074650756507665077650786507965080650816508265083650846508565086650876508865089650906509165092650936509465095650966509765098650996510065101651026510365104651056510665107651086510965110651116511265113651146511565116651176511865119651206512165122651236512465125651266512765128651296513065131651326513365134651356513665137651386513965140651416514265143651446514565146651476514865149651506515165152651536515465155651566515765158651596516065161651626516365164651656516665167651686516965170651716517265173651746517565176651776517865179651806518165182651836518465185651866518765188651896519065191651926519365194651956519665197651986519965200652016520265203652046520565206652076520865209652106521165212652136521465215652166521765218652196522065221652226522365224652256522665227652286522965230652316523265233652346523565236652376523865239652406524165242652436524465245652466524765248652496525065251652526525365254652556525665257652586525965260652616526265263652646526565266652676526865269652706527165272652736527465275652766527765278652796528065281652826528365284652856528665287652886528965290652916529265293652946529565296652976529865299653006530165302653036530465305653066530765308653096531065311653126531365314653156531665317653186531965320653216532265323653246532565326653276532865329653306533165332653336533465335653366533765338653396534065341653426534365344653456534665347653486534965350653516535265353653546535565356653576535865359653606536165362653636536465365653666536765368653696537065371653726537365374653756537665377653786537965380653816538265383653846538565386653876538865389653906539165392653936539465395653966539765398653996540065401654026540365404654056540665407654086540965410654116541265413654146541565416654176541865419654206542165422654236542465425654266542765428654296543065431654326543365434654356543665437654386543965440654416544265443654446544565446654476544865449654506545165452654536545465455654566545765458654596546065461654626546365464654656546665467654686546965470654716547265473654746547565476654776547865479654806548165482654836548465485654866548765488654896549065491654926549365494654956549665497654986549965500655016550265503655046550565506655076550865509655106551165512655136551465515655166551765518655196552065521655226552365524655256552665527655286552965530655316553265533655346553565536655376553865539655406554165542655436554465545655466554765548655496555065551655526555365554655556555665557655586555965560655616556265563655646556565566655676556865569655706557165572655736557465575655766557765578655796558065581655826558365584655856558665587655886558965590655916559265593655946559565596655976559865599656006560165602656036560465605656066560765608656096561065611656126561365614656156561665617656186561965620656216562265623656246562565626656276562865629656306563165632656336563465635656366563765638656396564065641656426564365644656456564665647656486564965650656516565265653656546565565656656576565865659656606566165662656636566465665656666566765668656696567065671656726567365674656756567665677656786567965680656816568265683656846568565686656876568865689656906569165692656936569465695656966569765698656996570065701657026570365704657056570665707657086570965710657116571265713657146571565716657176571865719657206572165722657236572465725657266572765728657296573065731657326573365734657356573665737657386573965740657416574265743657446574565746657476574865749657506575165752657536575465755657566575765758657596576065761657626576365764657656576665767657686576965770657716577265773657746577565776657776577865779657806578165782657836578465785657866578765788657896579065791657926579365794657956579665797657986579965800658016580265803658046580565806658076580865809658106581165812658136581465815658166581765818658196582065821658226582365824658256582665827658286582965830658316583265833658346583565836658376583865839658406584165842658436584465845658466584765848658496585065851658526585365854658556585665857658586585965860658616586265863658646586565866658676586865869658706587165872658736587465875658766587765878658796588065881658826588365884658856588665887658886588965890658916589265893658946589565896658976589865899659006590165902659036590465905659066590765908659096591065911659126591365914659156591665917659186591965920659216592265923659246592565926659276592865929659306593165932659336593465935659366593765938659396594065941659426594365944659456594665947659486594965950659516595265953659546595565956659576595865959659606596165962659636596465965659666596765968659696597065971659726597365974659756597665977659786597965980659816598265983659846598565986659876598865989659906599165992659936599465995659966599765998659996600066001660026600366004660056600666007660086600966010660116601266013660146601566016660176601866019660206602166022660236602466025660266602766028660296603066031660326603366034660356603666037660386603966040660416604266043660446604566046660476604866049660506605166052660536605466055660566605766058660596606066061660626606366064660656606666067660686606966070660716607266073660746607566076660776607866079660806608166082660836608466085660866608766088660896609066091660926609366094660956609666097660986609966100661016610266103661046610566106661076610866109661106611166112661136611466115661166611766118661196612066121661226612366124661256612666127661286612966130661316613266133661346613566136661376613866139661406614166142661436614466145661466614766148661496615066151661526615366154661556615666157661586615966160661616616266163661646616566166661676616866169661706617166172661736617466175661766617766178661796618066181661826618366184661856618666187661886618966190661916619266193661946619566196661976619866199662006620166202662036620466205662066620766208662096621066211662126621366214662156621666217662186621966220662216622266223662246622566226662276622866229662306623166232662336623466235662366623766238662396624066241662426624366244662456624666247662486624966250662516625266253662546625566256662576625866259662606626166262662636626466265662666626766268662696627066271662726627366274662756627666277662786627966280662816628266283662846628566286662876628866289662906629166292662936629466295662966629766298662996630066301663026630366304663056630666307663086630966310663116631266313663146631566316663176631866319663206632166322663236632466325663266632766328663296633066331663326633366334663356633666337663386633966340663416634266343663446634566346663476634866349663506635166352663536635466355663566635766358663596636066361663626636366364663656636666367663686636966370663716637266373663746637566376663776637866379663806638166382663836638466385663866638766388663896639066391663926639366394663956639666397663986639966400664016640266403664046640566406664076640866409664106641166412664136641466415664166641766418664196642066421664226642366424664256642666427664286642966430664316643266433664346643566436664376643866439664406644166442664436644466445664466644766448664496645066451664526645366454664556645666457664586645966460664616646266463664646646566466664676646866469664706647166472664736647466475664766647766478664796648066481664826648366484664856648666487664886648966490664916649266493664946649566496664976649866499665006650166502665036650466505665066650766508665096651066511665126651366514665156651666517665186651966520665216652266523665246652566526665276652866529665306653166532665336653466535665366653766538665396654066541665426654366544665456654666547665486654966550665516655266553665546655566556665576655866559665606656166562665636656466565665666656766568665696657066571665726657366574665756657666577665786657966580665816658266583665846658566586665876658866589665906659166592665936659466595665966659766598665996660066601666026660366604666056660666607666086660966610666116661266613666146661566616666176661866619666206662166622666236662466625666266662766628666296663066631666326663366634666356663666637666386663966640666416664266643666446664566646666476664866649666506665166652666536665466655666566665766658666596666066661666626666366664666656666666667666686666966670666716667266673666746667566676666776667866679666806668166682666836668466685666866668766688666896669066691666926669366694666956669666697666986669966700667016670266703667046670566706667076670866709667106671166712667136671466715667166671766718667196672066721667226672366724667256672666727667286672966730667316673266733667346673566736667376673866739667406674166742667436674466745667466674766748667496675066751667526675366754667556675666757667586675966760667616676266763667646676566766667676676866769667706677166772667736677466775667766677766778667796678066781667826678366784667856678666787667886678966790667916679266793667946679566796667976679866799668006680166802668036680466805668066680766808668096681066811668126681366814668156681666817668186681966820668216682266823668246682566826668276682866829668306683166832668336683466835668366683766838668396684066841668426684366844668456684666847668486684966850668516685266853668546685566856668576685866859668606686166862668636686466865668666686766868668696687066871668726687366874668756687666877668786687966880668816688266883668846688566886668876688866889668906689166892668936689466895668966689766898668996690066901669026690366904669056690666907669086690966910669116691266913669146691566916669176691866919669206692166922669236692466925669266692766928669296693066931669326693366934669356693666937669386693966940669416694266943669446694566946669476694866949669506695166952669536695466955669566695766958669596696066961669626696366964669656696666967669686696966970669716697266973669746697566976669776697866979669806698166982669836698466985669866698766988669896699066991669926699366994669956699666997669986699967000670016700267003670046700567006670076700867009670106701167012670136701467015670166701767018670196702067021670226702367024670256702667027670286702967030670316703267033670346703567036670376703867039670406704167042670436704467045670466704767048670496705067051670526705367054670556705667057670586705967060670616706267063670646706567066670676706867069670706707167072670736707467075670766707767078670796708067081670826708367084670856708667087670886708967090670916709267093670946709567096670976709867099671006710167102671036710467105671066710767108671096711067111671126711367114671156711667117671186711967120671216712267123671246712567126671276712867129671306713167132671336713467135671366713767138671396714067141671426714367144671456714667147671486714967150671516715267153671546715567156671576715867159671606716167162671636716467165671666716767168671696717067171671726717367174671756717667177671786717967180671816718267183671846718567186671876718867189671906719167192671936719467195671966719767198671996720067201672026720367204672056720667207672086720967210672116721267213672146721567216672176721867219672206722167222672236722467225672266722767228672296723067231672326723367234672356723667237672386723967240672416724267243672446724567246672476724867249672506725167252672536725467255672566725767258672596726067261672626726367264672656726667267672686726967270672716727267273672746727567276672776727867279672806728167282672836728467285672866728767288672896729067291672926729367294672956729667297672986729967300673016730267303673046730567306673076730867309673106731167312673136731467315673166731767318673196732067321673226732367324673256732667327673286732967330673316733267333673346733567336673376733867339673406734167342673436734467345673466734767348673496735067351673526735367354673556735667357673586735967360673616736267363673646736567366673676736867369673706737167372673736737467375673766737767378673796738067381673826738367384673856738667387673886738967390673916739267393673946739567396673976739867399674006740167402674036740467405674066740767408674096741067411674126741367414674156741667417674186741967420674216742267423674246742567426674276742867429674306743167432674336743467435674366743767438674396744067441674426744367444674456744667447674486744967450674516745267453674546745567456674576745867459674606746167462674636746467465674666746767468674696747067471674726747367474674756747667477674786747967480674816748267483674846748567486674876748867489674906749167492674936749467495674966749767498674996750067501675026750367504675056750667507675086750967510675116751267513675146751567516675176751867519675206752167522675236752467525675266752767528675296753067531675326753367534675356753667537675386753967540675416754267543675446754567546675476754867549675506755167552675536755467555675566755767558675596756067561675626756367564675656756667567675686756967570675716757267573675746757567576675776757867579675806758167582675836758467585675866758767588675896759067591675926759367594675956759667597675986759967600676016760267603676046760567606676076760867609676106761167612676136761467615676166761767618676196762067621676226762367624676256762667627676286762967630676316763267633676346763567636676376763867639676406764167642676436764467645676466764767648676496765067651676526765367654676556765667657676586765967660676616766267663676646766567666676676766867669676706767167672676736767467675676766767767678676796768067681676826768367684676856768667687676886768967690676916769267693676946769567696676976769867699677006770167702677036770467705677066770767708677096771067711677126771367714677156771667717677186771967720677216772267723677246772567726677276772867729677306773167732677336773467735677366773767738677396774067741677426774367744677456774667747677486774967750677516775267753677546775567756677576775867759677606776167762677636776467765677666776767768677696777067771677726777367774677756777667777677786777967780677816778267783677846778567786677876778867789677906779167792677936779467795677966779767798677996780067801678026780367804678056780667807678086780967810678116781267813678146781567816678176781867819678206782167822678236782467825678266782767828678296783067831678326783367834678356783667837678386783967840678416784267843678446784567846678476784867849678506785167852678536785467855678566785767858678596786067861678626786367864678656786667867678686786967870678716787267873678746787567876678776787867879678806788167882678836788467885678866788767888678896789067891678926789367894
  1. /**
  2. * Tween.js - Licensed under the MIT license
  3. * https://github.com/sole/tween.js
  4. * ----------------------------------------------
  5. *
  6. * See https://github.com/sole/tween.js/graphs/contributors for the full list of contributors.
  7. * Thank you all, you're awesome!
  8. */
  9. // Date.now shim for (ahem) Internet Explo(d|r)er
  10. if ( Date.now === undefined ) {
  11. Date.now = function () {
  12. return new Date().valueOf();
  13. };
  14. }
  15. var TWEEN = TWEEN || ( function () {
  16. var _tweens = [];
  17. return {
  18. REVISION: '14',
  19. getAll: function () {
  20. return _tweens;
  21. },
  22. removeAll: function () {
  23. _tweens = [];
  24. },
  25. add: function ( tween ) {
  26. _tweens.push( tween );
  27. },
  28. remove: function ( tween ) {
  29. var i = _tweens.indexOf( tween );
  30. if ( i !== -1 ) {
  31. _tweens.splice( i, 1 );
  32. }
  33. },
  34. update: function ( time ) {
  35. if ( _tweens.length === 0 ) return false;
  36. var i = 0;
  37. time = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() );
  38. while ( i < _tweens.length ) {
  39. if ( _tweens[ i ].update( time ) ) {
  40. i++;
  41. } else {
  42. _tweens.splice( i, 1 );
  43. }
  44. }
  45. return true;
  46. }
  47. };
  48. } )();
  49. TWEEN.Tween = function ( object ) {
  50. var _object = object;
  51. var _valuesStart = {};
  52. var _valuesEnd = {};
  53. var _valuesStartRepeat = {};
  54. var _duration = 1000;
  55. var _repeat = 0;
  56. var _yoyo = false;
  57. var _isPlaying = false;
  58. var _reversed = false;
  59. var _delayTime = 0;
  60. var _startTime = null;
  61. var _easingFunction = TWEEN.Easing.Linear.None;
  62. var _interpolationFunction = TWEEN.Interpolation.Linear;
  63. var _chainedTweens = [];
  64. var _onStartCallback = null;
  65. var _onStartCallbackFired = false;
  66. var _onUpdateCallback = null;
  67. var _onCompleteCallback = null;
  68. var _onStopCallback = null;
  69. // Set all starting values present on the target object
  70. for ( var field in object ) {
  71. _valuesStart[ field ] = parseFloat(object[field], 10);
  72. }
  73. this.to = function ( properties, duration ) {
  74. if ( duration !== undefined ) {
  75. _duration = duration;
  76. }
  77. _valuesEnd = properties;
  78. return this;
  79. };
  80. this.start = function ( time ) {
  81. TWEEN.add( this );
  82. _isPlaying = true;
  83. _onStartCallbackFired = false;
  84. _startTime = time !== undefined ? time : ( typeof window !== 'undefined' && window.performance !== undefined && window.performance.now !== undefined ? window.performance.now() : Date.now() );
  85. _startTime += _delayTime;
  86. for ( var property in _valuesEnd ) {
  87. // check if an Array was provided as property value
  88. if ( _valuesEnd[ property ] instanceof Array ) {
  89. if ( _valuesEnd[ property ].length === 0 ) {
  90. continue;
  91. }
  92. // create a local copy of the Array with the start value at the front
  93. _valuesEnd[ property ] = [ _object[ property ] ].concat( _valuesEnd[ property ] );
  94. }
  95. _valuesStart[ property ] = _object[ property ];
  96. if( ( _valuesStart[ property ] instanceof Array ) === false ) {
  97. _valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings
  98. }
  99. _valuesStartRepeat[ property ] = _valuesStart[ property ] || 0;
  100. }
  101. return this;
  102. };
  103. this.stop = function () {
  104. if ( !_isPlaying ) {
  105. return this;
  106. }
  107. TWEEN.remove( this );
  108. _isPlaying = false;
  109. if ( _onStopCallback !== null ) {
  110. _onStopCallback.call( _object );
  111. }
  112. this.stopChainedTweens();
  113. return this;
  114. };
  115. this.stopChainedTweens = function () {
  116. for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) {
  117. _chainedTweens[ i ].stop();
  118. }
  119. };
  120. this.delay = function ( amount ) {
  121. _delayTime = amount;
  122. return this;
  123. };
  124. this.repeat = function ( times ) {
  125. _repeat = times;
  126. return this;
  127. };
  128. this.yoyo = function( yoyo ) {
  129. _yoyo = yoyo;
  130. return this;
  131. };
  132. this.easing = function ( easing ) {
  133. _easingFunction = easing;
  134. return this;
  135. };
  136. this.interpolation = function ( interpolation ) {
  137. _interpolationFunction = interpolation;
  138. return this;
  139. };
  140. this.chain = function () {
  141. _chainedTweens = arguments;
  142. return this;
  143. };
  144. this.onStart = function ( callback ) {
  145. _onStartCallback = callback;
  146. return this;
  147. };
  148. this.onUpdate = function ( callback ) {
  149. _onUpdateCallback = callback;
  150. return this;
  151. };
  152. this.onComplete = function ( callback ) {
  153. _onCompleteCallback = callback;
  154. return this;
  155. };
  156. this.onStop = function ( callback ) {
  157. _onStopCallback = callback;
  158. return this;
  159. };
  160. this.update = function ( time ) {
  161. var property;
  162. if ( time < _startTime ) {
  163. return true;
  164. }
  165. if ( _onStartCallbackFired === false ) {
  166. if ( _onStartCallback !== null ) {
  167. _onStartCallback.call( _object );
  168. }
  169. _onStartCallbackFired = true;
  170. }
  171. var elapsed = ( time - _startTime ) / _duration;
  172. elapsed = elapsed > 1 ? 1 : elapsed;
  173. var value = _easingFunction( elapsed );
  174. for ( property in _valuesEnd ) {
  175. var start = _valuesStart[ property ] || 0;
  176. var end = _valuesEnd[ property ];
  177. if ( end instanceof Array ) {
  178. _object[ property ] = _interpolationFunction( end, value );
  179. } else {
  180. // Parses relative end values with start as base (e.g.: +10, -3)
  181. if ( typeof(end) === "string" ) {
  182. end = start + parseFloat(end, 10);
  183. }
  184. // protect against non numeric properties.
  185. if ( typeof(end) === "number" ) {
  186. _object[ property ] = start + ( end - start ) * value;
  187. }
  188. }
  189. }
  190. if ( _onUpdateCallback !== null ) {
  191. _onUpdateCallback.call( _object, value );
  192. }
  193. if ( elapsed == 1 ) {
  194. if ( _repeat > 0 ) {
  195. if( isFinite( _repeat ) ) {
  196. _repeat--;
  197. }
  198. // reassign starting values, restart by making startTime = now
  199. for( property in _valuesStartRepeat ) {
  200. if ( typeof( _valuesEnd[ property ] ) === "string" ) {
  201. _valuesStartRepeat[ property ] = _valuesStartRepeat[ property ] + parseFloat(_valuesEnd[ property ], 10);
  202. }
  203. if (_yoyo) {
  204. var tmp = _valuesStartRepeat[ property ];
  205. _valuesStartRepeat[ property ] = _valuesEnd[ property ];
  206. _valuesEnd[ property ] = tmp;
  207. }
  208. _valuesStart[ property ] = _valuesStartRepeat[ property ];
  209. }
  210. if (_yoyo) {
  211. _reversed = !_reversed;
  212. }
  213. _startTime = time + _delayTime;
  214. return true;
  215. } else {
  216. if ( _onCompleteCallback !== null ) {
  217. _onCompleteCallback.call( _object );
  218. }
  219. for ( var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++ ) {
  220. _chainedTweens[ i ].start( time );
  221. }
  222. return false;
  223. }
  224. }
  225. return true;
  226. };
  227. };
  228. TWEEN.Easing = {
  229. Linear: {
  230. None: function ( k ) {
  231. return k;
  232. }
  233. },
  234. Quadratic: {
  235. In: function ( k ) {
  236. return k * k;
  237. },
  238. Out: function ( k ) {
  239. return k * ( 2 - k );
  240. },
  241. InOut: function ( k ) {
  242. if ( ( k *= 2 ) < 1 ) return 0.5 * k * k;
  243. return - 0.5 * ( --k * ( k - 2 ) - 1 );
  244. }
  245. },
  246. Cubic: {
  247. In: function ( k ) {
  248. return k * k * k;
  249. },
  250. Out: function ( k ) {
  251. return --k * k * k + 1;
  252. },
  253. InOut: function ( k ) {
  254. if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k;
  255. return 0.5 * ( ( k -= 2 ) * k * k + 2 );
  256. }
  257. },
  258. Quartic: {
  259. In: function ( k ) {
  260. return k * k * k * k;
  261. },
  262. Out: function ( k ) {
  263. return 1 - ( --k * k * k * k );
  264. },
  265. InOut: function ( k ) {
  266. if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k;
  267. return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 );
  268. }
  269. },
  270. Quintic: {
  271. In: function ( k ) {
  272. return k * k * k * k * k;
  273. },
  274. Out: function ( k ) {
  275. return --k * k * k * k * k + 1;
  276. },
  277. InOut: function ( k ) {
  278. if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k;
  279. return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 );
  280. }
  281. },
  282. Sinusoidal: {
  283. In: function ( k ) {
  284. return 1 - Math.cos( k * Math.PI / 2 );
  285. },
  286. Out: function ( k ) {
  287. return Math.sin( k * Math.PI / 2 );
  288. },
  289. InOut: function ( k ) {
  290. return 0.5 * ( 1 - Math.cos( Math.PI * k ) );
  291. }
  292. },
  293. Exponential: {
  294. In: function ( k ) {
  295. return k === 0 ? 0 : Math.pow( 1024, k - 1 );
  296. },
  297. Out: function ( k ) {
  298. return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k );
  299. },
  300. InOut: function ( k ) {
  301. if ( k === 0 ) return 0;
  302. if ( k === 1 ) return 1;
  303. if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 );
  304. return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 );
  305. }
  306. },
  307. Circular: {
  308. In: function ( k ) {
  309. return 1 - Math.sqrt( 1 - k * k );
  310. },
  311. Out: function ( k ) {
  312. return Math.sqrt( 1 - ( --k * k ) );
  313. },
  314. InOut: function ( k ) {
  315. if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1);
  316. return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1);
  317. }
  318. },
  319. Elastic: {
  320. In: function ( k ) {
  321. var s, a = 0.1, p = 0.4;
  322. if ( k === 0 ) return 0;
  323. if ( k === 1 ) return 1;
  324. if ( !a || a < 1 ) { a = 1; s = p / 4; }
  325. else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
  326. return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
  327. },
  328. Out: function ( k ) {
  329. var s, a = 0.1, p = 0.4;
  330. if ( k === 0 ) return 0;
  331. if ( k === 1 ) return 1;
  332. if ( !a || a < 1 ) { a = 1; s = p / 4; }
  333. else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
  334. return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 );
  335. },
  336. InOut: function ( k ) {
  337. var s, a = 0.1, p = 0.4;
  338. if ( k === 0 ) return 0;
  339. if ( k === 1 ) return 1;
  340. if ( !a || a < 1 ) { a = 1; s = p / 4; }
  341. else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI );
  342. if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) );
  343. return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1;
  344. }
  345. },
  346. Back: {
  347. In: function ( k ) {
  348. var s = 1.70158;
  349. return k * k * ( ( s + 1 ) * k - s );
  350. },
  351. Out: function ( k ) {
  352. var s = 1.70158;
  353. return --k * k * ( ( s + 1 ) * k + s ) + 1;
  354. },
  355. InOut: function ( k ) {
  356. var s = 1.70158 * 1.525;
  357. if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) );
  358. return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 );
  359. }
  360. },
  361. Bounce: {
  362. In: function ( k ) {
  363. return 1 - TWEEN.Easing.Bounce.Out( 1 - k );
  364. },
  365. Out: function ( k ) {
  366. if ( k < ( 1 / 2.75 ) ) {
  367. return 7.5625 * k * k;
  368. } else if ( k < ( 2 / 2.75 ) ) {
  369. return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75;
  370. } else if ( k < ( 2.5 / 2.75 ) ) {
  371. return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375;
  372. } else {
  373. return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375;
  374. }
  375. },
  376. InOut: function ( k ) {
  377. if ( k < 0.5 ) return TWEEN.Easing.Bounce.In( k * 2 ) * 0.5;
  378. return TWEEN.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5;
  379. }
  380. }
  381. };
  382. TWEEN.Interpolation = {
  383. Linear: function ( v, k ) {
  384. var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.Linear;
  385. if ( k < 0 ) return fn( v[ 0 ], v[ 1 ], f );
  386. if ( k > 1 ) return fn( v[ m ], v[ m - 1 ], m - f );
  387. return fn( v[ i ], v[ i + 1 > m ? m : i + 1 ], f - i );
  388. },
  389. Bezier: function ( v, k ) {
  390. var b = 0, n = v.length - 1, pw = Math.pow, bn = TWEEN.Interpolation.Utils.Bernstein, i;
  391. for ( i = 0; i <= n; i++ ) {
  392. b += pw( 1 - k, n - i ) * pw( k, i ) * v[ i ] * bn( n, i );
  393. }
  394. return b;
  395. },
  396. CatmullRom: function ( v, k ) {
  397. var m = v.length - 1, f = m * k, i = Math.floor( f ), fn = TWEEN.Interpolation.Utils.CatmullRom;
  398. if ( v[ 0 ] === v[ m ] ) {
  399. if ( k < 0 ) i = Math.floor( f = m * ( 1 + k ) );
  400. return fn( v[ ( i - 1 + m ) % m ], v[ i ], v[ ( i + 1 ) % m ], v[ ( i + 2 ) % m ], f - i );
  401. } else {
  402. if ( k < 0 ) return v[ 0 ] - ( fn( v[ 0 ], v[ 0 ], v[ 1 ], v[ 1 ], -f ) - v[ 0 ] );
  403. if ( k > 1 ) return v[ m ] - ( fn( v[ m ], v[ m ], v[ m - 1 ], v[ m - 1 ], f - m ) - v[ m ] );
  404. return fn( v[ i ? i - 1 : 0 ], v[ i ], v[ m < i + 1 ? m : i + 1 ], v[ m < i + 2 ? m : i + 2 ], f - i );
  405. }
  406. },
  407. Utils: {
  408. Linear: function ( p0, p1, t ) {
  409. return ( p1 - p0 ) * t + p0;
  410. },
  411. Bernstein: function ( n , i ) {
  412. var fc = TWEEN.Interpolation.Utils.Factorial;
  413. return fc( n ) / fc( i ) / fc( n - i );
  414. },
  415. Factorial: ( function () {
  416. var a = [ 1 ];
  417. return function ( n ) {
  418. var s = 1, i;
  419. if ( a[ n ] ) return a[ n ];
  420. for ( i = n; i > 1; i-- ) s *= i;
  421. return a[ n ] = s;
  422. };
  423. } )(),
  424. CatmullRom: function ( p0, p1, p2, p3, t ) {
  425. var v0 = ( p2 - p0 ) * 0.5, v1 = ( p3 - p1 ) * 0.5, t2 = t * t, t3 = t * t2;
  426. return ( 2 * p1 - 2 * p2 + v0 + v1 ) * t3 + ( - 3 * p1 + 3 * p2 - 2 * v0 - v1 ) * t2 + v0 * t + p1;
  427. }
  428. }
  429. };
  430. ;
  431. (function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(global):typeof define==="function"&&define.amd?define(factory):factory(global)})(typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:this,function(global){"use strict";global=global||{};var _Base64=global.Base64;var version="2.5.1";var buffer;if(typeof module!=="undefined"&&module.exports){try{buffer=eval("require('buffer').Buffer")}catch(err){buffer=undefined}}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i<l;i++)t[bin.charAt(i)]=i;return t}(b64chars);var fromCharCode=String.fromCharCode;var cb_utob=function(c){if(c.length<2){var cc=c.charCodeAt(0);return cc<128?c:cc<2048?fromCharCode(192|cc>>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?buffer.from&&Uint8Array&&buffer.from!==Uint8Array.from?function(u){return(u.constructor===buffer.constructor?u:buffer.from(u)).toString("base64")}:function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][€-¿]","[à-ï][€-¿]{2}","[ð-÷][€-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var _atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/\S{1,4}/g,cb_decode)};var atob=function(a){return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g,""))};var _decode=buffer?buffer.from&&Uint8Array&&buffer.from!==Uint8Array.from?function(a){return(a.constructor===buffer.constructor?a:buffer.from(a,"base64")).toString()}:function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(_atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict,__buffer__:buffer};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}if(global["Meteor"]){Base64=global.Base64}if(typeof module!=="undefined"&&module.exports){module.exports.Base64=global.Base64}else if(typeof define==="function"&&define.amd){define([],function(){return global.Base64})}return{Base64:global.Base64}});;
  432. /*
  433. bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
  434. Backing buffer: ArrayBuffer, Accessor: Uint8Array
  435. Released under the Apache License, Version 2.0
  436. see: https://github.com/dcodeIO/bytebuffer.js for details
  437. */
  438. function u(k){function g(a,b,c){"undefined"===typeof a&&(a=g.DEFAULT_CAPACITY);"undefined"===typeof b&&(b=g.DEFAULT_ENDIAN);"undefined"===typeof c&&(c=g.DEFAULT_NOASSERT);if(!c){a|=0;if(0>a)throw RangeError("Illegal capacity");b=!!b;c=!!c}this.buffer=0===a?v:new ArrayBuffer(a);this.view=0===a?null:new Uint8Array(this.buffer);this.offset=0;this.markedOffset=-1;this.limit=a;this.littleEndian=b;this.noAssert=c}function m(a){var b=0;return function(){return b<a.length?a.charCodeAt(b++):null}}function s(){var a=
  439. [],b=[];return function(){if(0===arguments.length)return b.join("")+w.apply(String,a);1024<a.length+arguments.length&&(b.push(w.apply(String,a)),a.length=0);Array.prototype.push.apply(a,arguments)}}function x(a,b,c,d,f){var n;n=8*f-d-1;var h=(1<<n)-1,e=h>>1,g=-7;f=c?f-1:0;var q=c?-1:1,k=a[b+f];f+=q;c=k&(1<<-g)-1;k>>=-g;for(g+=n;0<g;c=256*c+a[b+f],f+=q,g-=8);n=c&(1<<-g)-1;c>>=-g;for(g+=d;0<g;n=256*n+a[b+f],f+=q,g-=8);if(0===c)c=1-e;else{if(c===h)return n?NaN:Infinity*(k?-1:1);n+=Math.pow(2,d);c-=e}return(k?
  440. -1:1)*n*Math.pow(2,c-d)}function z(a,b,c,d,f,n){var e,g=8*n-f-1,t=(1<<g)-1,k=t>>1,y=23===f?Math.pow(2,-24)-Math.pow(2,-77):0;n=d?0:n-1;var l=d?1:-1,m=0>b||0===b&&0>1/b?1:0;b=Math.abs(b);isNaN(b)||Infinity===b?(b=isNaN(b)?1:0,d=t):(d=Math.floor(Math.log(b)/Math.LN2),1>b*(e=Math.pow(2,-d))&&(d--,e*=2),b=1<=d+k?b+y/e:b+y*Math.pow(2,1-k),2<=b*e&&(d++,e/=2),d+k>=t?(b=0,d=t):1<=d+k?(b=(b*e-1)*Math.pow(2,f),d+=k):(b=b*Math.pow(2,k-1)*Math.pow(2,f),d=0));for(;8<=f;a[c+n]=b&255,n+=l,b/=256,f-=8);d=d<<f|b;
  441. for(g+=f;0<g;a[c+n]=d&255,n+=l,d/=256,g-=8);a[c+n-l]|=128*m}g.VERSION="5.0.0";g.LITTLE_ENDIAN=!0;g.BIG_ENDIAN=!1;g.DEFAULT_CAPACITY=16;g.DEFAULT_ENDIAN=g.BIG_ENDIAN;g.DEFAULT_NOASSERT=!1;g.Long=k||null;var e=g.prototype;Object.defineProperty(e,"__isByteBuffer__",{value:!0,enumerable:!1,configurable:!1});var v=new ArrayBuffer(0),w=String.fromCharCode;g.accessor=function(){return Uint8Array};g.allocate=function(a,b,c){return new g(a,b,c)};g.concat=function(a,b,c,d){if("boolean"===typeof b||"string"!==
  442. typeof b)d=c,c=b,b=void 0;for(var f=0,e=0,h=a.length,p;e<h;++e)g.isByteBuffer(a[e])||(a[e]=g.wrap(a[e],b)),p=a[e].limit-a[e].offset,0<p&&(f+=p);if(0===f)return new g(0,c,d);b=new g(f,c,d);for(e=0;e<h;)c=a[e++],p=c.limit-c.offset,0>=p||(b.view.set(c.view.subarray(c.offset,c.limit),b.offset),b.offset+=p);b.limit=b.offset;b.offset=0;return b};g.isByteBuffer=function(a){return!0===(a&&a.__isByteBuffer__)};g.type=function(){return ArrayBuffer};g.wrap=function(a,b,c,d){"string"!==typeof b&&(d=c,c=b,b=void 0);
  443. if("string"===typeof a)switch("undefined"===typeof b&&(b="utf8"),b){case "base64":return g.fromBase64(a,c);case "hex":return g.fromHex(a,c);case "binary":return g.fromBinary(a,c);case "utf8":return g.fromUTF8(a,c);case "debug":return g.fromDebug(a,c);default:throw Error("Unsupported encoding: "+b);}if(null===a||"object"!==typeof a)throw TypeError("Illegal buffer");if(g.isByteBuffer(a))return b=e.clone.call(a),b.markedOffset=-1,b;if(a instanceof Uint8Array)b=new g(0,c,d),0<a.length&&(b.buffer=a.buffer,
  444. b.offset=a.byteOffset,b.limit=a.byteOffset+a.byteLength,b.view=new Uint8Array(a.buffer));else if(a instanceof ArrayBuffer)b=new g(0,c,d),0<a.byteLength&&(b.buffer=a,b.offset=0,b.limit=a.byteLength,b.view=0<a.byteLength?new Uint8Array(a):null);else if("[object Array]"===Object.prototype.toString.call(a))for(b=new g(a.length,c,d),b.limit=a.length,c=0;c<a.length;++c)b.view[c]=a[c];else throw TypeError("Illegal buffer");return b};e.readBytes=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);
  445. if(!this.noAssert){if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+a>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+"+a+") <= "+this.buffer.byteLength);}var d=this.slice(b,b+a);c&&(this.offset+=a);return d};e.writeBytes=e.append;e.writeInt8=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==
  446. typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=1;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);this.view[b-1]=a;c&&(this.offset+=1);return this};e.writeByte=e.writeInt8;e.readInt8=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");
  447. a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}a=this.view[a];128===(a&128)&&(a=-(255-a+1));b&&(this.offset+=1);return a};e.readByte=e.readInt8;e.writeUint8=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=
  448. 0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=1;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);this.view[b-1]=a;c&&(this.offset+=1);return this};e.writeUInt8=e.writeUint8;e.readUint8=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
  449. a+" (+1) <= "+this.buffer.byteLength);}a=this.view[a];b&&(this.offset+=1);return a};e.readUInt8=e.readUint8;e.writeInt16=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);
  450. }b+=2;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=2;this.littleEndian?(this.view[b+1]=(a&65280)>>>8,this.view[b]=a&255):(this.view[b]=(a&65280)>>>8,this.view[b+1]=a&255);c&&(this.offset+=2);return this};e.writeShort=e.writeInt16;e.readInt16=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
  451. a+" (+2) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a],c|=this.view[a+1]<<8):(c=this.view[a]<<8,c|=this.view[a+1]);32768===(c&32768)&&(c=-(65535-c+1));b&&(this.offset+=2);return c};e.readShort=e.readInt16;e.writeUint16=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");
  452. b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=2;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=2;this.littleEndian?(this.view[b+1]=(a&65280)>>>8,this.view[b]=a&255):(this.view[b]=(a&65280)>>>8,this.view[b+1]=a&255);c&&(this.offset+=2);return this};e.writeUInt16=e.writeUint16;e.readUint16=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+
  453. a+" (not an integer)");a>>>=0;if(0>a||a+2>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+2) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a],c|=this.view[a+1]<<8):(c=this.view[a]<<8,c|=this.view[a+1]);b&&(this.offset+=2);return c};e.readUInt16=e.readUint16;e.writeInt32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==
  454. typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=4;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=4;this.littleEndian?(this.view[b+3]=a>>>24&255,this.view[b+2]=a>>>16&255,this.view[b+1]=a>>>8&255,this.view[b]=a&255):(this.view[b]=a>>>24&255,this.view[b+1]=a>>>16&255,this.view[b+2]=a>>>8&255,this.view[b+3]=a&255);c&&(this.offset+=4);
  455. return this};e.writeInt=e.writeInt32;e.readInt32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0):(c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+
  456. 3],c+=this.view[a]<<24>>>0);b&&(this.offset+=4);return c|0};e.readInt=e.readInt32;e.writeUint32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=4;var d=this.buffer.byteLength;
  457. b>d&&this.resize((d*=2)>b?d:b);b-=4;this.littleEndian?(this.view[b+3]=a>>>24&255,this.view[b+2]=a>>>16&255,this.view[b+1]=a>>>8&255,this.view[b]=a&255):(this.view[b]=a>>>24&255,this.view[b+1]=a>>>16&255,this.view[b+2]=a>>>8&255,this.view[b+3]=a&255);c&&(this.offset+=4);return this};e.writeUInt32=e.writeUint32;e.readUint32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>
  458. a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}var c=0;this.littleEndian?(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0):(c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=this.view[a]<<24>>>0);b&&(this.offset+=4);return c};e.readUInt32=e.readUint32;k&&(e.writeInt64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"===typeof a)a=k.fromNumber(a);
  459. else if("string"===typeof a)a=k.fromString(a);else if(!(a&&a instanceof k))throw TypeError("Illegal value: "+a+" (not an integer or Long)");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}"number"===typeof a?a=k.fromNumber(a):"string"===typeof a&&(a=k.fromString(a));b+=8;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=8;
  460. var d=a.low,f=a.high;this.littleEndian?(this.view[b+3]=d>>>24&255,this.view[b+2]=d>>>16&255,this.view[b+1]=d>>>8&255,this.view[b]=d&255,b+=4,this.view[b+3]=f>>>24&255,this.view[b+2]=f>>>16&255,this.view[b+1]=f>>>8&255,this.view[b]=f&255):(this.view[b]=f>>>24&255,this.view[b+1]=f>>>16&255,this.view[b+2]=f>>>8&255,this.view[b+3]=f&255,b+=4,this.view[b]=d>>>24&255,this.view[b+1]=d>>>16&255,this.view[b+2]=d>>>8&255,this.view[b+3]=d&255);c&&(this.offset+=8);return this},e.writeLong=e.writeInt64,e.readInt64=
  461. function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+8) <= "+this.buffer.byteLength);}var c=0,d=0;this.littleEndian?(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0,a+=4,d=this.view[a+2]<<16,d|=this.view[a+1]<<8,d|=this.view[a],d+=this.view[a+3]<<24>>>0):(d=this.view[a+
  462. 1]<<16,d|=this.view[a+2]<<8,d|=this.view[a+3],d+=this.view[a]<<24>>>0,a+=4,c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=this.view[a]<<24>>>0);a=new k(c,d,!1);b&&(this.offset+=8);return a},e.readLong=e.readInt64,e.writeUint64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"===typeof a)a=k.fromNumber(a);else if("string"===typeof a)a=k.fromString(a);else if(!(a&&a instanceof k))throw TypeError("Illegal value: "+a+" (not an integer or Long)");
  463. if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}"number"===typeof a?a=k.fromNumber(a):"string"===typeof a&&(a=k.fromString(a));b+=8;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=8;var d=a.low,f=a.high;this.littleEndian?(this.view[b+3]=d>>>24&255,this.view[b+2]=d>>>16&255,this.view[b+1]=d>>>8&255,this.view[b]=d&255,b+=4,
  464. this.view[b+3]=f>>>24&255,this.view[b+2]=f>>>16&255,this.view[b+1]=f>>>8&255,this.view[b]=f&255):(this.view[b]=f>>>24&255,this.view[b+1]=f>>>16&255,this.view[b+2]=f>>>8&255,this.view[b+3]=f&255,b+=4,this.view[b]=d>>>24&255,this.view[b+1]=d>>>16&255,this.view[b+2]=d>>>8&255,this.view[b+3]=d&255);c&&(this.offset+=8);return this},e.writeUInt64=e.writeUint64,e.readUint64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+
  465. a+" (not an integer)");a>>>=0;if(0>a||a+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+8) <= "+this.buffer.byteLength);}var c=0,d=0;this.littleEndian?(c=this.view[a+2]<<16,c|=this.view[a+1]<<8,c|=this.view[a],c+=this.view[a+3]<<24>>>0,a+=4,d=this.view[a+2]<<16,d|=this.view[a+1]<<8,d|=this.view[a],d+=this.view[a+3]<<24>>>0):(d=this.view[a+1]<<16,d|=this.view[a+2]<<8,d|=this.view[a+3],d+=this.view[a]<<24>>>0,a+=4,c=this.view[a+1]<<16,c|=this.view[a+2]<<8,c|=this.view[a+3],c+=
  466. this.view[a]<<24>>>0);a=new k(c,d,!0);b&&(this.offset+=8);return a},e.readUInt64=e.readUint64);e.writeFloat32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a)throw TypeError("Illegal value: "+a+" (not a number)");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=4;var d=this.buffer.byteLength;
  467. b>d&&this.resize((d*=2)>b?d:b);z(this.view,a,b-4,this.littleEndian,23,4);c&&(this.offset+=4);return this};e.writeFloat=e.writeFloat32;e.readFloat32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}a=x(this.view,a,this.littleEndian,23,4);b&&(this.offset+=4);return a};
  468. e.readFloat=e.readFloat32;e.writeFloat64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a)throw TypeError("Illegal value: "+a+" (not a number)");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}b+=8;var d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);z(this.view,a,b-8,this.littleEndian,
  469. 52,8);c&&(this.offset+=8);return this};e.writeDouble=e.writeFloat64;e.readFloat64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+8>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+8) <= "+this.buffer.byteLength);}a=x(this.view,a,this.littleEndian,52,8);b&&(this.offset+=8);return a};e.readDouble=e.readFloat64;g.MAX_VARINT32_BYTES=5;g.calculateVarint32=
  470. function(a){a>>>=0;return 128>a?1:16384>a?2:2097152>a?3:268435456>a?4:5};g.zigZagEncode32=function(a){return((a|=0)<<1^a>>31)>>>0};g.zigZagDecode32=function(a){return a>>>1^-(a&1)|0};e.writeVarint32=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
  471. b+" (+0) <= "+this.buffer.byteLength);}var d=g.calculateVarint32(a),f;b+=d;f=this.buffer.byteLength;b>f&&this.resize((f*=2)>b?f:b);b-=d;for(a>>>=0;128<=a;)f=a&127|128,this.view[b++]=f,a>>>=7;this.view[b++]=a;return c?(this.offset=b,this):d};e.writeVarint32ZigZag=function(a,b){return this.writeVarint32(g.zigZagEncode32(a),b)};e.readVarint32=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");
  472. a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=0,d=0,f;do{if(!this.noAssert&&a>this.limit)throw a=Error("Truncated"),a.truncated=!0,a;f=this.view[a++];5>c&&(d|=(f&127)<<7*c);++c}while(0!==(f&128));d|=0;return b?(this.offset=a,d):{value:d,length:c}};e.readVarint32ZigZag=function(a){a=this.readVarint32(a);"object"===typeof a?a.value=g.zigZagDecode32(a.value):a=g.zigZagDecode32(a);return a};k&&(g.MAX_VARINT64_BYTES=10,g.calculateVarint64=
  473. function(a){"number"===typeof a?a=k.fromNumber(a):"string"===typeof a&&(a=k.fromString(a));var b=a.toInt()>>>0,c=a.shiftRightUnsigned(28).toInt()>>>0;a=a.shiftRightUnsigned(56).toInt()>>>0;return 0==a?0==c?16384>b?128>b?1:2:2097152>b?3:4:16384>c?128>c?5:6:2097152>c?7:8:128>a?9:10},g.zigZagEncode64=function(a){"number"===typeof a?a=k.fromNumber(a,!1):"string"===typeof a?a=k.fromString(a,!1):!1!==a.unsigned&&(a=a.toSigned());return a.shiftLeft(1).xor(a.shiftRight(63)).toUnsigned()},g.zigZagDecode64=
  474. function(a){"number"===typeof a?a=k.fromNumber(a,!1):"string"===typeof a?a=k.fromString(a,!1):!1!==a.unsigned&&(a=a.toSigned());return a.shiftRightUnsigned(1).xor(a.and(k.ONE).toSigned().negate()).toSigned()},e.writeVarint64=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"===typeof a)a=k.fromNumber(a);else if("string"===typeof a)a=k.fromString(a);else if(!(a&&a instanceof k))throw TypeError("Illegal value: "+a+" (not an integer or Long)");if("number"!==
  475. typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}"number"===typeof a?a=k.fromNumber(a,!1):"string"===typeof a?a=k.fromString(a,!1):!1!==a.unsigned&&(a=a.toSigned());var d=g.calculateVarint64(a),f=a.toInt()>>>0,e=a.shiftRightUnsigned(28).toInt()>>>0,h=a.shiftRightUnsigned(56).toInt()>>>0;b+=d;var p=this.buffer.byteLength;b>p&&this.resize((p*=2)>b?p:b);
  476. b-=d;switch(d){case 10:this.view[b+9]=h>>>7&1;case 9:this.view[b+8]=9!==d?h|128:h&127;case 8:this.view[b+7]=8!==d?e>>>21|128:e>>>21&127;case 7:this.view[b+6]=7!==d?e>>>14|128:e>>>14&127;case 6:this.view[b+5]=6!==d?e>>>7|128:e>>>7&127;case 5:this.view[b+4]=5!==d?e|128:e&127;case 4:this.view[b+3]=4!==d?f>>>21|128:f>>>21&127;case 3:this.view[b+2]=3!==d?f>>>14|128:f>>>14&127;case 2:this.view[b+1]=2!==d?f>>>7|128:f>>>7&127;case 1:this.view[b]=1!==d?f|128:f&127}return c?(this.offset+=d,this):d},e.writeVarint64ZigZag=
  477. function(a,b){return this.writeVarint64(g.zigZagEncode64(a),b)},e.readVarint64=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=a,d=0,f=0,e=0,h=0,h=this.view[a++],d=h&127;if(h&128&&(h=this.view[a++],d|=(h&127)<<7,h&128||this.noAssert&&"undefined"===typeof h)&&
  478. (h=this.view[a++],d|=(h&127)<<14,h&128||this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],d|=(h&127)<<21,h&128||this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],f=h&127,h&128||this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],f|=(h&127)<<7,h&128||this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],f|=(h&127)<<14,h&128||this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],f|=(h&127)<<21,h&128||this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],e=h&127,h&128||
  479. this.noAssert&&"undefined"===typeof h)&&(h=this.view[a++],e|=(h&127)<<7,h&128||this.noAssert&&"undefined"===typeof h))throw Error("Buffer overrun");d=k.fromBits(d|f<<28,f>>>4|e<<24,!1);return b?(this.offset=a,d):{value:d,length:a-c}},e.readVarint64ZigZag=function(a){(a=this.readVarint64(a))&&a.value instanceof k?a.value=g.zigZagDecode64(a.value):a=g.zigZagDecode64(a);return a});e.writeCString=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);var d,f=a.length;if(!this.noAssert){if("string"!==
  480. typeof a)throw TypeError("Illegal str: Not a string");for(d=0;d<f;++d)if(0===a.charCodeAt(d))throw RangeError("Illegal str: Contains NULL-characters");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}f=l.a(m(a))[1];b+=f+1;d=this.buffer.byteLength;b>d&&this.resize((d*=2)>b?d:b);b-=f+1;l.b(m(a),function(a){this.view[b++]=a}.bind(this));this.view[b++]=
  481. 0;return c?(this.offset=b,this):f};e.readCString=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=a,d,f=-1;l.c(function(){if(0===f)return null;if(a>=this.limit)throw RangeError("Illegal range: Truncated data, "+a+" < "+this.limit);f=this.view[a++];return 0===
  482. f?null:f}.bind(this),d=s(),!0);return b?(this.offset=a,d()):{string:d(),length:a-c}};e.writeIString=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d=b,f;f=l.a(m(a),this.noAssert)[1];b+=
  483. 4+f;var e=this.buffer.byteLength;b>e&&this.resize((e*=2)>b?e:b);b-=4+f;this.littleEndian?(this.view[b+3]=f>>>24&255,this.view[b+2]=f>>>16&255,this.view[b+1]=f>>>8&255,this.view[b]=f&255):(this.view[b]=f>>>24&255,this.view[b+1]=f>>>16&255,this.view[b+2]=f>>>8&255,this.view[b+3]=f&255);b+=4;l.b(m(a),function(a){this.view[b++]=a}.bind(this));if(b!==d+4+f)throw RangeError("Illegal range: Truncated data, "+b+" == "+(b+4+f));return c?(this.offset=b,this):b-d};e.readIString=function(a){var b="undefined"===
  484. typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+4>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+4) <= "+this.buffer.byteLength);}var c=a,d=this.readUint32(a),d=this.readUTF8String(d,g.METRICS_BYTES,a+=4);a+=d.length;return b?(this.offset=a,d.string):{string:d.string,length:a-c}};g.METRICS_CHARS="c";g.METRICS_BYTES="b";e.writeUTF8String=function(a,b){var c="undefined"===
  485. typeof b;c&&(b=this.offset);if(!this.noAssert){if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d,f=b;d=l.a(m(a))[1];b+=d;var e=this.buffer.byteLength;b>e&&this.resize((e*=2)>b?e:b);b-=d;l.b(m(a),function(a){this.view[b++]=a}.bind(this));return c?(this.offset=b,this):b-f};e.writeString=e.writeUTF8String;g.calculateUTF8Chars=function(a){return l.a(m(a))[0]};
  486. g.calculateUTF8Bytes=function(a){return l.a(m(a))[1]};g.calculateString=g.calculateUTF8Bytes;e.readUTF8String=function(a,b,c){"number"===typeof b&&(c=b,b=void 0);var d="undefined"===typeof c;d&&(c=this.offset);"undefined"===typeof b&&(b=g.METRICS_CHARS);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal length: "+a+" (not an integer)");a|=0;if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
  487. c+" (+0) <= "+this.buffer.byteLength);}var f=0,e=c,h;if(b===g.METRICS_CHARS){h=s();l.f(function(){return f<a&&c<this.limit?this.view[c++]:null}.bind(this),function(a){++f;l.e(a,h)});if(f!==a)throw RangeError("Illegal range: Truncated data, "+f+" == "+a);return d?(this.offset=c,h()):{string:h(),length:c-e}}if(b===g.METRICS_BYTES){if(!this.noAssert){if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+a>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+
  488. c+" (+"+a+") <= "+this.buffer.byteLength);}var p=c+a;l.c(function(){return c<p?this.view[c++]:null}.bind(this),h=s(),this.noAssert);if(c!==p)throw RangeError("Illegal range: Truncated data, "+c+" == "+p);return d?(this.offset=c,h()):{string:h(),length:c-e}}throw TypeError("Unsupported metrics: "+b);};e.readString=e.readUTF8String;e.writeVString=function(a,b){var c="undefined"===typeof b;c&&(b=this.offset);if(!this.noAssert){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");if("number"!==
  489. typeof b||0!==b%1)throw TypeError("Illegal offset: "+b+" (not an integer)");b>>>=0;if(0>b||b+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+b+" (+0) <= "+this.buffer.byteLength);}var d=b,f,e;f=l.a(m(a),this.noAssert)[1];e=g.calculateVarint32(f);b+=e+f;var h=this.buffer.byteLength;b>h&&this.resize((h*=2)>b?h:b);b-=e+f;b+=this.writeVarint32(f,b);l.b(m(a),function(a){this.view[b++]=a}.bind(this));if(b!==d+f+e)throw RangeError("Illegal range: Truncated data, "+b+" == "+(b+f+e));return c?
  490. (this.offset=b,this):b-d};e.readVString=function(a){var b="undefined"===typeof a;b&&(a=this.offset);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+1>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+1) <= "+this.buffer.byteLength);}var c=a,d=this.readVarint32(a),d=this.readUTF8String(d.value,g.METRICS_BYTES,a+=d.length);a+=d.length;return b?(this.offset=a,d.string):{string:d.string,length:a-c}};e.append=
  491. function(a,b,c){if("number"===typeof b||"string"!==typeof b)c=b,b=void 0;var d="undefined"===typeof c;d&&(c=this.offset);if(!this.noAssert){if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+c+" (+0) <= "+this.buffer.byteLength);}a instanceof g||(a=g.wrap(a,b));b=a.limit-a.offset;if(0>=b)return this;c+=b;var f=this.buffer.byteLength;c>f&&this.resize((f*=2)>c?f:c);this.view.set(a.view.subarray(a.offset,
  492. a.limit),c-b);a.offset+=b;d&&(this.offset+=b);return this};e.appendTo=function(a,b){a.append(this,b);return this};e.assert=function(a){this.noAssert=!a;return this};e.capacity=function(){return this.buffer.byteLength};e.clear=function(){this.offset=0;this.limit=this.buffer.byteLength;this.markedOffset=-1;return this};e.clone=function(a){var b=new g(0,this.littleEndian,this.noAssert);a?(b.buffer=new ArrayBuffer(this.buffer.byteLength),b.view=new Uint8Array(b.buffer)):(b.buffer=this.buffer,b.view=this.view);
  493. b.offset=this.offset;b.markedOffset=this.markedOffset;b.limit=this.limit;return b};e.compact=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}if(0===
  494. a&&b===this.buffer.byteLength)return this;var c=b-a;if(0===c)return this.buffer=v,this.view=null,0<=this.markedOffset&&(this.markedOffset-=a),this.limit=this.offset=0,this;var d=new ArrayBuffer(c),f=new Uint8Array(d);f.set(this.view.subarray(a,b));this.buffer=d;this.view=f;0<=this.markedOffset&&(this.markedOffset-=a);this.offset=0;this.limit=c;return this};e.copy=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||
  495. 0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}if(a===b)return new g(0,this.littleEndian,this.noAssert);var c=b-a,d=new g(c,this.littleEndian,this.noAssert);d.offset=0;d.limit=c;0<=d.markedOffset&&(d.markedOffset-=a);this.copyTo(d,0,a,b);return d};e.copyTo=function(a,b,c,d){var f,
  496. e;if(!this.noAssert&&!g.isByteBuffer(a))throw TypeError("Illegal target: Not a ByteBuffer");b=(e="undefined"===typeof b)?a.offset:b|0;c=(f="undefined"===typeof c)?this.offset:c|0;d="undefined"===typeof d?this.limit:d|0;if(0>b||b>a.buffer.byteLength)throw RangeError("Illegal target range: 0 <= "+b+" <= "+a.buffer.byteLength);if(0>c||d>this.buffer.byteLength)throw RangeError("Illegal source range: 0 <= "+c+" <= "+this.buffer.byteLength);var h=d-c;if(0===h)return a;a.ensureCapacity(b+h);a.view.set(this.view.subarray(c,
  497. d),b);f&&(this.offset+=h);e&&(a.offset+=h);return this};e.ensureCapacity=function(a){var b=this.buffer.byteLength;return b<a?this.resize((b*=2)>a?b:a):this};e.fill=function(a,b,c){var d="undefined"===typeof b;d&&(b=this.offset);"string"===typeof a&&0<a.length&&(a=a.charCodeAt(0));"undefined"===typeof b&&(b=this.offset);"undefined"===typeof c&&(c=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal value: "+a+" (not an integer)");a|=0;if("number"!==typeof b||0!==
  498. b%1)throw TypeError("Illegal begin: Not an integer");b>>>=0;if("number"!==typeof c||0!==c%1)throw TypeError("Illegal end: Not an integer");c>>>=0;if(0>b||b>c||c>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+b+" <= "+c+" <= "+this.buffer.byteLength);}if(b>=c)return this;for(;b<c;)this.view[b++]=a;d&&(this.offset=b);return this};e.flip=function(){this.limit=this.offset;this.offset=0;return this};e.mark=function(a){a="undefined"===typeof a?this.offset:a;if(!this.noAssert){if("number"!==
  499. typeof a||0!==a%1)throw TypeError("Illegal offset: "+a+" (not an integer)");a>>>=0;if(0>a||a+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+a+" (+0) <= "+this.buffer.byteLength);}this.markedOffset=a;return this};e.order=function(a){if(!this.noAssert&&"boolean"!==typeof a)throw TypeError("Illegal littleEndian: Not a boolean");this.littleEndian=!!a;return this};e.LE=function(a){this.littleEndian="undefined"!==typeof a?!!a:!0;return this};e.BE=function(a){this.littleEndian="undefined"!==
  500. typeof a?!a:!1;return this};e.prepend=function(a,b,c){if("number"===typeof b||"string"!==typeof b)c=b,b=void 0;var d="undefined"===typeof c;d&&(c=this.offset);if(!this.noAssert){if("number"!==typeof c||0!==c%1)throw TypeError("Illegal offset: "+c+" (not an integer)");c>>>=0;if(0>c||c+0>this.buffer.byteLength)throw RangeError("Illegal offset: 0 <= "+c+" (+0) <= "+this.buffer.byteLength);}a instanceof g||(a=g.wrap(a,b));b=a.limit-a.offset;if(0>=b)return this;var f=b-c;if(0<f){var e=new ArrayBuffer(this.buffer.byteLength+
  501. f),h=new Uint8Array(e);h.set(this.view.subarray(c,this.buffer.byteLength),b);this.buffer=e;this.view=h;this.offset+=f;0<=this.markedOffset&&(this.markedOffset+=f);this.limit+=f;c+=f}else new Uint8Array(this.buffer);this.view.set(a.view.subarray(a.offset,a.limit),c-b);a.offset=a.limit;d&&(this.offset-=b);return this};e.prependTo=function(a,b){a.prepend(this,b);return this};e.printDebug=function(a){"function"!==typeof a&&(a=console.log.bind(console));a(this.toString()+"\n-------------------------------------------------------------------\n"+
  502. this.toDebug(!0))};e.remaining=function(){return this.limit-this.offset};e.reset=function(){0<=this.markedOffset?(this.offset=this.markedOffset,this.markedOffset=-1):this.offset=0;return this};e.resize=function(a){if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal capacity: "+a+" (not an integer)");a|=0;if(0>a)throw RangeError("Illegal capacity: 0 <= "+a);}if(this.buffer.byteLength<a){a=new ArrayBuffer(a);var b=new Uint8Array(a);b.set(this.view);this.buffer=a;this.view=b}return this};
  503. e.reverse=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}if(a===b)return this;Array.prototype.reverse.call(this.view.subarray(a,b));return this};
  504. e.skip=function(a){if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal length: "+a+" (not an integer)");a|=0}var b=this.offset+a;if(!this.noAssert&&(0>b||b>this.buffer.byteLength))throw RangeError("Illegal length: 0 <= "+this.offset+" + "+a+" <= "+this.buffer.byteLength);this.offset=b;return this};e.slice=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");
  505. a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}var c=this.clone();c.offset=a;c.limit=b;return c};e.toBuffer=function(a){var b=this.offset,c=this.limit;if(!this.noAssert){if("number"!==typeof b||0!==b%1)throw TypeError("Illegal offset: Not an integer");b>>>=0;if("number"!==typeof c||0!==c%1)throw TypeError("Illegal limit: Not an integer");
  506. c>>>=0;if(0>b||b>c||c>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+b+" <= "+c+" <= "+this.buffer.byteLength);}if(!a&&0===b&&c===this.buffer.byteLength)return this.buffer;if(b===c)return v;a=new ArrayBuffer(c-b);(new Uint8Array(a)).set((new Uint8Array(this.buffer)).subarray(b,c),0);return a};e.toArrayBuffer=e.toBuffer;e.toString=function(a,b,c){if("undefined"===typeof a)return"ByteBufferAB(offset="+this.offset+",markedOffset="+this.markedOffset+",limit="+this.limit+",capacity="+this.capacity()+
  507. ")";"number"===typeof a&&(c=b=a="utf8");switch(a){case "utf8":return this.toUTF8(b,c);case "base64":return this.toBase64(b,c);case "hex":return this.toHex(b,c);case "binary":return this.toBinary(b,c);case "debug":return this.toDebug();case "columns":return this.m();default:throw Error("Unsupported encoding: "+a);}};var A=function(){for(var a={},b=[65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,
  508. 116,117,118,119,120,121,122,48,49,50,51,52,53,54,55,56,57,43,47],c=[],d=0,f=b.length;d<f;++d)c[b[d]]=d;a.h=function(a,c){for(var d,f;null!==(d=a());)c(b[d>>2&63]),f=(d&3)<<4,null!==(d=a())?(f|=d>>4&15,c(b[(f|d>>4&15)&63]),f=(d&15)<<2,null!==(d=a())?(c(b[(f|d>>6&3)&63]),c(b[d&63])):(c(b[f&63]),c(61))):(c(b[f&63]),c(61),c(61))};a.g=function(a,b){function d(a){throw Error("Illegal character code: "+a);}for(var f,e,g;null!==(f=a());)if(e=c[f],"undefined"===typeof e&&d(f),null!==(f=a())&&(g=c[f],"undefined"===
  509. typeof g&&d(f),b(e<<2>>>0|(g&48)>>4),null!==(f=a()))){e=c[f];if("undefined"===typeof e)if(61===f)break;else d(f);b((g&15)<<4>>>0|(e&60)>>2);if(null!==(f=a())){g=c[f];if("undefined"===typeof g)if(61===f)break;else d(f);b((e&3)<<6>>>0|g)}}};a.test=function(a){return/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(a)};return a}();e.toBase64=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);a|=0;b|=0;if(0>a||b>this.capacity||a>b)throw RangeError("begin, end");
  510. var c;A.h(function(){return a<b?this.view[a++]:null}.bind(this),c=s());return c()};g.fromBase64=function(a,b){if("string"!==typeof a)throw TypeError("str");var c=new g(a.length/4*3,b),d=0;A.g(m(a),function(a){c.view[d++]=a});c.limit=d;return c};g.btoa=function(a){return g.fromBinary(a).toBase64()};g.atob=function(a){return g.fromBase64(a).toBinary()};e.toBinary=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=this.limit);a|=0;b|=0;if(0>a||b>this.capacity()||a>b)throw RangeError("begin, end");
  511. if(a===b)return"";for(var c=[],d=[];a<b;)c.push(this.view[a++]),1024<=c.length&&(d.push(String.fromCharCode.apply(String,c)),c=[]);return d.join("")+String.fromCharCode.apply(String,c)};g.fromBinary=function(a,b){if("string"!==typeof a)throw TypeError("str");for(var c=0,d=a.length,f,e=new g(d,b);c<d;){f=a.charCodeAt(c);if(255<f)throw RangeError("illegal char code: "+f);e.view[c++]=f}e.limit=d;return e};e.toDebug=function(a){for(var b=-1,c=this.buffer.byteLength,d,f="",e="",g="";b<c;){-1!==b&&(d=this.view[b],
  512. f=16>d?f+("0"+d.toString(16).toUpperCase()):f+d.toString(16).toUpperCase(),a&&(e+=32<d&&127>d?String.fromCharCode(d):"."));++b;if(a&&0<b&&0===b%16&&b!==c){for(;51>f.length;)f+=" ";g+=f+e+"\n";f=e=""}f=b===this.offset&&b===this.limit?f+(b===this.markedOffset?"!":"|"):b===this.offset?f+(b===this.markedOffset?"[":"<"):b===this.limit?f+(b===this.markedOffset?"]":">"):f+(b===this.markedOffset?"'":a||0!==b&&b!==c?" ":"")}if(a&&" "!==f){for(;51>f.length;)f+=" ";g+=f+e+"\n"}return a?g:f};g.fromDebug=function(a,
  513. b,c){var d=a.length;b=new g((d+1)/3|0,b,c);for(var f=0,e=0,h,k=!1,l=!1,q=!1,m=!1,r=!1;f<d;){switch(h=a.charAt(f++)){case "!":if(!c){if(l||q||m){r=!0;break}l=q=m=!0}b.offset=b.markedOffset=b.limit=e;k=!1;break;case "|":if(!c){if(l||m){r=!0;break}l=m=!0}b.offset=b.limit=e;k=!1;break;case "[":if(!c){if(l||q){r=!0;break}l=q=!0}b.offset=b.markedOffset=e;k=!1;break;case "<":if(!c){if(l){r=!0;break}l=!0}b.offset=e;k=!1;break;case "]":if(!c){if(m||q){r=!0;break}m=q=!0}b.limit=b.markedOffset=e;k=!1;break;
  514. case ">":if(!c){if(m){r=!0;break}m=!0}b.limit=e;k=!1;break;case "'":if(!c){if(q){r=!0;break}q=!0}b.markedOffset=e;k=!1;break;case " ":k=!1;break;default:if(!c&&k){r=!0;break}h=parseInt(h+a.charAt(f++),16);if(!c&&(isNaN(h)||0>h||255<h))throw TypeError("Illegal str: Not a debug encoded string");b.view[e++]=h;k=!0}if(r)throw TypeError("Illegal str: Invalid symbol at "+f);}if(!c){if(!l||!m)throw TypeError("Illegal str: Missing offset or limit");if(e<b.buffer.byteLength)throw TypeError("Illegal str: Not a debug encoded string (is it hex?) "+
  515. e+" < "+d);}return b};e.toHex=function(a,b){a="undefined"===typeof a?this.offset:a;b="undefined"===typeof b?this.limit:b;if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}for(var c=Array(b-a),d;a<b;)d=this.view[a++],16>d?c.push("0",d.toString(16)):
  516. c.push(d.toString(16));return c.join("")};g.fromHex=function(a,b,c){if(!c){if("string"!==typeof a)throw TypeError("Illegal str: Not a string");if(0!==a.length%2)throw TypeError("Illegal str: Length not a multiple of 2");}var d=a.length;b=new g(d/2|0,b);for(var f,e=0,h=0;e<d;e+=2){f=parseInt(a.substring(e,e+2),16);if(!c&&(!isFinite(f)||0>f||255<f))throw TypeError("Illegal str: Contains non-hex characters");b.view[h++]=f}b.limit=h;return b};var l=function(){var a={j:1114111,i:function(a,c){var d=null;
  517. "number"===typeof a&&(d=a,a=function(){return null});for(;null!==d||null!==(d=a());)128>d?c(d&127):(2048>d?c(d>>6&31|192):(65536>d?c(d>>12&15|224):(c(d>>18&7|240),c(d>>12&63|128)),c(d>>6&63|128)),c(d&63|128)),d=null},f:function(a,c){function d(a){a=a.slice(0,a.indexOf(null));var b=Error(a.toString());b.name="TruncatedError";b.bytes=a;throw b;}for(var f,e,g,k;null!==(f=a());)if(0===(f&128))c(f);else if(192===(f&224))null===(e=a())&&d([f,e]),c((f&31)<<6|e&63);else if(224===(f&240))null!==(e=a())&&null!==
  518. (g=a())||d([f,e,g]),c((f&15)<<12|(e&63)<<6|g&63);else if(240===(f&248))null!==(e=a())&&null!==(g=a())&&null!==(k=a())||d([f,e,g,k]),c((f&7)<<18|(e&63)<<12|(g&63)<<6|k&63);else throw RangeError("Illegal starting byte: "+f);},d:function(a,c){for(var d,f=null;null!==(d=null!==f?f:a());)55296<=d&&57343>=d&&null!==(f=a())&&56320<=f&&57343>=f?(c(1024*(d-55296)+f-56320+65536),f=null):c(d);null!==f&&c(f)},e:function(a,c){var d=null;"number"===typeof a&&(d=a,a=function(){return null});for(;null!==d||null!==
  519. (d=a());)65535>=d?c(d):(d-=65536,c((d>>10)+55296),c(d%1024+56320)),d=null},b:function(b,c){a.d(b,function(b){a.i(b,c)})},c:function(b,c){a.f(b,function(b){a.e(b,c)})},k:function(a){return 128>a?1:2048>a?2:65536>a?3:4},l:function(a){for(var c,d=0;null!==(c=a());)d+=128>c?1:2048>c?2:65536>c?3:4;return d},a:function(b){var c=0,d=0;a.d(b,function(a){++c;d+=128>a?1:2048>a?2:65536>a?3:4});return[c,d]}};return a}();e.toUTF8=function(a,b){"undefined"===typeof a&&(a=this.offset);"undefined"===typeof b&&(b=
  520. this.limit);if(!this.noAssert){if("number"!==typeof a||0!==a%1)throw TypeError("Illegal begin: Not an integer");a>>>=0;if("number"!==typeof b||0!==b%1)throw TypeError("Illegal end: Not an integer");b>>>=0;if(0>a||a>b||b>this.buffer.byteLength)throw RangeError("Illegal range: 0 <= "+a+" <= "+b+" <= "+this.buffer.byteLength);}var c;try{l.c(function(){return a<b?this.view[a++]:null}.bind(this),c=s())}catch(d){if(a!==b)throw RangeError("Illegal range: Truncated data, "+a+" != "+b);}return c()};g.fromUTF8=
  521. function(a,b,c){if(!c&&"string"!==typeof a)throw TypeError("Illegal str: Not a string");var d=new g(l.a(m(a),!0)[1],b,c),e=0;l.b(m(a),function(a){d.view[e++]=a});d.limit=e;return d};return g}if("function"===typeof define&&define.amd)define(["long"],u);else if("function"===typeof require&&"object"===typeof module&&module&&module.exports){var B=module,C,D;try{D=require("long")}catch(E){}C=u(D);B.exports=C}else(this.dcodeIO=this.dcodeIO||{}).ByteBuffer=u(this.dcodeIO.Long);
  522. ;
  523. /*
  524. protobuf.js (c) 2013 Daniel Wirtz <dcode@dcode.io>
  525. Released under the Apache License, Version 2.0
  526. see: https://github.com/dcodeIO/protobuf.js for details
  527. */
  528. (function(h,u){"function"===typeof define&&define.amd?define(["bytebuffer"],u):"function"===typeof require&&"object"===typeof module&&module&&module.exports?module.exports=u(require("bytebuffer"),!0):(h.dcodeIO=h.dcodeIO||{}).ProtoBuf=u(h.dcodeIO.ByteBuffer)})(this,function(h,u){var d={};d.ByteBuffer=h;d.Long=h.Long||null;d.VERSION="5.0.1";d.WIRE_TYPES={};d.WIRE_TYPES.VARINT=0;d.WIRE_TYPES.BITS64=1;d.WIRE_TYPES.LDELIM=2;d.WIRE_TYPES.STARTGROUP=3;d.WIRE_TYPES.ENDGROUP=4;d.WIRE_TYPES.BITS32=5;d.PACKABLE_WIRE_TYPES=
  529. [d.WIRE_TYPES.VARINT,d.WIRE_TYPES.BITS64,d.WIRE_TYPES.BITS32];d.TYPES={int32:{name:"int32",wireType:d.WIRE_TYPES.VARINT,defaultValue:0},uint32:{name:"uint32",wireType:d.WIRE_TYPES.VARINT,defaultValue:0},sint32:{name:"sint32",wireType:d.WIRE_TYPES.VARINT,defaultValue:0},int64:{name:"int64",wireType:d.WIRE_TYPES.VARINT,defaultValue:d.Long?d.Long.ZERO:void 0},uint64:{name:"uint64",wireType:d.WIRE_TYPES.VARINT,defaultValue:d.Long?d.Long.UZERO:void 0},sint64:{name:"sint64",wireType:d.WIRE_TYPES.VARINT,
  530. defaultValue:d.Long?d.Long.ZERO:void 0},bool:{name:"bool",wireType:d.WIRE_TYPES.VARINT,defaultValue:!1},"double":{name:"double",wireType:d.WIRE_TYPES.BITS64,defaultValue:0},string:{name:"string",wireType:d.WIRE_TYPES.LDELIM,defaultValue:""},bytes:{name:"bytes",wireType:d.WIRE_TYPES.LDELIM,defaultValue:null},fixed32:{name:"fixed32",wireType:d.WIRE_TYPES.BITS32,defaultValue:0},sfixed32:{name:"sfixed32",wireType:d.WIRE_TYPES.BITS32,defaultValue:0},fixed64:{name:"fixed64",wireType:d.WIRE_TYPES.BITS64,
  531. defaultValue:d.Long?d.Long.UZERO:void 0},sfixed64:{name:"sfixed64",wireType:d.WIRE_TYPES.BITS64,defaultValue:d.Long?d.Long.ZERO:void 0},"float":{name:"float",wireType:d.WIRE_TYPES.BITS32,defaultValue:0},"enum":{name:"enum",wireType:d.WIRE_TYPES.VARINT,defaultValue:0},message:{name:"message",wireType:d.WIRE_TYPES.LDELIM,defaultValue:null},group:{name:"group",wireType:d.WIRE_TYPES.STARTGROUP,defaultValue:null}};d.MAP_KEY_TYPES=[d.TYPES.int32,d.TYPES.sint32,d.TYPES.sfixed32,d.TYPES.uint32,d.TYPES.fixed32,
  532. d.TYPES.int64,d.TYPES.sint64,d.TYPES.sfixed64,d.TYPES.uint64,d.TYPES.fixed64,d.TYPES.bool,d.TYPES.string,d.TYPES.bytes];d.ID_MIN=1;d.ID_MAX=536870911;d.convertFieldsToCamelCase=!1;d.populateAccessors=!0;d.populateDefaults=!0;d.Util=function(){var b={};b.IS_NODE=!("object"!==typeof process||"[object process]"!==process+""||process.browser);b.XHR=function(){for(var b=[function(){return new XMLHttpRequest},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml3.XMLHTTP")},
  533. function(){return new ActiveXObject("Microsoft.XMLHTTP")}],d=null,h=0;h<b.length;h++){try{d=b[h]()}catch(n){continue}break}if(!d)throw Error("XMLHttpRequest is not supported");return d};b.fetch=function(d,p){p&&"function"!=typeof p&&(p=null);if(b.IS_NODE){var h=require("fs");if(p)h.readFile(d,function(b,d){b?p(null):p(""+d)});else try{return h.readFileSync(d)}catch(n){return null}}else{var k=b.XHR();k.open("GET",d,p?!0:!1);k.setRequestHeader("Accept","text/plain");"function"===typeof k.overrideMimeType&&
  534. k.overrideMimeType("text/plain");if(p)k.onreadystatechange=function(){4==k.readyState&&(200==k.status||0==k.status&&"string"===typeof k.responseText?p(k.responseText):p(null))},4!=k.readyState&&k.send(null);else return k.send(null),200==k.status||0==k.status&&"string"===typeof k.responseText?k.responseText:null}};b.toCamelCase=function(b){return b.replace(/_([a-zA-Z])/g,function(b,d){return d.toUpperCase()})};return b}();d.Lang={DELIM:/[\s\{\}=;:\[\],'"\(\)<>]/g,RULE:/^(?:required|optional|repeated|map)$/,
  535. TYPE:/^(?:double|float|int32|uint32|sint32|int64|uint64|sint64|fixed32|sfixed32|fixed64|sfixed64|bool|string|bytes)$/,NAME:/^[a-zA-Z_][a-zA-Z_0-9]*$/,TYPEDEF:/^[a-zA-Z][a-zA-Z_0-9]*$/,TYPEREF:/^(?:\.?[a-zA-Z_][a-zA-Z_0-9]*)+$/,FQTYPEREF:/^(?:\.[a-zA-Z][a-zA-Z_0-9]*)+$/,NUMBER:/^-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+|([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?)|inf|nan)$/,NUMBER_DEC:/^(?:[1-9][0-9]*|0)$/,NUMBER_HEX:/^0[xX][0-9a-fA-F]+$/,NUMBER_OCT:/^0[0-7]+$/,NUMBER_FLT:/^([0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)?|inf|nan)$/,
  536. BOOL:/^(?:true|false)$/i,ID:/^(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,NEGID:/^\-?(?:[1-9][0-9]*|0|0[xX][0-9a-fA-F]+|0[0-7]+)$/,WHITESPACE:/\s/,STRING:/(?:"([^"\\]*(?:\\.[^"\\]*)*)")|(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g,STRING_DQ:/(?:"([^"\\]*(?:\\.[^"\\]*)*)")/g,STRING_SQ:/(?:'([^'\\]*(?:\\.[^'\\]*)*)')/g};d.DotProto=function(b,d){function h(b,c){var a=-1,l=1;"-"==b.charAt(0)&&(l=-1,b=b.substring(1));if(d.NUMBER_DEC.test(b))a=parseInt(b);else if(d.NUMBER_HEX.test(b))a=parseInt(b.substring(2),16);
  537. else if(d.NUMBER_OCT.test(b))a=parseInt(b.substring(1),8);else throw Error("illegal id value: "+(0>l?"-":"")+b);a=l*a|0;if(!c&&0>a)throw Error("illegal id value: "+(0>l?"-":"")+b);return a}function q(b){var c=1;"-"==b.charAt(0)&&(c=-1,b=b.substring(1));if(d.NUMBER_DEC.test(b))return c*parseInt(b,10);if(d.NUMBER_HEX.test(b))return c*parseInt(b.substring(2),16);if(d.NUMBER_OCT.test(b))return c*parseInt(b.substring(1),8);if("inf"===b)return Infinity*c;if("nan"===b)return NaN;if(d.NUMBER_FLT.test(b))return c*
  538. parseFloat(b);throw Error("illegal number value: "+(0>c?"-":"")+b);}function n(b,c,d){"undefined"===typeof b[c]?b[c]=d:(Array.isArray(b[c])||(b[c]=[b[c]]),b[c].push(d))}var k={},a=function(b){this.source=b+"";this.index=0;this.line=1;this.stack=[];this._stringOpen=null},e=a.prototype;e._readString=function(){var b='"'===this._stringOpen?d.STRING_DQ:d.STRING_SQ;b.lastIndex=this.index-1;var c=b.exec(this.source);if(!c)throw Error("unterminated string");this.index=b.lastIndex;this.stack.push(this._stringOpen);
  539. this._stringOpen=null;return c[1]};e.next=function(){if(0<this.stack.length)return this.stack.shift();if(this.index>=this.source.length)return null;if(null!==this._stringOpen)return this._readString();var b,c;do{for(b=!1;d.WHITESPACE.test(c=this.source.charAt(this.index));)if("\n"===c&&++this.line,++this.index===this.source.length)return null;if("/"===this.source.charAt(this.index))if(++this.index,"/"===this.source.charAt(this.index)){for(;"\n"!==this.source.charAt(++this.index);)if(this.index==this.source.length)return null;
  540. ++this.index;++this.line;b=!0}else if("*"===(c=this.source.charAt(this.index))){do{"\n"===c&&++this.line;if(++this.index===this.source.length)return null;b=c;c=this.source.charAt(this.index)}while("*"!==b||"/"!==c);++this.index;b=!0}else return"/"}while(b);if(this.index===this.source.length)return null;c=this.index;d.DELIM.lastIndex=0;if(!d.DELIM.test(this.source.charAt(c++)))for(;c<this.source.length&&!d.DELIM.test(this.source.charAt(c));)++c;c=this.source.substring(this.index,this.index=c);if('"'===
  541. c||"'"===c)this._stringOpen=c;return c};e.peek=function(){if(0===this.stack.length){var b=this.next();if(null===b)return null;this.stack.push(b)}return this.stack[0]};e.skip=function(b){var c=this.next();if(c!==b)throw Error("illegal '"+c+"', '"+b+"' expected");};e.omit=function(b){return this.peek()===b?(this.next(),!0):!1};e.toString=function(){return"Tokenizer ("+this.index+"/"+this.source.length+" at line "+this.line+")"};k.Tokenizer=a;var f=function(b){this.tn=new a(b);this.proto3=!1},e=f.prototype;
  542. e.parse=function(){var b={name:"[ROOT]","package":null,messages:[],enums:[],imports:[],options:{},services:[]},c,a=!0,l;try{for(;c=this.tn.next();)switch(c){case "package":if(!a||null!==b["package"])throw Error("unexpected 'package'");c=this.tn.next();if(!d.TYPEREF.test(c))throw Error("illegal package name: "+c);this.tn.skip(";");b["package"]=c;break;case "import":if(!a)throw Error("unexpected 'import'");c=this.tn.peek();("public"===c||(l="weak"===c))&&this.tn.next();c=this._readString();this.tn.skip(";");
  543. l||b.imports.push(c);break;case "syntax":if(!a)throw Error("unexpected 'syntax'");this.tn.skip("=");"proto3"===(b.syntax=this._readString())&&(this.proto3=!0);this.tn.skip(";");break;case "message":this._parseMessage(b,null);a=!1;break;case "enum":this._parseEnum(b);a=!1;break;case "option":this._parseOption(b);break;case "service":this._parseService(b);break;case "extend":this._parseExtend(b);break;default:throw Error("unexpected '"+c+"'");}}catch(e){throw e.message="Parse error at line "+this.tn.line+
  544. ": "+e.message,e;}delete b.name;return b};f.parse=function(b){return(new f(b)).parse()};e._readString=function(){var b="",c;do{c=this.tn.next();if("'"!==c&&'"'!==c)throw Error("illegal string delimiter: "+c);b+=this.tn.next();this.tn.skip(c);c=this.tn.peek()}while('"'===c||'"'===c);return b};e._readValue=function(b){var c=this.tn.peek();if('"'===c||"'"===c)return this._readString();this.tn.next();if(d.NUMBER.test(c))return q(c);if(d.BOOL.test(c))return"true"===c.toLowerCase();if(b&&d.TYPEREF.test(c))return c;
  545. throw Error("illegal value: "+c);};e._parseOption=function(b,c){var a=this.tn.next(),l=!1;"("===a&&(l=!0,a=this.tn.next());if(!d.TYPEREF.test(a))throw Error("illegal option name: "+a);var e=a;l&&(this.tn.skip(")"),e="("+e+")",a=this.tn.peek(),d.FQTYPEREF.test(a)&&(e+=a,this.tn.next()));this.tn.skip("=");this._parseOptionValue(b,e);c||this.tn.skip(";")};e._parseOptionValue=function(b,c){var a=this.tn.peek();if("{"!==a)n(b.options,c,this._readValue(!0));else for(this.tn.skip("{");"}"!==(a=this.tn.next());){if(!d.NAME.test(a))throw Error("illegal option name: "+
  546. c+"."+a);this.tn.omit(":")?n(b.options,c+"."+a,this._readValue(!0)):this._parseOptionValue(b,c+"."+a)}};e._parseService=function(b){var c=this.tn.next();if(!d.NAME.test(c))throw Error("illegal service name at line "+this.tn.line+": "+c);var a={name:c,rpc:{},options:{}};for(this.tn.skip("{");"}"!==(c=this.tn.next());)if("option"===c)this._parseOption(a);else if("rpc"===c)this._parseServiceRPC(a);else throw Error("illegal service token: "+c);this.tn.omit(";");b.services.push(a)};e._parseServiceRPC=
  547. function(b){var c=this.tn.next();if(!d.NAME.test(c))throw Error("illegal rpc service method name: "+c);var a=c,l={request:null,response:null,request_stream:!1,response_stream:!1,options:{}};this.tn.skip("(");c=this.tn.next();"stream"===c.toLowerCase()&&(l.request_stream=!0,c=this.tn.next());if(!d.TYPEREF.test(c))throw Error("illegal rpc service request type: "+c);l.request=c;this.tn.skip(")");c=this.tn.next();if("returns"!==c.toLowerCase())throw Error("illegal rpc service request type delimiter: "+
  548. c);this.tn.skip("(");c=this.tn.next();"stream"===c.toLowerCase()&&(l.response_stream=!0,c=this.tn.next());l.response=c;this.tn.skip(")");c=this.tn.peek();if("{"===c){for(this.tn.next();"}"!==(c=this.tn.next());)if("option"===c)this._parseOption(l);else throw Error("illegal rpc service token: "+c);this.tn.omit(";")}else this.tn.skip(";");"undefined"===typeof b.rpc&&(b.rpc={});b.rpc[a]=l};e._parseMessage=function(b,c){var a=!!c,l=this.tn.next(),e={name:"",fields:[],enums:[],messages:[],options:{},services:[],
  549. oneofs:{}};if(!d.NAME.test(l))throw Error("illegal "+(a?"group":"message")+" name: "+l);e.name=l;a&&(this.tn.skip("="),c.id=h(this.tn.next()),e.isGroup=!0);l=this.tn.peek();"["===l&&c&&this._parseFieldOptions(c);for(this.tn.skip("{");"}"!==(l=this.tn.next());)if(d.RULE.test(l))this._parseMessageField(e,l);else if("oneof"===l)this._parseMessageOneOf(e);else if("enum"===l)this._parseEnum(e);else if("message"===l)this._parseMessage(e);else if("option"===l)this._parseOption(e);else if("service"===l)this._parseService(e);
  550. else if("extensions"===l)e.extensions=this._parseExtensionRanges();else if("reserved"===l)this._parseIgnored();else if("extend"===l)this._parseExtend(e);else if(d.TYPEREF.test(l)){if(!this.proto3)throw Error("illegal field rule: "+l);this._parseMessageField(e,"optional",l)}else throw Error("illegal message token: "+l);this.tn.omit(";");b.messages.push(e);return e};e._parseIgnored=function(){for(;";"!==this.tn.peek();)this.tn.next();this.tn.skip(";")};e._parseMessageField=function(b,c,a){if(!d.RULE.test(c))throw Error("illegal message field rule: "+
  551. c);var e={rule:c,type:"",name:"",options:{},id:0};if("map"===c){if(a)throw Error("illegal type: "+a);this.tn.skip("<");c=this.tn.next();if(!d.TYPE.test(c)&&!d.TYPEREF.test(c))throw Error("illegal message field type: "+c);e.keytype=c;this.tn.skip(",");c=this.tn.next();if(!d.TYPE.test(c)&&!d.TYPEREF.test(c))throw Error("illegal message field: "+c);e.type=c;this.tn.skip(">");c=this.tn.next();if(!d.NAME.test(c))throw Error("illegal message field name: "+c);e.name=c;this.tn.skip("=");e.id=h(this.tn.next());
  552. c=this.tn.peek();"["===c&&this._parseFieldOptions(e);this.tn.skip(";")}else if(a="undefined"!==typeof a?a:this.tn.next(),"group"===a){c=this._parseMessage(b,e);if(!/^[A-Z]/.test(c.name))throw Error("illegal group name: "+c.name);e.type=c.name;e.name=c.name.toLowerCase();this.tn.omit(";")}else{if(!d.TYPE.test(a)&&!d.TYPEREF.test(a))throw Error("illegal message field type: "+a);e.type=a;c=this.tn.next();if(!d.NAME.test(c))throw Error("illegal message field name: "+c);e.name=c;this.tn.skip("=");e.id=
  553. h(this.tn.next());c=this.tn.peek();"["===c&&this._parseFieldOptions(e);this.tn.skip(";")}b.fields.push(e);return e};e._parseMessageOneOf=function(b){var c=this.tn.next();if(!d.NAME.test(c))throw Error("illegal oneof name: "+c);var a=c,e=[];for(this.tn.skip("{");"}"!==(c=this.tn.next());)c=this._parseMessageField(b,"optional",c),c.oneof=a,e.push(c.id);this.tn.omit(";");b.oneofs[a]=e};e._parseFieldOptions=function(b){this.tn.skip("[");for(var c=!0;"]"!==this.tn.peek();)c||this.tn.skip(","),this._parseOption(b,
  554. !0),c=!1;this.tn.next()};e._parseEnum=function(b){var c={name:"",values:[],options:{}},a=this.tn.next();if(!d.NAME.test(a))throw Error("illegal name: "+a);c.name=a;for(this.tn.skip("{");"}"!==(a=this.tn.next());)if("option"===a)this._parseOption(c);else{if(!d.NAME.test(a))throw Error("illegal name: "+a);this.tn.skip("=");var e={name:a,id:h(this.tn.next(),!0)},a=this.tn.peek();"["===a&&this._parseFieldOptions({options:{}});this.tn.skip(";");c.values.push(e)}this.tn.omit(";");b.enums.push(c)};e._parseExtensionRanges=
  555. function(){var a=[],c,d;do{for(d=[];;){c=this.tn.next();switch(c){case "min":c=b.ID_MIN;break;case "max":c=b.ID_MAX;break;default:c=q(c)}d.push(c);if(2===d.length)break;if("to"!==this.tn.peek()){d.push(c);break}this.tn.next()}a.push(d)}while(this.tn.omit(","));this.tn.skip(";");return a};e._parseExtend=function(b){var a=this.tn.next();if(!d.TYPEREF.test(a))throw Error("illegal extend reference: "+a);var e={ref:a,fields:[]};for(this.tn.skip("{");"}"!==(a=this.tn.next());)if(d.RULE.test(a))this._parseMessageField(e,
  556. a);else if(d.TYPEREF.test(a)){if(!this.proto3)throw Error("illegal field rule: "+a);this._parseMessageField(e,"optional",a)}else throw Error("illegal extend token: "+a);this.tn.omit(";");b.messages.push(e);return e};e.toString=function(){return"Parser at line "+this.tn.line};k.Parser=f;return k}(d,d.Lang);d.Reflect=function(b){function d(g,m){if(g&&"number"===typeof g.low&&"number"===typeof g.high&&"boolean"===typeof g.unsigned&&g.low===g.low&&g.high===g.high)return new b.Long(g.low,g.high,"undefined"===
  557. typeof m?g.unsigned:m);if("string"===typeof g)return b.Long.fromString(g,m||!1,10);if("number"===typeof g)return b.Long.fromNumber(g,m||!1);throw Error("not convertible to Long");}function p(g,m){var a=m.readVarint32(),c=a&7,a=a>>>3;switch(c){case b.WIRE_TYPES.VARINT:do a=m.readUint8();while(128===(a&128));break;case b.WIRE_TYPES.BITS64:m.offset+=8;break;case b.WIRE_TYPES.LDELIM:a=m.readVarint32();m.offset+=a;break;case b.WIRE_TYPES.STARTGROUP:p(a,m);break;case b.WIRE_TYPES.ENDGROUP:if(a===g)return!1;
  558. throw Error("Illegal GROUPEND after unknown group: "+a+" ("+g+" expected)");case b.WIRE_TYPES.BITS32:m.offset+=4;break;default:throw Error("Illegal wire type in unknown group "+g+": "+c);}return!0}var q={},n=function(g,b,a){this.builder=g;this.parent=b;this.name=a},k=n.prototype;k.fqn=function(){var g=this.name,b=this;do{b=b.parent;if(null==b)break;g=b.name+"."+g}while(1);return g};k.toString=function(g){return(g?this.className+" ":"")+this.fqn()};k.build=function(){throw Error(this.toString(!0)+
  559. " cannot be built directly");};q.T=n;var a=function(g,b,a,c,d){n.call(this,g,b,a);this.className="Namespace";this.children=[];this.options=c||{};this.syntax=d||"proto2"},k=a.prototype=Object.create(n.prototype);k.getChildren=function(b){b=b||null;if(null==b)return this.children.slice();for(var a=[],c=0,d=this.children.length;c<d;++c)this.children[c]instanceof b&&a.push(this.children[c]);return a};k.addChild=function(b){var a;if(a=this.getChild(b.name))if(a instanceof s.Field&&a.name!==a.originalName&&
  560. null===this.getChild(a.originalName))a.name=a.originalName;else if(b instanceof s.Field&&b.name!==b.originalName&&null===this.getChild(b.originalName))b.name=b.originalName;else throw Error("Duplicate name in namespace "+this.toString(!0)+": "+b.name);this.children.push(b)};k.getChild=function(b){for(var a="number"===typeof b?"id":"name",c=0,d=this.children.length;c<d;++c)if(this.children[c][a]===b)return this.children[c];return null};k.resolve=function(b,a){var c="string"===typeof b?b.split("."):
  561. b,d=this,e=0;if(""===c[e]){for(;null!==d.parent;)d=d.parent;e++}do{do{if(!(d instanceof q.Namespace)){d=null;break}d=d.getChild(c[e]);if(!(d&&d instanceof q.T)||a&&!(d instanceof q.Namespace)){d=null;break}e++}while(e<c.length);if(null!=d)break;if(null!==this.parent)return this.parent.resolve(b,a)}while(null!=d);return d};k.qn=function(b){var a=[],c=b;do a.unshift(c.name),c=c.parent;while(null!==c);for(c=1;c<=a.length;c++){var d=a.slice(a.length-c);if(b===this.resolve(d,b instanceof q.Namespace))return d.join(".")}return b.fqn()};
  562. k.build=function(){for(var b={},c=this.children,d=0,e=c.length,l;d<e;++d)l=c[d],l instanceof a&&(b[l.name]=l.build());Object.defineProperty&&Object.defineProperty(b,"$options",{value:this.buildOpt()});return b};k.buildOpt=function(){for(var b={},a=Object.keys(this.options),c=0,d=a.length;c<d;++c)b[a[c]]=this.options[a[c]];return b};k.getOption=function(b){return"undefined"===typeof b?this.options:"undefined"!==typeof this.options[b]?this.options[b]:null};q.Namespace=a;var e=function(g,a,c,d){this.type=
  563. g;this.resolvedType=a;this.isMapKey=c;this.syntax=d;if(c&&0>b.MAP_KEY_TYPES.indexOf(g))throw Error("Invalid map key type: "+g.name);},f=e.prototype;e.defaultFieldValue=function(g){"string"===typeof g&&(g=b.TYPES[g]);if("undefined"===typeof g.defaultValue)throw Error("default value for type "+g.name+" is not supported");return g==b.TYPES.bytes?new h(0):g.defaultValue};f.verifyValue=function(g){function a(b,g){throw Error("Illegal value for "+c.toString(!0)+" of type "+c.type.name+": "+b+" ("+g+")");
  564. }var c=this;switch(this.type){case b.TYPES.int32:case b.TYPES.sint32:case b.TYPES.sfixed32:return("number"!==typeof g||g===g&&0!==g%1)&&a(typeof g,"not an integer"),4294967295<g?g|0:g;case b.TYPES.uint32:case b.TYPES.fixed32:return("number"!==typeof g||g===g&&0!==g%1)&&a(typeof g,"not an integer"),0>g?g>>>0:g;case b.TYPES.int64:case b.TYPES.sint64:case b.TYPES.sfixed64:if(b.Long)try{return d(g,!1)}catch(e){a(typeof g,e.message)}else a(typeof g,"requires Long.js");case b.TYPES.uint64:case b.TYPES.fixed64:if(b.Long)try{return d(g,
  565. !0)}catch(l){a(typeof g,l.message)}else a(typeof g,"requires Long.js");case b.TYPES.bool:return"boolean"!==typeof g&&a(typeof g,"not a boolean"),g;case b.TYPES["float"]:case b.TYPES["double"]:return"number"!==typeof g&&a(typeof g,"not a number"),g;case b.TYPES.string:return"string"===typeof g||g&&g instanceof String||a(typeof g,"not a string"),""+g;case b.TYPES.bytes:return h.isByteBuffer(g)?g:h.wrap(g,"base64");case b.TYPES["enum"]:for(var f=this.resolvedType.getChildren(b.Reflect.Enum.Value),k=
  566. 0;k<f.length;k++)if(f[k].name==g||f[k].id==g)return f[k].id;if("proto3"===this.syntax)return("number"!==typeof g||g===g&&0!==g%1)&&a(typeof g,"not an integer"),(4294967295<g||0>g)&&a(typeof g,"not in range for uint32"),g;a(g,"not a valid enum value");case b.TYPES.group:case b.TYPES.message:g&&"object"===typeof g||a(typeof g,"object expected");if(g instanceof this.resolvedType.clazz)return g;if(g instanceof b.Builder.Message){var f={},k;for(k in g)g.hasOwnProperty(k)&&(f[k]=g[k]);g=f}return new this.resolvedType.clazz(g)}throw Error("[INTERNAL] Illegal value for "+
  567. this.toString(!0)+": "+g+" (undefined type "+this.type+")");};f.calculateLength=function(g,a){if(null===a)return 0;var c;switch(this.type){case b.TYPES.int32:return 0>a?h.calculateVarint64(a):h.calculateVarint32(a);case b.TYPES.uint32:return h.calculateVarint32(a);case b.TYPES.sint32:return h.calculateVarint32(h.zigZagEncode32(a));case b.TYPES.fixed32:case b.TYPES.sfixed32:case b.TYPES["float"]:return 4;case b.TYPES.int64:case b.TYPES.uint64:return h.calculateVarint64(a);case b.TYPES.sint64:return h.calculateVarint64(h.zigZagEncode64(a));
  568. case b.TYPES.fixed64:case b.TYPES.sfixed64:return 8;case b.TYPES.bool:return 1;case b.TYPES["enum"]:return h.calculateVarint32(a);case b.TYPES["double"]:return 8;case b.TYPES.string:return c=h.calculateUTF8Bytes(a),h.calculateVarint32(c)+c;case b.TYPES.bytes:if(0>a.remaining())throw Error("Illegal value for "+this.toString(!0)+": "+a.remaining()+" bytes remaining");return h.calculateVarint32(a.remaining())+a.remaining();case b.TYPES.message:return c=this.resolvedType.calculate(a),h.calculateVarint32(c)+
  569. c;case b.TYPES.group:return c=this.resolvedType.calculate(a),c+h.calculateVarint32(g<<3|b.WIRE_TYPES.ENDGROUP)}throw Error("[INTERNAL] Illegal value to encode in "+this.toString(!0)+": "+a+" (unknown type)");};f.encodeValue=function(g,a,c){if(null===a)return c;switch(this.type){case b.TYPES.int32:0>a?c.writeVarint64(a):c.writeVarint32(a);break;case b.TYPES.uint32:c.writeVarint32(a);break;case b.TYPES.sint32:c.writeVarint32ZigZag(a);break;case b.TYPES.fixed32:c.writeUint32(a);break;case b.TYPES.sfixed32:c.writeInt32(a);
  570. break;case b.TYPES.int64:case b.TYPES.uint64:c.writeVarint64(a);break;case b.TYPES.sint64:c.writeVarint64ZigZag(a);break;case b.TYPES.fixed64:c.writeUint64(a);break;case b.TYPES.sfixed64:c.writeInt64(a);break;case b.TYPES.bool:"string"===typeof a?c.writeVarint32("false"===a.toLowerCase()?0:!!a):c.writeVarint32(a?1:0);break;case b.TYPES["enum"]:c.writeVarint32(a);break;case b.TYPES["float"]:c.writeFloat32(a);break;case b.TYPES["double"]:c.writeFloat64(a);break;case b.TYPES.string:c.writeVString(a);
  571. break;case b.TYPES.bytes:if(0>a.remaining())throw Error("Illegal value for "+this.toString(!0)+": "+a.remaining()+" bytes remaining");g=a.offset;c.writeVarint32(a.remaining());c.append(a);a.offset=g;break;case b.TYPES.message:g=(new h).LE();this.resolvedType.encode(a,g);c.writeVarint32(g.offset);c.append(g.flip());break;case b.TYPES.group:this.resolvedType.encode(a,c);c.writeVarint32(g<<3|b.WIRE_TYPES.ENDGROUP);break;default:throw Error("[INTERNAL] Illegal value to encode in "+this.toString(!0)+": "+
  572. a+" (unknown type)");}return c};f.decode=function(a,c,d){if(c!=this.type.wireType)throw Error("Unexpected wire type for element");switch(this.type){case b.TYPES.int32:return a.readVarint32()|0;case b.TYPES.uint32:return a.readVarint32()>>>0;case b.TYPES.sint32:return a.readVarint32ZigZag()|0;case b.TYPES.fixed32:return a.readUint32()>>>0;case b.TYPES.sfixed32:return a.readInt32()|0;case b.TYPES.int64:return a.readVarint64();case b.TYPES.uint64:return a.readVarint64().toUnsigned();case b.TYPES.sint64:return a.readVarint64ZigZag();
  573. case b.TYPES.fixed64:return a.readUint64();case b.TYPES.sfixed64:return a.readInt64();case b.TYPES.bool:return!!a.readVarint32();case b.TYPES["enum"]:return a.readVarint32();case b.TYPES["float"]:return a.readFloat();case b.TYPES["double"]:return a.readDouble();case b.TYPES.string:return a.readVString();case b.TYPES.bytes:d=a.readVarint32();if(a.remaining()<d)throw Error("Illegal number of bytes for "+this.toString(!0)+": "+d+" required but got only "+a.remaining());c=a.clone();c.limit=c.offset+d;
  574. a.offset+=d;return c;case b.TYPES.message:return d=a.readVarint32(),this.resolvedType.decode(a,d);case b.TYPES.group:return this.resolvedType.decode(a,-1,d)}throw Error("[INTERNAL] Illegal decode type");};f.valueFromString=function(a){if(!this.isMapKey)throw Error("valueFromString() called on non-map-key element");switch(this.type){case b.TYPES.int32:case b.TYPES.sint32:case b.TYPES.sfixed32:case b.TYPES.uint32:case b.TYPES.fixed32:return this.verifyValue(parseInt(a));case b.TYPES.int64:case b.TYPES.sint64:case b.TYPES.sfixed64:case b.TYPES.uint64:case b.TYPES.fixed64:return this.verifyValue(a);
  575. case b.TYPES.bool:return"true"===a;case b.TYPES.string:return this.verifyValue(a);case b.TYPES.bytes:return h.fromBinary(a)}};f.valueToString=function(a){if(!this.isMapKey)throw Error("valueToString() called on non-map-key element");return this.type===b.TYPES.bytes?a.toString("binary"):a.toString()};q.Element=e;var s=function(b,c,d,e,l,f){a.call(this,b,c,d,e,f);this.className="Message";this.extensions=void 0;this.clazz=null;this.isGroup=!!l;this._fieldsByName=this._fieldsById=this._fields=null},f=
  576. s.prototype=Object.create(a.prototype);f.build=function(a){if(this.clazz&&!a)return this.clazz;a=function(b,a){function c(a,g,d,e){if(null===a||"object"!==typeof a){if(e&&e instanceof b.Reflect.Enum){var m=b.Reflect.Enum.getName(e.object,a);if(null!==m)return m}return a}if(h.isByteBuffer(a))return g?a.toBase64():a.toBuffer();if(b.Long.isLong(a))return d?a.toString():b.Long.fromValue(a);var l;if(Array.isArray(a))return l=[],a.forEach(function(a,b){l[b]=c(a,g,d,e)}),l;l={};if(a instanceof b.Map){for(var m=
  577. a.entries(),f=m.next();!f.done;f=m.next())l[a.keyElem.valueToString(f.value[0])]=c(f.value[1],g,d,a.valueElem.resolvedType);return l}var m=a.$type,f=void 0,k;for(k in a)a.hasOwnProperty(k)&&(m&&(f=m.getChild(k))?l[k]=c(a[k],g,d,f.resolvedType):l[k]=c(a[k],g,d));return l}var g=a.getChildren(b.Reflect.Message.Field),d=a.getChildren(b.Reflect.Message.OneOf),e=function(c,m){b.Builder.Message.call(this);for(var l=0,f=d.length;l<f;++l)this[d[l].name]=null;l=0;for(f=g.length;l<f;++l){var k=g[l];this[k.name]=
  578. k.repeated?[]:k.map?new b.Map(k):null;!k.required&&"proto3"!==a.syntax||null===k.defaultValue||(this[k.name]=k.defaultValue)}if(0<arguments.length)if(1!==arguments.length||null===c||"object"!==typeof c||!("function"!==typeof c.encode||c instanceof e)||Array.isArray(c)||c instanceof b.Map||h.isByteBuffer(c)||c instanceof ArrayBuffer||b.Long&&c instanceof b.Long)for(l=0,f=arguments.length;l<f;++l)"undefined"!==typeof(k=arguments[l])&&this.$set(g[l].name,k);else this.$set(c)},m=e.prototype=Object.create(b.Builder.Message.prototype);
  579. m.add=function(c,g,d){var e=a._fieldsByName[c];if(!d){if(!e)throw Error(this+"#"+c+" is undefined");if(!(e instanceof b.Reflect.Message.Field))throw Error(this+"#"+c+" is not a field: "+e.toString(!0));if(!e.repeated)throw Error(this+"#"+c+" is not a repeated field");g=e.verifyValue(g,!0)}null===this[c]&&(this[c]=[]);this[c].push(g);return this};m.$add=m.add;m.set=function(c,g,d){if(c&&"object"===typeof c){d=g;for(var e in c)c.hasOwnProperty(e)&&"undefined"!==typeof(g=c[e])&&this.$set(e,g,d);return this}e=
  580. a._fieldsByName[c];if(d)this[c]=g;else{if(!e)throw Error(this+"#"+c+" is not a field: undefined");if(!(e instanceof b.Reflect.Message.Field))throw Error(this+"#"+c+" is not a field: "+e.toString(!0));this[e.name]=g=e.verifyValue(g)}e&&e.oneof&&(d=this[e.oneof.name],null!==g?(null!==d&&d!==e.name&&(this[d]=null),this[e.oneof.name]=e.name):d===c&&(this[e.oneof.name]=null));return this};m.$set=m.set;m.get=function(c,g){if(g)return this[c];var d=a._fieldsByName[c];if(!(d&&d instanceof b.Reflect.Message.Field))throw Error(this+
  581. "#"+c+" is not a field: undefined");if(!(d instanceof b.Reflect.Message.Field))throw Error(this+"#"+c+" is not a field: "+d.toString(!0));return this[d.name]};m.$get=m.get;for(var l=0;l<g.length;l++){var f=g[l];f instanceof b.Reflect.Message.ExtensionField||a.builder.options.populateAccessors&&function(b){var c=b.originalName.replace(/(_[a-zA-Z])/g,function(a){return a.toUpperCase().replace("_","")}),c=c.substring(0,1).toUpperCase()+c.substring(1),g=b.originalName.replace(/([A-Z])/g,function(a){return"_"+
  582. a}),d=function(a,c){this[b.name]=c?a:b.verifyValue(a);return this},e=function(){return this[b.name]};null===a.getChild("set"+c)&&(m["set"+c]=d);null===a.getChild("set_"+g)&&(m["set_"+g]=d);null===a.getChild("get"+c)&&(m["get"+c]=e);null===a.getChild("get_"+g)&&(m["get_"+g]=e)}(f)}m.encode=function(b,c){"boolean"===typeof b&&(c=b,b=void 0);var g=!1;b||(b=new h,g=!0);var d=b.littleEndian;try{return a.encode(this,b.LE(),c),(g?b.flip():b).LE(d)}catch(e){throw b.LE(d),e;}};e.encode=function(b,a,c){return(new e(b)).encode(a,
  583. c)};m.calculate=function(){return a.calculate(this)};m.encodeDelimited=function(b,c){var g=!1;b||(b=new h,g=!0);var d=(new h).LE();a.encode(this,d,c).flip();b.writeVarint32(d.remaining());b.append(d);return g?b.flip():b};m.encodeAB=function(){try{return this.encode().toArrayBuffer()}catch(b){throw b.encoded&&(b.encoded=b.encoded.toArrayBuffer()),b;}};m.toArrayBuffer=m.encodeAB;m.encodeNB=function(){try{return this.encode().toBuffer()}catch(b){throw b.encoded&&(b.encoded=b.encoded.toBuffer()),b;}};
  584. m.toBuffer=m.encodeNB;m.encode64=function(){try{return this.encode().toBase64()}catch(b){throw b.encoded&&(b.encoded=b.encoded.toBase64()),b;}};m.toBase64=m.encode64;m.encodeHex=function(){try{return this.encode().toHex()}catch(b){throw b.encoded&&(b.encoded=b.encoded.toHex()),b;}};m.toHex=m.encodeHex;m.toRaw=function(b,a){return c(this,!!b,!!a,this.$type)};m.encodeJSON=function(){return JSON.stringify(c(this,!0,!0,this.$type))};e.decode=function(b,c,g){"string"===typeof c&&(g=c);"string"===typeof b&&
  585. (b=h.wrap(b,g?g:"base64"));b=h.isByteBuffer(b)?b:h.wrap(b);c=b.littleEndian;try{var d=a.decode(b.LE());b.LE(c);return d}catch(e){throw b.LE(c),e;}};e.decodeDelimited=function(b,c){"string"===typeof b&&(b=h.wrap(b,c?c:"base64"));b=h.isByteBuffer(b)?b:h.wrap(b);if(1>b.remaining())return null;var g=b.offset,d=b.readVarint32();if(b.remaining()<d)return b.offset=g,null;try{var e=a.decode(b.slice(b.offset,b.offset+d).LE());b.offset+=d;return e}catch(m){throw b.offset+=d,m;}};e.decode64=function(b){return e.decode(b,
  586. "base64")};e.decodeHex=function(b){return e.decode(b,"hex")};e.decodeJSON=function(b){return new e(JSON.parse(b))};m.toString=function(){return a.toString()};Object.defineProperty&&(Object.defineProperty(e,"$options",{value:a.buildOpt()}),Object.defineProperty(m,"$options",{value:e.$options}),Object.defineProperty(e,"$type",{value:a}),Object.defineProperty(m,"$type",{value:a}));return e}(b,this);this._fields=[];this._fieldsById={};this._fieldsByName={};for(var c=0,d=this.children.length,e;c<d;c++)if(e=
  587. this.children[c],e instanceof t||e instanceof s||e instanceof w){if(a.hasOwnProperty(e.name))throw Error("Illegal reflect child of "+this.toString(!0)+": "+e.toString(!0)+" cannot override static property '"+e.name+"'");a[e.name]=e.build()}else if(e instanceof s.Field)e.build(),this._fields.push(e),this._fieldsById[e.id]=e,this._fieldsByName[e.name]=e;else if(!(e instanceof s.OneOf||e instanceof l))throw Error("Illegal reflect child of "+this.toString(!0)+": "+this.children[c].toString(!0));return this.clazz=
  588. a};f.encode=function(b,a,c){for(var d=null,e,l=0,f=this._fields.length,k;l<f;++l)e=this._fields[l],k=b[e.name],e.required&&null===k?null===d&&(d=e):e.encode(c?k:e.verifyValue(k),a,b);if(null!==d)throw b=Error("Missing at least one required field for "+this.toString(!0)+": "+d),b.encoded=a,b;return a};f.calculate=function(b){for(var a=0,c=0,d=this._fields.length,e,l;c<d;++c){e=this._fields[c];l=b[e.name];if(e.required&&null===l)throw Error("Missing at least one required field for "+this.toString(!0)+
  589. ": "+e);a+=e.calculate(l,b)}return a};f.decode=function(a,c,d){c="number"===typeof c?c:-1;for(var e=a.offset,l=new this.clazz,f,k,s;a.offset<e+c||-1===c&&0<a.remaining();){f=a.readVarint32();k=f&7;s=f>>>3;if(k===b.WIRE_TYPES.ENDGROUP){if(s!==d)throw Error("Illegal group end indicator for "+this.toString(!0)+": "+s+" ("+(d?d+" expected":"not a group")+")");break}if(f=this._fieldsById[s])f.repeated&&!f.options.packed?l[f.name].push(f.decode(k,a)):f.map?(k=f.decode(k,a),l[f.name].set(k[0],k[1])):(l[f.name]=
  590. f.decode(k,a),f.oneof&&(k=l[f.oneof.name],null!==k&&k!==f.name&&(l[k]=null),l[f.oneof.name]=f.name));else switch(k){case b.WIRE_TYPES.VARINT:a.readVarint32();break;case b.WIRE_TYPES.BITS32:a.offset+=4;break;case b.WIRE_TYPES.BITS64:a.offset+=8;break;case b.WIRE_TYPES.LDELIM:f=a.readVarint32();a.offset+=f;break;case b.WIRE_TYPES.STARTGROUP:for(;p(s,a););break;default:throw Error("Illegal wire type for unknown field "+s+" in "+this.toString(!0)+"#decode: "+k);}}a=0;for(c=this._fields.length;a<c;++a)if(f=
  591. this._fields[a],null===l[f.name])if("proto3"===this.syntax)l[f.name]=f.defaultValue;else{if(f.required)throw a=Error("Missing at least one required field for "+this.toString(!0)+": "+f.name),a.decoded=l,a;b.populateDefaults&&null!==f.defaultValue&&(l[f.name]=f.defaultValue)}return l};q.Message=s;var c=function(a,c,d,e,l,f,k,h,r,p){n.call(this,a,c,f);this.className="Message.Field";this.required="required"===d;this.repeated="repeated"===d;this.map="map"===d;this.keyType=e||null;this.type=l;this.resolvedType=
  592. null;this.id=k;this.options=h||{};this.defaultValue=null;this.oneof=r||null;this.syntax=p||"proto2";this.originalName=this.name;this.keyElement=this.element=null;!this.builder.options.convertFieldsToCamelCase||this instanceof s.ExtensionField||(this.name=b.Util.toCamelCase(this.name))},f=c.prototype=Object.create(n.prototype);f.build=function(){this.element=new e(this.type,this.resolvedType,!1,this.syntax);this.map&&(this.keyElement=new e(this.keyType,void 0,!0,this.syntax));"proto3"!==this.syntax||
  593. this.repeated||this.map?"undefined"!==typeof this.options["default"]&&(this.defaultValue=this.verifyValue(this.options["default"])):this.defaultValue=e.defaultFieldValue(this.type)};f.verifyValue=function(a,c){function d(b,a){throw Error("Illegal value for "+e.toString(!0)+" of type "+e.type.name+": "+b+" ("+a+")");}c=c||!1;var e=this;if(null===a)return this.required&&d(typeof a,"required"),"proto3"===this.syntax&&this.type!==b.TYPES.message&&d(typeof a,"proto3 field without field presence cannot be null"),
  594. null;var l;if(this.repeated&&!c){Array.isArray(a)||(a=[a]);var f=[];for(l=0;l<a.length;l++)f.push(this.element.verifyValue(a[l]));return f}if(this.map&&!c){if(a instanceof b.Map)return a;a instanceof Object||d(typeof a,"expected ProtoBuf.Map or raw object for map field");return new b.Map(this,a)}!this.repeated&&Array.isArray(a)&&d(typeof a,"no array expected");return this.element.verifyValue(a)};f.hasWirePresence=function(a,c){if("proto3"!==this.syntax)return null!==a;if(this.oneof&&c[this.oneof.name]===
  595. this.name)return!0;switch(this.type){case b.TYPES.int32:case b.TYPES.sint32:case b.TYPES.sfixed32:case b.TYPES.uint32:case b.TYPES.fixed32:return 0!==a;case b.TYPES.int64:case b.TYPES.sint64:case b.TYPES.sfixed64:case b.TYPES.uint64:case b.TYPES.fixed64:return 0!==a.low||0!==a.high;case b.TYPES.bool:return a;case b.TYPES["float"]:case b.TYPES["double"]:return 0!==a;case b.TYPES.string:return 0<a.length;case b.TYPES.bytes:return 0<a.remaining();case b.TYPES["enum"]:return 0!==a;case b.TYPES.message:return null!==
  596. a;default:return!0}};f.encode=function(a,c,d){if(null===this.type||"object"!==typeof this.type)throw Error("[INTERNAL] Unresolved type in "+this.toString(!0)+": "+this.type);if(null===a||this.repeated&&0==a.length)return c;try{if(this.repeated){var e;if(this.options.packed&&0<=b.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType)){c.writeVarint32(this.id<<3|b.WIRE_TYPES.LDELIM);c.ensureCapacity(c.offset+=1);var l=c.offset;for(e=0;e<a.length;e++)this.element.encodeValue(this.id,a[e],c);var f=c.offset-
  597. l,k=h.calculateVarint32(f);if(1<k){var s=c.slice(l,c.offset),l=l+(k-1);c.offset=l;c.append(s)}c.writeVarint32(f,l-k)}else for(e=0;e<a.length;e++)c.writeVarint32(this.id<<3|this.type.wireType),this.element.encodeValue(this.id,a[e],c)}else this.map?a.forEach(function(a,d,e){e=h.calculateVarint32(8|this.keyType.wireType)+this.keyElement.calculateLength(1,d)+h.calculateVarint32(16|this.type.wireType)+this.element.calculateLength(2,a);c.writeVarint32(this.id<<3|b.WIRE_TYPES.LDELIM);c.writeVarint32(e);
  598. c.writeVarint32(8|this.keyType.wireType);this.keyElement.encodeValue(1,d,c);c.writeVarint32(16|this.type.wireType);this.element.encodeValue(2,a,c)},this):this.hasWirePresence(a,d)&&(c.writeVarint32(this.id<<3|this.type.wireType),this.element.encodeValue(this.id,a,c))}catch(r){throw Error("Illegal value for "+this.toString(!0)+": "+a+" ("+r+")");}return c};f.calculate=function(a,c){a=this.verifyValue(a);if(null===this.type||"object"!==typeof this.type)throw Error("[INTERNAL] Unresolved type in "+this.toString(!0)+
  599. ": "+this.type);if(null===a||this.repeated&&0==a.length)return 0;var d=0;try{if(this.repeated){var e,l;if(this.options.packed&&0<=b.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType)){d+=h.calculateVarint32(this.id<<3|b.WIRE_TYPES.LDELIM);for(e=l=0;e<a.length;e++)l+=this.element.calculateLength(this.id,a[e]);d+=h.calculateVarint32(l);d+=l}else for(e=0;e<a.length;e++)d+=h.calculateVarint32(this.id<<3|this.type.wireType),d+=this.element.calculateLength(this.id,a[e])}else this.map?a.forEach(function(a,
  600. c,e){a=h.calculateVarint32(8|this.keyType.wireType)+this.keyElement.calculateLength(1,c)+h.calculateVarint32(16|this.type.wireType)+this.element.calculateLength(2,a);d+=h.calculateVarint32(this.id<<3|b.WIRE_TYPES.LDELIM);d+=h.calculateVarint32(a);d+=a},this):this.hasWirePresence(a,c)&&(d+=h.calculateVarint32(this.id<<3|this.type.wireType),d+=this.element.calculateLength(this.id,a))}catch(f){throw Error("Illegal value for "+this.toString(!0)+": "+a+" ("+f+")");}return d};f.decode=function(a,c,d){if(!(!this.map&&
  601. a==this.type.wireType||!d&&this.repeated&&this.options.packed&&a==b.WIRE_TYPES.LDELIM||this.map&&a==b.WIRE_TYPES.LDELIM))throw Error("Illegal wire type for field "+this.toString(!0)+": "+a+" ("+this.type.wireType+" expected)");if(a==b.WIRE_TYPES.LDELIM&&this.repeated&&this.options.packed&&0<=b.PACKABLE_WIRE_TYPES.indexOf(this.type.wireType)&&!d){a=c.readVarint32();a=c.offset+a;for(d=[];c.offset<a;)d.push(this.decode(this.type.wireType,c,!0));return d}if(this.map){var l=e.defaultFieldValue(this.keyType);
  602. d=e.defaultFieldValue(this.type);a=c.readVarint32();if(c.remaining()<a)throw Error("Illegal number of bytes for "+this.toString(!0)+": "+a+" required but got only "+c.remaining());var f=c.clone();f.limit=f.offset+a;for(c.offset+=a;0<f.remaining();)if(c=f.readVarint32(),a=c&7,c>>>=3,1===c)l=this.keyElement.decode(f,a,c);else if(2===c)d=this.element.decode(f,a,c);else throw Error("Unexpected tag in map field key/value submessage");return[l,d]}return this.element.decode(c,a,this.id)};q.Message.Field=
  603. c;f=function(a,b,d,e,l,f,k){c.call(this,a,b,d,null,e,l,f,k)};f.prototype=Object.create(c.prototype);q.Message.ExtensionField=f;q.Message.OneOf=function(a,b,c){n.call(this,a,b,c);this.fields=[]};var t=function(b,c,d,e,l){a.call(this,b,c,d,e,l);this.className="Enum";this.object=null};t.getName=function(a,b){for(var c=Object.keys(a),d=0,e;d<c.length;++d)if(a[e=c[d]]===b)return e;return null};(t.prototype=Object.create(a.prototype)).build=function(a){if(this.object&&!a)return this.object;a=new b.Builder.Enum;
  604. for(var c=this.getChildren(t.Value),d=0,e=c.length;d<e;++d)a[c[d].name]=c[d].id;Object.defineProperty&&Object.defineProperty(a,"$options",{value:this.buildOpt(),enumerable:!1});return this.object=a};q.Enum=t;f=function(a,b,c,d){n.call(this,a,b,c);this.className="Enum.Value";this.id=d};f.prototype=Object.create(n.prototype);q.Enum.Value=f;var l=function(a,b,c,d){n.call(this,a,b,c);this.field=d};l.prototype=Object.create(n.prototype);q.Extension=l;var w=function(b,c,d,e){a.call(this,b,c,d,e);this.className=
  605. "Service";this.clazz=null};(w.prototype=Object.create(a.prototype)).build=function(a){return this.clazz&&!a?this.clazz:this.clazz=function(a,b){for(var c=function(b){a.Builder.Service.call(this);this.rpcImpl=b||function(a,b,c){setTimeout(c.bind(this,Error("Not implemented, see: https://github.com/dcodeIO/ProtoBuf.js/wiki/Services")),0)}},d=c.prototype=Object.create(a.Builder.Service.prototype),e=b.getChildren(a.Reflect.Service.RPCMethod),l=0;l<e.length;l++)(function(a){d[a.name]=function(c,d){try{try{c=
  606. a.resolvedRequestType.clazz.decode(h.wrap(c))}catch(e){if(!(e instanceof TypeError))throw e;}if(null===c||"object"!==typeof c)throw Error("Illegal arguments");c instanceof a.resolvedRequestType.clazz||(c=new a.resolvedRequestType.clazz(c));this.rpcImpl(a.fqn(),c,function(c,e){if(c)d(c);else{null===e&&(e="");try{e=a.resolvedResponseType.clazz.decode(e)}catch(l){}e&&e instanceof a.resolvedResponseType.clazz?d(null,e):d(Error("Illegal response type received in service method "+b.name+"#"+a.name))}})}catch(l){setTimeout(d.bind(this,
  607. l),0)}};c[a.name]=function(b,d,e){(new c(b))[a.name](d,e)};Object.defineProperty&&(Object.defineProperty(c[a.name],"$options",{value:a.buildOpt()}),Object.defineProperty(d[a.name],"$options",{value:c[a.name].$options}))})(e[l]);Object.defineProperty&&(Object.defineProperty(c,"$options",{value:b.buildOpt()}),Object.defineProperty(d,"$options",{value:c.$options}),Object.defineProperty(c,"$type",{value:b}),Object.defineProperty(d,"$type",{value:b}));return c}(b,this)};q.Service=w;var v=function(a,b,
  608. c,d){n.call(this,a,b,c);this.className="Service.Method";this.options=d||{}};(v.prototype=Object.create(n.prototype)).buildOpt=k.buildOpt;q.Service.Method=v;k=function(a,b,c,d,e,l,f,k){v.call(this,a,b,c,k);this.className="Service.RPCMethod";this.requestName=d;this.responseName=e;this.requestStream=l;this.responseStream=f;this.resolvedResponseType=this.resolvedRequestType=null};k.prototype=Object.create(v.prototype);q.Service.RPCMethod=k;return q}(d);d.Builder=function(b,d,h){function q(a){a.messages&&
  609. a.messages.forEach(function(b){b.syntax=a.syntax;q(b)});a.enums&&a.enums.forEach(function(b){b.syntax=a.syntax})}var n=function(a){this.ptr=this.ns=new h.Namespace(this,null,"");this.resolved=!1;this.result=null;this.files={};this.importRoot=null;this.options=a||{}},k=n.prototype;n.isMessage=function(a){return"string"!==typeof a.name||"undefined"!==typeof a.values||"undefined"!==typeof a.rpc?!1:!0};n.isMessageField=function(a){return"string"!==typeof a.rule||"string"!==typeof a.name||"string"!==typeof a.type||
  610. "undefined"===typeof a.id?!1:!0};n.isEnum=function(a){return"string"===typeof a.name&&"undefined"!==typeof a.values&&Array.isArray(a.values)&&0!==a.values.length?!0:!1};n.isService=function(a){return"string"===typeof a.name&&"object"===typeof a.rpc&&a.rpc?!0:!1};n.isExtend=function(a){return"string"!==typeof a.ref?!1:!0};k.reset=function(){this.ptr=this.ns;return this};k.define=function(a){if("string"!==typeof a||!d.TYPEREF.test(a))throw Error("illegal namespace: "+a);a.split(".").forEach(function(a){var b=
  611. this.ptr.getChild(a);null===b&&this.ptr.addChild(b=new h.Namespace(this,this.ptr,a));this.ptr=b},this);return this};k.create=function(a){if(!a)return this;if(Array.isArray(a)){if(0===a.length)return this;a=a.slice()}else a=[a];for(var d=[a];0<d.length;){a=d.pop();if(!Array.isArray(a))throw Error("not a valid namespace: "+JSON.stringify(a));for(;0<a.length;){var f=a.shift();if(n.isMessage(f)){var k=new h.Message(this,this.ptr,f.name,f.options,f.isGroup,f.syntax),c={};f.oneofs&&Object.keys(f.oneofs).forEach(function(a){k.addChild(c[a]=
  612. new h.Message.OneOf(this,k,a))},this);f.fields&&f.fields.forEach(function(a){if(null!==k.getChild(a.id|0))throw Error("duplicate or invalid field id in "+k.name+": "+a.id);if(a.options&&"object"!==typeof a.options)throw Error("illegal field options in "+k.name+"#"+a.name);var b=null;if("string"===typeof a.oneof&&!(b=c[a.oneof]))throw Error("illegal oneof in "+k.name+"#"+a.name+": "+a.oneof);a=new h.Message.Field(this,k,a.rule,a.keytype,a.type,a.name,a.id,a.options,b,f.syntax);b&&b.fields.push(a);
  613. k.addChild(a)},this);var r=[];f.enums&&f.enums.forEach(function(a){r.push(a)});f.messages&&f.messages.forEach(function(a){r.push(a)});f.services&&f.services.forEach(function(a){r.push(a)});f.extensions&&(k.extensions="number"===typeof f.extensions[0]?[f.extensions]:f.extensions);this.ptr.addChild(k);if(0<r.length){d.push(a);a=r;r=null;this.ptr=k;k=null;continue}r=null}else if(n.isEnum(f))k=new h.Enum(this,this.ptr,f.name,f.options,f.syntax),f.values.forEach(function(a){k.addChild(new h.Enum.Value(this,
  614. k,a.name,a.id))},this),this.ptr.addChild(k);else if(n.isService(f))k=new h.Service(this,this.ptr,f.name,f.options),Object.keys(f.rpc).forEach(function(a){var b=f.rpc[a];k.addChild(new h.Service.RPCMethod(this,k,a,b.request,b.response,!!b.request_stream,!!b.response_stream,b.options))},this),this.ptr.addChild(k);else if(n.isExtend(f))if(k=this.ptr.resolve(f.ref,!0))f.fields.forEach(function(a){if(null!==k.getChild(a.id|0))throw Error("duplicate extended field id in "+k.name+": "+a.id);if(k.extensions){var c=
  615. !1;k.extensions.forEach(function(b){a.id>=b[0]&&a.id<=b[1]&&(c=!0)});if(!c)throw Error("illegal extended field id in "+k.name+": "+a.id+" (not within valid ranges)");}var d=a.name;this.options.convertFieldsToCamelCase&&(d=b.Util.toCamelCase(d));var d=new h.Message.ExtensionField(this,k,a.rule,a.type,this.ptr.fqn()+"."+d,a.id,a.options),e=new h.Extension(this,this.ptr,a.name,d);d.extension=e;this.ptr.addChild(e);k.addChild(d)},this);else{if(!/\.?google\.protobuf\./.test(f.ref))throw Error("extended message "+
  616. f.ref+" is not defined");}else throw Error("not a valid definition: "+JSON.stringify(f));k=f=null}a=null;this.ptr=this.ptr.parent}this.resolved=!1;this.result=null;return this};k["import"]=function(a,d){var k="/";if("string"===typeof d){b.Util.IS_NODE&&(d=require("path").resolve(d));if(!0===this.files[d])return this.reset();this.files[d]=!0}else if("object"===typeof d){var h=d.root;b.Util.IS_NODE&&(h=require("path").resolve(h));if(0<=h.indexOf("\\")||0<=d.file.indexOf("\\"))k="\\";h=h+k+d.file;if(!0===
  617. this.files[h])return this.reset();this.files[h]=!0}if(a.imports&&0<a.imports.length){var c=!1;if("object"===typeof d){if(this.importRoot=d.root,c=!0,h=this.importRoot,d=d.file,0<=h.indexOf("\\")||0<=d.indexOf("\\"))k="\\"}else"string"===typeof d?this.importRoot?h=this.importRoot:0<=d.indexOf("/")?(h=d.replace(/\/[^\/]*$/,""),""===h&&(h="/")):0<=d.indexOf("\\")?(h=d.replace(/\\[^\\]*$/,""),k="\\"):h=".":h=null;for(var r=0;r<a.imports.length;r++)if("string"===typeof a.imports[r]){if(!h)throw Error("cannot determine import root");
  618. var l=a.imports[r];if("google/protobuf/descriptor.proto"!==l&&(l=h+k+l,!0!==this.files[l])){/\.proto$/i.test(l)&&!b.DotProto&&(l=l.replace(/\.proto$/,".json"));var n=b.Util.fetch(l);if(null===n)throw Error("failed to import '"+l+"' in '"+d+"': file not found");if(/\.json$/i.test(l))this["import"](JSON.parse(n+""),l);else this["import"](b.DotProto.Parser.parse(n),l)}}else if(d)if(/\.(\w+)$/.test(d))this["import"](a.imports[r],d.replace(/^(.+)\.(\w+)$/,function(a,b,c){return b+"_import"+r+"."+c}));
  619. else this["import"](a.imports[r],d+"_import"+r);else this["import"](a.imports[r]);c&&(this.importRoot=null)}a["package"]&&this.define(a["package"]);a.syntax&&q(a);var p=this.ptr;a.options&&Object.keys(a.options).forEach(function(b){p.options[b]=a.options[b]});a.messages&&(this.create(a.messages),this.ptr=p);a.enums&&(this.create(a.enums),this.ptr=p);a.services&&(this.create(a.services),this.ptr=p);a["extends"]&&this.create(a["extends"]);return this.reset()};k.resolveAll=function(){var a;if(null==
  620. this.ptr||"object"===typeof this.ptr.type)return this;if(this.ptr instanceof h.Namespace)this.ptr.children.forEach(function(a){this.ptr=a;this.resolveAll()},this);else if(this.ptr instanceof h.Message.Field){if(d.TYPE.test(this.ptr.type))this.ptr.type=b.TYPES[this.ptr.type];else{if(!d.TYPEREF.test(this.ptr.type))throw Error("illegal type reference in "+this.ptr.toString(!0)+": "+this.ptr.type);a=(this.ptr instanceof h.Message.ExtensionField?this.ptr.extension.parent:this.ptr.parent).resolve(this.ptr.type,
  621. !0);if(!a)throw Error("unresolvable type reference in "+this.ptr.toString(!0)+": "+this.ptr.type);this.ptr.resolvedType=a;if(a instanceof h.Enum){if(this.ptr.type=b.TYPES["enum"],"proto3"===this.ptr.syntax&&"proto3"!==a.syntax)throw Error("proto3 message cannot reference proto2 enum");}else if(a instanceof h.Message)this.ptr.type=a.isGroup?b.TYPES.group:b.TYPES.message;else throw Error("illegal type reference in "+this.ptr.toString(!0)+": "+this.ptr.type);}if(this.ptr.map){if(!d.TYPE.test(this.ptr.keyType))throw Error("illegal key type for map field in "+
  622. this.ptr.toString(!0)+": "+this.ptr.keyType);this.ptr.keyType=b.TYPES[this.ptr.keyType]}}else if(this.ptr instanceof b.Reflect.Service.Method)if(this.ptr instanceof b.Reflect.Service.RPCMethod){a=this.ptr.parent.resolve(this.ptr.requestName,!0);if(!(a&&a instanceof b.Reflect.Message))throw Error("Illegal type reference in "+this.ptr.toString(!0)+": "+this.ptr.requestName);this.ptr.resolvedRequestType=a;a=this.ptr.parent.resolve(this.ptr.responseName,!0);if(!(a&&a instanceof b.Reflect.Message))throw Error("Illegal type reference in "+
  623. this.ptr.toString(!0)+": "+this.ptr.responseName);this.ptr.resolvedResponseType=a}else throw Error("illegal service type in "+this.ptr.toString(!0));else if(!(this.ptr instanceof b.Reflect.Message.OneOf||this.ptr instanceof b.Reflect.Extension||this.ptr instanceof b.Reflect.Enum.Value))throw Error("illegal object in namespace: "+typeof this.ptr+": "+this.ptr);return this.reset()};k.build=function(a){this.reset();this.resolved||(this.resolveAll(),this.resolved=!0,this.result=null);null===this.result&&
  624. (this.result=this.ns.build());if(!a)return this.result;a="string"===typeof a?a.split("."):a;for(var b=this.result,d=0;d<a.length;d++)if(b[a[d]])b=b[a[d]];else{b=null;break}return b};k.lookup=function(a,b){return a?this.ns.resolve(a,b):this.ns};k.toString=function(){return"Builder"};n.Message=function(){};n.Enum=function(){};n.Service=function(){};return n}(d,d.Lang,d.Reflect);d.Map=function(b,d){function h(b){var a=0;return{next:function(){return a<b.length?{done:!1,value:b[a++]}:{done:!0}}}}var q=
  625. function(b,a){if(!b.map)throw Error("field is not a map");this.field=b;this.keyElem=new d.Element(b.keyType,null,!0,b.syntax);this.valueElem=new d.Element(b.type,b.resolvedType,!1,b.syntax);this.map={};Object.defineProperty(this,"size",{get:function(){return Object.keys(this.map).length}});if(a)for(var e=Object.keys(a),f=0;f<e.length;f++){var h=this.keyElem.valueFromString(e[f]),c=this.valueElem.verifyValue(a[e[f]]);this.map[this.keyElem.valueToString(h)]={key:h,value:c}}},n=q.prototype;n.clear=function(){this.map=
  626. {}};n["delete"]=function(b){b=this.keyElem.valueToString(this.keyElem.verifyValue(b));var a=b in this.map;delete this.map[b];return a};n.entries=function(){for(var b=[],a=Object.keys(this.map),d=0,f;d<a.length;d++)b.push([(f=this.map[a[d]]).key,f.value]);return h(b)};n.keys=function(){for(var b=[],a=Object.keys(this.map),d=0;d<a.length;d++)b.push(this.map[a[d]].key);return h(b)};n.values=function(){for(var b=[],a=Object.keys(this.map),d=0;d<a.length;d++)b.push(this.map[a[d]].value);return h(b)};n.forEach=
  627. function(b,a){for(var d=Object.keys(this.map),f=0,h;f<d.length;f++)b.call(a,(h=this.map[d[f]]).value,h.key,this)};n.set=function(b,a){var d=this.keyElem.verifyValue(b),f=this.valueElem.verifyValue(a);this.map[this.keyElem.valueToString(d)]={key:d,value:f};return this};n.get=function(b){b=this.keyElem.valueToString(this.keyElem.verifyValue(b));return b in this.map?this.map[b].value:void 0};n.has=function(b){return this.keyElem.valueToString(this.keyElem.verifyValue(b))in this.map};return q}(d,d.Reflect);
  628. d.loadProto=function(b,h,p){if("string"===typeof h||h&&"string"===typeof h.file&&"string"===typeof h.root)p=h,h=void 0;return d.loadJson(d.DotProto.Parser.parse(b),h,p)};d.protoFromString=d.loadProto;d.loadProtoFile=function(b,h,p){h&&"object"===typeof h?(p=h,h=null):h&&"function"===typeof h||(h=null);if(h)return d.Util.fetch("string"===typeof b?b:b.root+"/"+b.file,function(n){if(null===n)h(Error("Failed to fetch file"));else try{h(null,d.loadProto(n,p,b))}catch(k){h(k)}});var q=d.Util.fetch("object"===
  629. typeof b?b.root+"/"+b.file:b);return null===q?null:d.loadProto(q,p,b)};d.protoFromFile=d.loadProtoFile;d.newBuilder=function(b){b=b||{};"undefined"===typeof b.convertFieldsToCamelCase&&(b.convertFieldsToCamelCase=d.convertFieldsToCamelCase);"undefined"===typeof b.populateAccessors&&(b.populateAccessors=d.populateAccessors);return new d.Builder(b)};d.loadJson=function(b,h,p){if("string"===typeof h||h&&"string"===typeof h.file&&"string"===typeof h.root)p=h,h=null;h&&"object"===typeof h||(h=d.newBuilder());
  630. "string"===typeof b&&(b=JSON.parse(b));h["import"](b,p);h.resolveAll();return h};d.loadJsonFile=function(b,h,p){h&&"object"===typeof h?(p=h,h=null):h&&"function"===typeof h||(h=null);if(h)return d.Util.fetch("string"===typeof b?b:b.root+"/"+b.file,function(n){if(null===n)h(Error("Failed to fetch file"));else try{h(null,d.loadJson(JSON.parse(n),p,b))}catch(k){h(k)}});var q=d.Util.fetch("object"===typeof b?b.root+"/"+b.file:b);return null===q?null:d.loadJson(JSON.parse(q),p,b)};return d});
  631. ;
  632. /*!
  633. * EventEmitter v5.2.6 - git.io/ee
  634. * Unlicense - http://unlicense.org/
  635. * Oliver Caldwell - https://oli.me.uk/
  636. * @preserve
  637. */
  638. !function(e){"use strict";function t(){}function n(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function r(e){return function(){return this[e].apply(this,arguments)}}function i(e){return"function"==typeof e||e instanceof RegExp||!(!e||"object"!=typeof e)&&i(e.listener)}var s=t.prototype,o=e.EventEmitter;s.getListeners=function(e){var t,n,r=this._getEvents();if(e instanceof RegExp){t={};for(n in r)r.hasOwnProperty(n)&&e.test(n)&&(t[n]=r[n])}else t=r[e]||(r[e]=[]);return t},s.flattenListeners=function(e){var t,n=[];for(t=0;t<e.length;t+=1)n.push(e[t].listener);return n},s.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},s.addListener=function(e,t){if(!i(t))throw new TypeError("listener must be a function");var r,s=this.getListenersAsObject(e),o="object"==typeof t;for(r in s)s.hasOwnProperty(r)&&-1===n(s[r],t)&&s[r].push(o?t:{listener:t,once:!1});return this},s.on=r("addListener"),s.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},s.once=r("addOnceListener"),s.defineEvent=function(e){return this.getListeners(e),this},s.defineEvents=function(e){for(var t=0;t<e.length;t+=1)this.defineEvent(e[t]);return this},s.removeListener=function(e,t){var r,i,s=this.getListenersAsObject(e);for(i in s)s.hasOwnProperty(i)&&-1!==(r=n(s[i],t))&&s[i].splice(r,1);return this},s.off=r("removeListener"),s.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},s.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},s.manipulateListeners=function(e,t,n){var r,i,s=e?this.removeListener:this.addListener,o=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(r=n.length;r--;)s.call(this,t,n[r]);else for(r in t)t.hasOwnProperty(r)&&(i=t[r])&&("function"==typeof i?s.call(this,r,i):o.call(this,r,i));return this},s.removeEvent=function(e){var t,n=typeof e,r=this._getEvents();if("string"===n)delete r[e];else if(e instanceof RegExp)for(t in r)r.hasOwnProperty(t)&&e.test(t)&&delete r[t];else delete this._events;return this},s.removeAllListeners=r("removeEvent"),s.emitEvent=function(e,t){var n,r,i,s,o=this.getListenersAsObject(e);for(s in o)if(o.hasOwnProperty(s))for(n=o[s].slice(0),i=0;i<n.length;i++)r=n[i],!0===r.once&&this.removeListener(e,r.listener),r.listener.apply(this,t||[])===this._getOnceReturnValue()&&this.removeListener(e,r.listener);return this},s.trigger=r("emitEvent"),s.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},s.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},s._getOnceReturnValue=function(){return!this.hasOwnProperty("_onceReturnValue")||this._onceReturnValue},s._getEvents=function(){return this._events||(this._events={})},t.noConflict=function(){return e.EventEmitter=o,t},"function"==typeof define&&define.amd?define(function(){return t}):"object"==typeof module&&module.exports?module.exports=t:e.EventEmitter=t}("undefined"!=typeof window?window:this||{});;
  639. /**
  640. * @license
  641. * Copyright 2010-2022 Three.js Authors
  642. * SPDX-License-Identifier: MIT
  643. */
  644. (function (global, factory) {
  645. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  646. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  647. (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {}));
  648. })(this, (function (exports) { 'use strict';
  649. const REVISION = '143';
  650. const MOUSE = {
  651. LEFT: 0,
  652. MIDDLE: 1,
  653. RIGHT: 2,
  654. ROTATE: 0,
  655. DOLLY: 1,
  656. PAN: 2
  657. };
  658. const TOUCH = {
  659. ROTATE: 0,
  660. PAN: 1,
  661. DOLLY_PAN: 2,
  662. DOLLY_ROTATE: 3
  663. };
  664. const CullFaceNone = 0;
  665. const CullFaceBack = 1;
  666. const CullFaceFront = 2;
  667. const CullFaceFrontBack = 3;
  668. const BasicShadowMap = 0;
  669. const PCFShadowMap = 1;
  670. const PCFSoftShadowMap = 2;
  671. const VSMShadowMap = 3;
  672. const FrontSide = 0;
  673. const BackSide = 1;
  674. const DoubleSide = 2;
  675. const FlatShading = 1;
  676. const SmoothShading = 2;
  677. const NoBlending = 0;
  678. const NormalBlending = 1;
  679. const AdditiveBlending = 2;
  680. const SubtractiveBlending = 3;
  681. const MultiplyBlending = 4;
  682. const CustomBlending = 5;
  683. const AddEquation = 100;
  684. const SubtractEquation = 101;
  685. const ReverseSubtractEquation = 102;
  686. const MinEquation = 103;
  687. const MaxEquation = 104;
  688. const ZeroFactor = 200;
  689. const OneFactor = 201;
  690. const SrcColorFactor = 202;
  691. const OneMinusSrcColorFactor = 203;
  692. const SrcAlphaFactor = 204;
  693. const OneMinusSrcAlphaFactor = 205;
  694. const DstAlphaFactor = 206;
  695. const OneMinusDstAlphaFactor = 207;
  696. const DstColorFactor = 208;
  697. const OneMinusDstColorFactor = 209;
  698. const SrcAlphaSaturateFactor = 210;
  699. const NeverDepth = 0;
  700. const AlwaysDepth = 1;
  701. const LessDepth = 2;
  702. const LessEqualDepth = 3;
  703. const EqualDepth = 4;
  704. const GreaterEqualDepth = 5;
  705. const GreaterDepth = 6;
  706. const NotEqualDepth = 7;
  707. const MultiplyOperation = 0;
  708. const MixOperation = 1;
  709. const AddOperation = 2;
  710. const NoToneMapping = 0;
  711. const LinearToneMapping = 1;
  712. const ReinhardToneMapping = 2;
  713. const CineonToneMapping = 3;
  714. const ACESFilmicToneMapping = 4;
  715. const CustomToneMapping = 5;
  716. const UVMapping = 300;
  717. const CubeReflectionMapping = 301;
  718. const CubeRefractionMapping = 302;
  719. const EquirectangularReflectionMapping = 303;
  720. const EquirectangularRefractionMapping = 304;
  721. const CubeUVReflectionMapping = 306;
  722. const RepeatWrapping = 1000;
  723. const ClampToEdgeWrapping = 1001;
  724. const MirroredRepeatWrapping = 1002;
  725. const NearestFilter = 1003;
  726. const NearestMipmapNearestFilter = 1004;
  727. const NearestMipMapNearestFilter = 1004;
  728. const NearestMipmapLinearFilter = 1005;
  729. const NearestMipMapLinearFilter = 1005;
  730. const LinearFilter = 1006;
  731. const LinearMipmapNearestFilter = 1007;
  732. const LinearMipMapNearestFilter = 1007;
  733. const LinearMipmapLinearFilter = 1008;
  734. const LinearMipMapLinearFilter = 1008;
  735. const UnsignedByteType = 1009;
  736. const ByteType = 1010;
  737. const ShortType = 1011;
  738. const UnsignedShortType = 1012;
  739. const IntType = 1013;
  740. const UnsignedIntType = 1014;
  741. const FloatType = 1015;
  742. const HalfFloatType = 1016;
  743. const UnsignedShort4444Type = 1017;
  744. const UnsignedShort5551Type = 1018;
  745. const UnsignedInt248Type = 1020;
  746. const AlphaFormat = 1021;
  747. const RGBFormat = 1022;
  748. const RGBAFormat = 1023;
  749. const LuminanceFormat = 1024;
  750. const LuminanceAlphaFormat = 1025;
  751. const DepthFormat = 1026;
  752. const DepthStencilFormat = 1027;
  753. const RedFormat = 1028;
  754. const RedIntegerFormat = 1029;
  755. const RGFormat = 1030;
  756. const RGIntegerFormat = 1031;
  757. const RGBAIntegerFormat = 1033;
  758. const RGB_S3TC_DXT1_Format = 33776;
  759. const RGBA_S3TC_DXT1_Format = 33777;
  760. const RGBA_S3TC_DXT3_Format = 33778;
  761. const RGBA_S3TC_DXT5_Format = 33779;
  762. const RGB_PVRTC_4BPPV1_Format = 35840;
  763. const RGB_PVRTC_2BPPV1_Format = 35841;
  764. const RGBA_PVRTC_4BPPV1_Format = 35842;
  765. const RGBA_PVRTC_2BPPV1_Format = 35843;
  766. const RGB_ETC1_Format = 36196;
  767. const RGB_ETC2_Format = 37492;
  768. const RGBA_ETC2_EAC_Format = 37496;
  769. const RGBA_ASTC_4x4_Format = 37808;
  770. const RGBA_ASTC_5x4_Format = 37809;
  771. const RGBA_ASTC_5x5_Format = 37810;
  772. const RGBA_ASTC_6x5_Format = 37811;
  773. const RGBA_ASTC_6x6_Format = 37812;
  774. const RGBA_ASTC_8x5_Format = 37813;
  775. const RGBA_ASTC_8x6_Format = 37814;
  776. const RGBA_ASTC_8x8_Format = 37815;
  777. const RGBA_ASTC_10x5_Format = 37816;
  778. const RGBA_ASTC_10x6_Format = 37817;
  779. const RGBA_ASTC_10x8_Format = 37818;
  780. const RGBA_ASTC_10x10_Format = 37819;
  781. const RGBA_ASTC_12x10_Format = 37820;
  782. const RGBA_ASTC_12x12_Format = 37821;
  783. const RGBA_BPTC_Format = 36492;
  784. const LoopOnce = 2200;
  785. const LoopRepeat = 2201;
  786. const LoopPingPong = 2202;
  787. const InterpolateDiscrete = 2300;
  788. const InterpolateLinear = 2301;
  789. const InterpolateSmooth = 2302;
  790. const ZeroCurvatureEnding = 2400;
  791. const ZeroSlopeEnding = 2401;
  792. const WrapAroundEnding = 2402;
  793. const NormalAnimationBlendMode = 2500;
  794. const AdditiveAnimationBlendMode = 2501;
  795. const TrianglesDrawMode = 0;
  796. const TriangleStripDrawMode = 1;
  797. const TriangleFanDrawMode = 2;
  798. const LinearEncoding = 3000;
  799. const sRGBEncoding = 3001;
  800. const BasicDepthPacking = 3200;
  801. const RGBADepthPacking = 3201;
  802. const TangentSpaceNormalMap = 0;
  803. const ObjectSpaceNormalMap = 1; // Color space string identifiers, matching CSS Color Module Level 4 and WebGPU names where available.
  804. const NoColorSpace = '';
  805. const SRGBColorSpace = 'srgb';
  806. const LinearSRGBColorSpace = 'srgb-linear';
  807. const ZeroStencilOp = 0;
  808. const KeepStencilOp = 7680;
  809. const ReplaceStencilOp = 7681;
  810. const IncrementStencilOp = 7682;
  811. const DecrementStencilOp = 7683;
  812. const IncrementWrapStencilOp = 34055;
  813. const DecrementWrapStencilOp = 34056;
  814. const InvertStencilOp = 5386;
  815. const NeverStencilFunc = 512;
  816. const LessStencilFunc = 513;
  817. const EqualStencilFunc = 514;
  818. const LessEqualStencilFunc = 515;
  819. const GreaterStencilFunc = 516;
  820. const NotEqualStencilFunc = 517;
  821. const GreaterEqualStencilFunc = 518;
  822. const AlwaysStencilFunc = 519;
  823. const StaticDrawUsage = 35044;
  824. const DynamicDrawUsage = 35048;
  825. const StreamDrawUsage = 35040;
  826. const StaticReadUsage = 35045;
  827. const DynamicReadUsage = 35049;
  828. const StreamReadUsage = 35041;
  829. const StaticCopyUsage = 35046;
  830. const DynamicCopyUsage = 35050;
  831. const StreamCopyUsage = 35042;
  832. const GLSL1 = '100';
  833. const GLSL3 = '300 es';
  834. const _SRGBAFormat = 1035; // fallback for WebGL 1
  835. /**
  836. * https://github.com/mrdoob/eventdispatcher.js/
  837. */
  838. class EventDispatcher {
  839. addEventListener(type, listener) {
  840. if (this._listeners === undefined) this._listeners = {};
  841. const listeners = this._listeners;
  842. if (listeners[type] === undefined) {
  843. listeners[type] = [];
  844. }
  845. if (listeners[type].indexOf(listener) === -1) {
  846. listeners[type].push(listener);
  847. }
  848. }
  849. hasEventListener(type, listener) {
  850. if (this._listeners === undefined) return false;
  851. const listeners = this._listeners;
  852. return listeners[type] !== undefined && listeners[type].indexOf(listener) !== -1;
  853. }
  854. removeEventListener(type, listener) {
  855. if (this._listeners === undefined) return;
  856. const listeners = this._listeners;
  857. const listenerArray = listeners[type];
  858. if (listenerArray !== undefined) {
  859. const index = listenerArray.indexOf(listener);
  860. if (index !== -1) {
  861. listenerArray.splice(index, 1);
  862. }
  863. }
  864. }
  865. dispatchEvent(event) {
  866. if (this._listeners === undefined) return;
  867. const listeners = this._listeners;
  868. const listenerArray = listeners[event.type];
  869. if (listenerArray !== undefined) {
  870. event.target = this; // Make a copy, in case listeners are removed while iterating.
  871. const array = listenerArray.slice(0);
  872. for (let i = 0, l = array.length; i < l; i++) {
  873. array[i].call(this, event);
  874. }
  875. event.target = null;
  876. }
  877. }
  878. }
  879. const _lut = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '0a', '0b', '0c', '0d', '0e', '0f', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a', '1b', '1c', '1d', '1e', '1f', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '2a', '2b', '2c', '2d', '2e', '2f', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '3a', '3b', '3c', '3d', '3e', '3f', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '4a', '4b', '4c', '4d', '4e', '4f', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '5a', '5b', '5c', '5d', '5e', '5f', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '6a', '6b', '6c', '6d', '6e', '6f', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '7a', '7b', '7c', '7d', '7e', '7f', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '8a', '8b', '8c', '8d', '8e', '8f', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '9a', '9b', '9c', '9d', '9e', '9f', 'a0', 'a1', 'a2', 'a3', 'a4', 'a5', 'a6', 'a7', 'a8', 'a9', 'aa', 'ab', 'ac', 'ad', 'ae', 'af', 'b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7', 'b8', 'b9', 'ba', 'bb', 'bc', 'bd', 'be', 'bf', 'c0', 'c1', 'c2', 'c3', 'c4', 'c5', 'c6', 'c7', 'c8', 'c9', 'ca', 'cb', 'cc', 'cd', 'ce', 'cf', 'd0', 'd1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9', 'da', 'db', 'dc', 'dd', 'de', 'df', 'e0', 'e1', 'e2', 'e3', 'e4', 'e5', 'e6', 'e7', 'e8', 'e9', 'ea', 'eb', 'ec', 'ed', 'ee', 'ef', 'f0', 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'fa', 'fb', 'fc', 'fd', 'fe', 'ff'];
  880. let _seed = 1234567;
  881. const DEG2RAD = Math.PI / 180;
  882. const RAD2DEG = 180 / Math.PI; // http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136
  883. function generateUUID() {
  884. const d0 = Math.random() * 0xffffffff | 0;
  885. const d1 = Math.random() * 0xffffffff | 0;
  886. const d2 = Math.random() * 0xffffffff | 0;
  887. const d3 = Math.random() * 0xffffffff | 0;
  888. const uuid = _lut[d0 & 0xff] + _lut[d0 >> 8 & 0xff] + _lut[d0 >> 16 & 0xff] + _lut[d0 >> 24 & 0xff] + '-' + _lut[d1 & 0xff] + _lut[d1 >> 8 & 0xff] + '-' + _lut[d1 >> 16 & 0x0f | 0x40] + _lut[d1 >> 24 & 0xff] + '-' + _lut[d2 & 0x3f | 0x80] + _lut[d2 >> 8 & 0xff] + '-' + _lut[d2 >> 16 & 0xff] + _lut[d2 >> 24 & 0xff] + _lut[d3 & 0xff] + _lut[d3 >> 8 & 0xff] + _lut[d3 >> 16 & 0xff] + _lut[d3 >> 24 & 0xff]; // .toLowerCase() here flattens concatenated strings to save heap memory space.
  889. return uuid.toLowerCase();
  890. }
  891. function clamp(value, min, max) {
  892. return Math.max(min, Math.min(max, value));
  893. } // compute euclidean modulo of m % n
  894. // https://en.wikipedia.org/wiki/Modulo_operation
  895. function euclideanModulo(n, m) {
  896. return (n % m + m) % m;
  897. } // Linear mapping from range <a1, a2> to range <b1, b2>
  898. function mapLinear(x, a1, a2, b1, b2) {
  899. return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
  900. } // https://www.gamedev.net/tutorials/programming/general-and-gameplay-programming/inverse-lerp-a-super-useful-yet-often-overlooked-function-r5230/
  901. function inverseLerp(x, y, value) {
  902. if (x !== y) {
  903. return (value - x) / (y - x);
  904. } else {
  905. return 0;
  906. }
  907. } // https://en.wikipedia.org/wiki/Linear_interpolation
  908. function lerp(x, y, t) {
  909. return (1 - t) * x + t * y;
  910. } // http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/
  911. function damp(x, y, lambda, dt) {
  912. return lerp(x, y, 1 - Math.exp(-lambda * dt));
  913. } // https://www.desmos.com/calculator/vcsjnyz7x4
  914. function pingpong(x, length = 1) {
  915. return length - Math.abs(euclideanModulo(x, length * 2) - length);
  916. } // http://en.wikipedia.org/wiki/Smoothstep
  917. function smoothstep(x, min, max) {
  918. if (x <= min) return 0;
  919. if (x >= max) return 1;
  920. x = (x - min) / (max - min);
  921. return x * x * (3 - 2 * x);
  922. }
  923. function smootherstep(x, min, max) {
  924. if (x <= min) return 0;
  925. if (x >= max) return 1;
  926. x = (x - min) / (max - min);
  927. return x * x * x * (x * (x * 6 - 15) + 10);
  928. } // Random integer from <low, high> interval
  929. function randInt(low, high) {
  930. return low + Math.floor(Math.random() * (high - low + 1));
  931. } // Random float from <low, high> interval
  932. function randFloat(low, high) {
  933. return low + Math.random() * (high - low);
  934. } // Random float from <-range/2, range/2> interval
  935. function randFloatSpread(range) {
  936. return range * (0.5 - Math.random());
  937. } // Deterministic pseudo-random float in the interval [ 0, 1 ]
  938. function seededRandom(s) {
  939. if (s !== undefined) _seed = s; // Mulberry32 generator
  940. let t = _seed += 0x6D2B79F5;
  941. t = Math.imul(t ^ t >>> 15, t | 1);
  942. t ^= t + Math.imul(t ^ t >>> 7, t | 61);
  943. return ((t ^ t >>> 14) >>> 0) / 4294967296;
  944. }
  945. function degToRad(degrees) {
  946. return degrees * DEG2RAD;
  947. }
  948. function radToDeg(radians) {
  949. return radians * RAD2DEG;
  950. }
  951. function isPowerOfTwo(value) {
  952. return (value & value - 1) === 0 && value !== 0;
  953. }
  954. function ceilPowerOfTwo(value) {
  955. return Math.pow(2, Math.ceil(Math.log(value) / Math.LN2));
  956. }
  957. function floorPowerOfTwo(value) {
  958. return Math.pow(2, Math.floor(Math.log(value) / Math.LN2));
  959. }
  960. function setQuaternionFromProperEuler(q, a, b, c, order) {
  961. // Intrinsic Proper Euler Angles - see https://en.wikipedia.org/wiki/Euler_angles
  962. // rotations are applied to the axes in the order specified by 'order'
  963. // rotation by angle 'a' is applied first, then by angle 'b', then by angle 'c'
  964. // angles are in radians
  965. const cos = Math.cos;
  966. const sin = Math.sin;
  967. const c2 = cos(b / 2);
  968. const s2 = sin(b / 2);
  969. const c13 = cos((a + c) / 2);
  970. const s13 = sin((a + c) / 2);
  971. const c1_3 = cos((a - c) / 2);
  972. const s1_3 = sin((a - c) / 2);
  973. const c3_1 = cos((c - a) / 2);
  974. const s3_1 = sin((c - a) / 2);
  975. switch (order) {
  976. case 'XYX':
  977. q.set(c2 * s13, s2 * c1_3, s2 * s1_3, c2 * c13);
  978. break;
  979. case 'YZY':
  980. q.set(s2 * s1_3, c2 * s13, s2 * c1_3, c2 * c13);
  981. break;
  982. case 'ZXZ':
  983. q.set(s2 * c1_3, s2 * s1_3, c2 * s13, c2 * c13);
  984. break;
  985. case 'XZX':
  986. q.set(c2 * s13, s2 * s3_1, s2 * c3_1, c2 * c13);
  987. break;
  988. case 'YXY':
  989. q.set(s2 * c3_1, c2 * s13, s2 * s3_1, c2 * c13);
  990. break;
  991. case 'ZYZ':
  992. q.set(s2 * s3_1, s2 * c3_1, c2 * s13, c2 * c13);
  993. break;
  994. default:
  995. console.warn('THREE.MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: ' + order);
  996. }
  997. }
  998. function denormalize$1(value, array) {
  999. switch (array.constructor) {
  1000. case Float32Array:
  1001. return value;
  1002. case Uint16Array:
  1003. return value / 65535.0;
  1004. case Uint8Array:
  1005. return value / 255.0;
  1006. case Int16Array:
  1007. return Math.max(value / 32767.0, -1.0);
  1008. case Int8Array:
  1009. return Math.max(value / 127.0, -1.0);
  1010. default:
  1011. throw new Error('Invalid component type.');
  1012. }
  1013. }
  1014. function normalize(value, array) {
  1015. switch (array.constructor) {
  1016. case Float32Array:
  1017. return value;
  1018. case Uint16Array:
  1019. return Math.round(value * 65535.0);
  1020. case Uint8Array:
  1021. return Math.round(value * 255.0);
  1022. case Int16Array:
  1023. return Math.round(value * 32767.0);
  1024. case Int8Array:
  1025. return Math.round(value * 127.0);
  1026. default:
  1027. throw new Error('Invalid component type.');
  1028. }
  1029. }
  1030. var MathUtils = /*#__PURE__*/Object.freeze({
  1031. __proto__: null,
  1032. DEG2RAD: DEG2RAD,
  1033. RAD2DEG: RAD2DEG,
  1034. generateUUID: generateUUID,
  1035. clamp: clamp,
  1036. euclideanModulo: euclideanModulo,
  1037. mapLinear: mapLinear,
  1038. inverseLerp: inverseLerp,
  1039. lerp: lerp,
  1040. damp: damp,
  1041. pingpong: pingpong,
  1042. smoothstep: smoothstep,
  1043. smootherstep: smootherstep,
  1044. randInt: randInt,
  1045. randFloat: randFloat,
  1046. randFloatSpread: randFloatSpread,
  1047. seededRandom: seededRandom,
  1048. degToRad: degToRad,
  1049. radToDeg: radToDeg,
  1050. isPowerOfTwo: isPowerOfTwo,
  1051. ceilPowerOfTwo: ceilPowerOfTwo,
  1052. floorPowerOfTwo: floorPowerOfTwo,
  1053. setQuaternionFromProperEuler: setQuaternionFromProperEuler,
  1054. normalize: normalize,
  1055. denormalize: denormalize$1
  1056. });
  1057. class Vector2 {
  1058. constructor(x = 0, y = 0) {
  1059. Vector2.prototype.isVector2 = true;
  1060. this.x = x;
  1061. this.y = y;
  1062. }
  1063. get width() {
  1064. return this.x;
  1065. }
  1066. set width(value) {
  1067. this.x = value;
  1068. }
  1069. get height() {
  1070. return this.y;
  1071. }
  1072. set height(value) {
  1073. this.y = value;
  1074. }
  1075. set(x, y) {
  1076. this.x = x;
  1077. this.y = y;
  1078. return this;
  1079. }
  1080. setScalar(scalar) {
  1081. this.x = scalar;
  1082. this.y = scalar;
  1083. return this;
  1084. }
  1085. setX(x) {
  1086. this.x = x;
  1087. return this;
  1088. }
  1089. setY(y) {
  1090. this.y = y;
  1091. return this;
  1092. }
  1093. setComponent(index, value) {
  1094. switch (index) {
  1095. case 0:
  1096. this.x = value;
  1097. break;
  1098. case 1:
  1099. this.y = value;
  1100. break;
  1101. default:
  1102. throw new Error('index is out of range: ' + index);
  1103. }
  1104. return this;
  1105. }
  1106. getComponent(index) {
  1107. switch (index) {
  1108. case 0:
  1109. return this.x;
  1110. case 1:
  1111. return this.y;
  1112. default:
  1113. throw new Error('index is out of range: ' + index);
  1114. }
  1115. }
  1116. clone() {
  1117. return new this.constructor(this.x, this.y);
  1118. }
  1119. copy(v) {
  1120. this.x = v.x;
  1121. this.y = v.y;
  1122. return this;
  1123. }
  1124. add(v) {
  1125. this.x += v.x;
  1126. this.y += v.y;
  1127. return this;
  1128. }
  1129. addScalar(s) {
  1130. this.x += s;
  1131. this.y += s;
  1132. return this;
  1133. }
  1134. addVectors(a, b) {
  1135. this.x = a.x + b.x;
  1136. this.y = a.y + b.y;
  1137. return this;
  1138. }
  1139. addScaledVector(v, s) {
  1140. this.x += v.x * s;
  1141. this.y += v.y * s;
  1142. return this;
  1143. }
  1144. sub(v) {
  1145. this.x -= v.x;
  1146. this.y -= v.y;
  1147. return this;
  1148. }
  1149. subScalar(s) {
  1150. this.x -= s;
  1151. this.y -= s;
  1152. return this;
  1153. }
  1154. subVectors(a, b) {
  1155. this.x = a.x - b.x;
  1156. this.y = a.y - b.y;
  1157. return this;
  1158. }
  1159. multiply(v) {
  1160. this.x *= v.x;
  1161. this.y *= v.y;
  1162. return this;
  1163. }
  1164. multiplyScalar(scalar) {
  1165. this.x *= scalar;
  1166. this.y *= scalar;
  1167. return this;
  1168. }
  1169. divide(v) {
  1170. this.x /= v.x;
  1171. this.y /= v.y;
  1172. return this;
  1173. }
  1174. divideScalar(scalar) {
  1175. return this.multiplyScalar(1 / scalar);
  1176. }
  1177. applyMatrix3(m) {
  1178. const x = this.x,
  1179. y = this.y;
  1180. const e = m.elements;
  1181. this.x = e[0] * x + e[3] * y + e[6];
  1182. this.y = e[1] * x + e[4] * y + e[7];
  1183. return this;
  1184. }
  1185. min(v) {
  1186. this.x = Math.min(this.x, v.x);
  1187. this.y = Math.min(this.y, v.y);
  1188. return this;
  1189. }
  1190. max(v) {
  1191. this.x = Math.max(this.x, v.x);
  1192. this.y = Math.max(this.y, v.y);
  1193. return this;
  1194. }
  1195. clamp(min, max) {
  1196. // assumes min < max, componentwise
  1197. this.x = Math.max(min.x, Math.min(max.x, this.x));
  1198. this.y = Math.max(min.y, Math.min(max.y, this.y));
  1199. return this;
  1200. }
  1201. clampScalar(minVal, maxVal) {
  1202. this.x = Math.max(minVal, Math.min(maxVal, this.x));
  1203. this.y = Math.max(minVal, Math.min(maxVal, this.y));
  1204. return this;
  1205. }
  1206. clampLength(min, max) {
  1207. const length = this.length();
  1208. return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
  1209. }
  1210. floor() {
  1211. this.x = Math.floor(this.x);
  1212. this.y = Math.floor(this.y);
  1213. return this;
  1214. }
  1215. ceil() {
  1216. this.x = Math.ceil(this.x);
  1217. this.y = Math.ceil(this.y);
  1218. return this;
  1219. }
  1220. round() {
  1221. this.x = Math.round(this.x);
  1222. this.y = Math.round(this.y);
  1223. return this;
  1224. }
  1225. roundToZero() {
  1226. this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
  1227. this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
  1228. return this;
  1229. }
  1230. negate() {
  1231. this.x = -this.x;
  1232. this.y = -this.y;
  1233. return this;
  1234. }
  1235. dot(v) {
  1236. return this.x * v.x + this.y * v.y;
  1237. }
  1238. cross(v) {
  1239. return this.x * v.y - this.y * v.x;
  1240. }
  1241. lengthSq() {
  1242. return this.x * this.x + this.y * this.y;
  1243. }
  1244. length() {
  1245. return Math.sqrt(this.x * this.x + this.y * this.y);
  1246. }
  1247. manhattanLength() {
  1248. return Math.abs(this.x) + Math.abs(this.y);
  1249. }
  1250. normalize() {
  1251. return this.divideScalar(this.length() || 1);
  1252. }
  1253. angle() {
  1254. // computes the angle in radians with respect to the positive x-axis
  1255. const angle = Math.atan2(-this.y, -this.x) + Math.PI;
  1256. return angle;
  1257. }
  1258. distanceTo(v) {
  1259. return Math.sqrt(this.distanceToSquared(v));
  1260. }
  1261. distanceToSquared(v) {
  1262. const dx = this.x - v.x,
  1263. dy = this.y - v.y;
  1264. return dx * dx + dy * dy;
  1265. }
  1266. manhattanDistanceTo(v) {
  1267. return Math.abs(this.x - v.x) + Math.abs(this.y - v.y);
  1268. }
  1269. setLength(length) {
  1270. return this.normalize().multiplyScalar(length);
  1271. }
  1272. lerp(v, alpha) {
  1273. this.x += (v.x - this.x) * alpha;
  1274. this.y += (v.y - this.y) * alpha;
  1275. return this;
  1276. }
  1277. lerpVectors(v1, v2, alpha) {
  1278. this.x = v1.x + (v2.x - v1.x) * alpha;
  1279. this.y = v1.y + (v2.y - v1.y) * alpha;
  1280. return this;
  1281. }
  1282. equals(v) {
  1283. return v.x === this.x && v.y === this.y;
  1284. }
  1285. fromArray(array, offset = 0) {
  1286. this.x = array[offset];
  1287. this.y = array[offset + 1];
  1288. return this;
  1289. }
  1290. toArray(array = [], offset = 0) {
  1291. array[offset] = this.x;
  1292. array[offset + 1] = this.y;
  1293. return array;
  1294. }
  1295. fromBufferAttribute(attribute, index) {
  1296. this.x = attribute.getX(index);
  1297. this.y = attribute.getY(index);
  1298. return this;
  1299. }
  1300. rotateAround(center, angle) {
  1301. const c = Math.cos(angle),
  1302. s = Math.sin(angle);
  1303. const x = this.x - center.x;
  1304. const y = this.y - center.y;
  1305. this.x = x * c - y * s + center.x;
  1306. this.y = x * s + y * c + center.y;
  1307. return this;
  1308. }
  1309. random() {
  1310. this.x = Math.random();
  1311. this.y = Math.random();
  1312. return this;
  1313. }
  1314. *[Symbol.iterator]() {
  1315. yield this.x;
  1316. yield this.y;
  1317. }
  1318. }
  1319. class Matrix3 {
  1320. constructor() {
  1321. Matrix3.prototype.isMatrix3 = true;
  1322. this.elements = [1, 0, 0, 0, 1, 0, 0, 0, 1];
  1323. }
  1324. set(n11, n12, n13, n21, n22, n23, n31, n32, n33) {
  1325. const te = this.elements;
  1326. te[0] = n11;
  1327. te[1] = n21;
  1328. te[2] = n31;
  1329. te[3] = n12;
  1330. te[4] = n22;
  1331. te[5] = n32;
  1332. te[6] = n13;
  1333. te[7] = n23;
  1334. te[8] = n33;
  1335. return this;
  1336. }
  1337. identity() {
  1338. this.set(1, 0, 0, 0, 1, 0, 0, 0, 1);
  1339. return this;
  1340. }
  1341. copy(m) {
  1342. const te = this.elements;
  1343. const me = m.elements;
  1344. te[0] = me[0];
  1345. te[1] = me[1];
  1346. te[2] = me[2];
  1347. te[3] = me[3];
  1348. te[4] = me[4];
  1349. te[5] = me[5];
  1350. te[6] = me[6];
  1351. te[7] = me[7];
  1352. te[8] = me[8];
  1353. return this;
  1354. }
  1355. extractBasis(xAxis, yAxis, zAxis) {
  1356. xAxis.setFromMatrix3Column(this, 0);
  1357. yAxis.setFromMatrix3Column(this, 1);
  1358. zAxis.setFromMatrix3Column(this, 2);
  1359. return this;
  1360. }
  1361. setFromMatrix4(m) {
  1362. const me = m.elements;
  1363. this.set(me[0], me[4], me[8], me[1], me[5], me[9], me[2], me[6], me[10]);
  1364. return this;
  1365. }
  1366. multiply(m) {
  1367. return this.multiplyMatrices(this, m);
  1368. }
  1369. premultiply(m) {
  1370. return this.multiplyMatrices(m, this);
  1371. }
  1372. multiplyMatrices(a, b) {
  1373. const ae = a.elements;
  1374. const be = b.elements;
  1375. const te = this.elements;
  1376. const a11 = ae[0],
  1377. a12 = ae[3],
  1378. a13 = ae[6];
  1379. const a21 = ae[1],
  1380. a22 = ae[4],
  1381. a23 = ae[7];
  1382. const a31 = ae[2],
  1383. a32 = ae[5],
  1384. a33 = ae[8];
  1385. const b11 = be[0],
  1386. b12 = be[3],
  1387. b13 = be[6];
  1388. const b21 = be[1],
  1389. b22 = be[4],
  1390. b23 = be[7];
  1391. const b31 = be[2],
  1392. b32 = be[5],
  1393. b33 = be[8];
  1394. te[0] = a11 * b11 + a12 * b21 + a13 * b31;
  1395. te[3] = a11 * b12 + a12 * b22 + a13 * b32;
  1396. te[6] = a11 * b13 + a12 * b23 + a13 * b33;
  1397. te[1] = a21 * b11 + a22 * b21 + a23 * b31;
  1398. te[4] = a21 * b12 + a22 * b22 + a23 * b32;
  1399. te[7] = a21 * b13 + a22 * b23 + a23 * b33;
  1400. te[2] = a31 * b11 + a32 * b21 + a33 * b31;
  1401. te[5] = a31 * b12 + a32 * b22 + a33 * b32;
  1402. te[8] = a31 * b13 + a32 * b23 + a33 * b33;
  1403. return this;
  1404. }
  1405. multiplyScalar(s) {
  1406. const te = this.elements;
  1407. te[0] *= s;
  1408. te[3] *= s;
  1409. te[6] *= s;
  1410. te[1] *= s;
  1411. te[4] *= s;
  1412. te[7] *= s;
  1413. te[2] *= s;
  1414. te[5] *= s;
  1415. te[8] *= s;
  1416. return this;
  1417. }
  1418. determinant() {
  1419. const te = this.elements;
  1420. const a = te[0],
  1421. b = te[1],
  1422. c = te[2],
  1423. d = te[3],
  1424. e = te[4],
  1425. f = te[5],
  1426. g = te[6],
  1427. h = te[7],
  1428. i = te[8];
  1429. return a * e * i - a * f * h - b * d * i + b * f * g + c * d * h - c * e * g;
  1430. }
  1431. invert() {
  1432. const te = this.elements,
  1433. n11 = te[0],
  1434. n21 = te[1],
  1435. n31 = te[2],
  1436. n12 = te[3],
  1437. n22 = te[4],
  1438. n32 = te[5],
  1439. n13 = te[6],
  1440. n23 = te[7],
  1441. n33 = te[8],
  1442. t11 = n33 * n22 - n32 * n23,
  1443. t12 = n32 * n13 - n33 * n12,
  1444. t13 = n23 * n12 - n22 * n13,
  1445. det = n11 * t11 + n21 * t12 + n31 * t13;
  1446. if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0);
  1447. const detInv = 1 / det;
  1448. te[0] = t11 * detInv;
  1449. te[1] = (n31 * n23 - n33 * n21) * detInv;
  1450. te[2] = (n32 * n21 - n31 * n22) * detInv;
  1451. te[3] = t12 * detInv;
  1452. te[4] = (n33 * n11 - n31 * n13) * detInv;
  1453. te[5] = (n31 * n12 - n32 * n11) * detInv;
  1454. te[6] = t13 * detInv;
  1455. te[7] = (n21 * n13 - n23 * n11) * detInv;
  1456. te[8] = (n22 * n11 - n21 * n12) * detInv;
  1457. return this;
  1458. }
  1459. transpose() {
  1460. let tmp;
  1461. const m = this.elements;
  1462. tmp = m[1];
  1463. m[1] = m[3];
  1464. m[3] = tmp;
  1465. tmp = m[2];
  1466. m[2] = m[6];
  1467. m[6] = tmp;
  1468. tmp = m[5];
  1469. m[5] = m[7];
  1470. m[7] = tmp;
  1471. return this;
  1472. }
  1473. getNormalMatrix(matrix4) {
  1474. return this.setFromMatrix4(matrix4).invert().transpose();
  1475. }
  1476. transposeIntoArray(r) {
  1477. const m = this.elements;
  1478. r[0] = m[0];
  1479. r[1] = m[3];
  1480. r[2] = m[6];
  1481. r[3] = m[1];
  1482. r[4] = m[4];
  1483. r[5] = m[7];
  1484. r[6] = m[2];
  1485. r[7] = m[5];
  1486. r[8] = m[8];
  1487. return this;
  1488. }
  1489. setUvTransform(tx, ty, sx, sy, rotation, cx, cy) {
  1490. const c = Math.cos(rotation);
  1491. const s = Math.sin(rotation);
  1492. this.set(sx * c, sx * s, -sx * (c * cx + s * cy) + cx + tx, -sy * s, sy * c, -sy * (-s * cx + c * cy) + cy + ty, 0, 0, 1);
  1493. return this;
  1494. }
  1495. scale(sx, sy) {
  1496. const te = this.elements;
  1497. te[0] *= sx;
  1498. te[3] *= sx;
  1499. te[6] *= sx;
  1500. te[1] *= sy;
  1501. te[4] *= sy;
  1502. te[7] *= sy;
  1503. return this;
  1504. }
  1505. rotate(theta) {
  1506. const c = Math.cos(theta);
  1507. const s = Math.sin(theta);
  1508. const te = this.elements;
  1509. const a11 = te[0],
  1510. a12 = te[3],
  1511. a13 = te[6];
  1512. const a21 = te[1],
  1513. a22 = te[4],
  1514. a23 = te[7];
  1515. te[0] = c * a11 + s * a21;
  1516. te[3] = c * a12 + s * a22;
  1517. te[6] = c * a13 + s * a23;
  1518. te[1] = -s * a11 + c * a21;
  1519. te[4] = -s * a12 + c * a22;
  1520. te[7] = -s * a13 + c * a23;
  1521. return this;
  1522. }
  1523. translate(tx, ty) {
  1524. const te = this.elements;
  1525. te[0] += tx * te[2];
  1526. te[3] += tx * te[5];
  1527. te[6] += tx * te[8];
  1528. te[1] += ty * te[2];
  1529. te[4] += ty * te[5];
  1530. te[7] += ty * te[8];
  1531. return this;
  1532. }
  1533. equals(matrix) {
  1534. const te = this.elements;
  1535. const me = matrix.elements;
  1536. for (let i = 0; i < 9; i++) {
  1537. if (te[i] !== me[i]) return false;
  1538. }
  1539. return true;
  1540. }
  1541. fromArray(array, offset = 0) {
  1542. for (let i = 0; i < 9; i++) {
  1543. this.elements[i] = array[i + offset];
  1544. }
  1545. return this;
  1546. }
  1547. toArray(array = [], offset = 0) {
  1548. const te = this.elements;
  1549. array[offset] = te[0];
  1550. array[offset + 1] = te[1];
  1551. array[offset + 2] = te[2];
  1552. array[offset + 3] = te[3];
  1553. array[offset + 4] = te[4];
  1554. array[offset + 5] = te[5];
  1555. array[offset + 6] = te[6];
  1556. array[offset + 7] = te[7];
  1557. array[offset + 8] = te[8];
  1558. return array;
  1559. }
  1560. clone() {
  1561. return new this.constructor().fromArray(this.elements);
  1562. }
  1563. }
  1564. function arrayNeedsUint32(array) {
  1565. // assumes larger values usually on last
  1566. for (let i = array.length - 1; i >= 0; --i) {
  1567. if (array[i] > 65535) return true;
  1568. }
  1569. return false;
  1570. }
  1571. const TYPED_ARRAYS = {
  1572. Int8Array: Int8Array,
  1573. Uint8Array: Uint8Array,
  1574. Uint8ClampedArray: Uint8ClampedArray,
  1575. Int16Array: Int16Array,
  1576. Uint16Array: Uint16Array,
  1577. Int32Array: Int32Array,
  1578. Uint32Array: Uint32Array,
  1579. Float32Array: Float32Array,
  1580. Float64Array: Float64Array
  1581. };
  1582. function getTypedArray(type, buffer) {
  1583. return new TYPED_ARRAYS[type](buffer);
  1584. }
  1585. function createElementNS(name) {
  1586. return document.createElementNS('http://www.w3.org/1999/xhtml', name);
  1587. }
  1588. function SRGBToLinear(c) {
  1589. return c < 0.04045 ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
  1590. }
  1591. function LinearToSRGB(c) {
  1592. return c < 0.0031308 ? c * 12.92 : 1.055 * Math.pow(c, 0.41666) - 0.055;
  1593. } // JavaScript RGB-to-RGB transforms, defined as
  1594. // FN[InputColorSpace][OutputColorSpace] callback functions.
  1595. const FN = {
  1596. [SRGBColorSpace]: {
  1597. [LinearSRGBColorSpace]: SRGBToLinear
  1598. },
  1599. [LinearSRGBColorSpace]: {
  1600. [SRGBColorSpace]: LinearToSRGB
  1601. }
  1602. };
  1603. const ColorManagement = {
  1604. legacyMode: true,
  1605. get workingColorSpace() {
  1606. return LinearSRGBColorSpace;
  1607. },
  1608. set workingColorSpace(colorSpace) {
  1609. console.warn('THREE.ColorManagement: .workingColorSpace is readonly.');
  1610. },
  1611. convert: function (color, sourceColorSpace, targetColorSpace) {
  1612. if (this.legacyMode || sourceColorSpace === targetColorSpace || !sourceColorSpace || !targetColorSpace) {
  1613. return color;
  1614. }
  1615. if (FN[sourceColorSpace] && FN[sourceColorSpace][targetColorSpace] !== undefined) {
  1616. const fn = FN[sourceColorSpace][targetColorSpace];
  1617. color.r = fn(color.r);
  1618. color.g = fn(color.g);
  1619. color.b = fn(color.b);
  1620. return color;
  1621. }
  1622. throw new Error('Unsupported color space conversion.');
  1623. },
  1624. fromWorkingColorSpace: function (color, targetColorSpace) {
  1625. return this.convert(color, this.workingColorSpace, targetColorSpace);
  1626. },
  1627. toWorkingColorSpace: function (color, sourceColorSpace) {
  1628. return this.convert(color, sourceColorSpace, this.workingColorSpace);
  1629. }
  1630. };
  1631. const _colorKeywords = {
  1632. 'aliceblue': 0xF0F8FF,
  1633. 'antiquewhite': 0xFAEBD7,
  1634. 'aqua': 0x00FFFF,
  1635. 'aquamarine': 0x7FFFD4,
  1636. 'azure': 0xF0FFFF,
  1637. 'beige': 0xF5F5DC,
  1638. 'bisque': 0xFFE4C4,
  1639. 'black': 0x000000,
  1640. 'blanchedalmond': 0xFFEBCD,
  1641. 'blue': 0x0000FF,
  1642. 'blueviolet': 0x8A2BE2,
  1643. 'brown': 0xA52A2A,
  1644. 'burlywood': 0xDEB887,
  1645. 'cadetblue': 0x5F9EA0,
  1646. 'chartreuse': 0x7FFF00,
  1647. 'chocolate': 0xD2691E,
  1648. 'coral': 0xFF7F50,
  1649. 'cornflowerblue': 0x6495ED,
  1650. 'cornsilk': 0xFFF8DC,
  1651. 'crimson': 0xDC143C,
  1652. 'cyan': 0x00FFFF,
  1653. 'darkblue': 0x00008B,
  1654. 'darkcyan': 0x008B8B,
  1655. 'darkgoldenrod': 0xB8860B,
  1656. 'darkgray': 0xA9A9A9,
  1657. 'darkgreen': 0x006400,
  1658. 'darkgrey': 0xA9A9A9,
  1659. 'darkkhaki': 0xBDB76B,
  1660. 'darkmagenta': 0x8B008B,
  1661. 'darkolivegreen': 0x556B2F,
  1662. 'darkorange': 0xFF8C00,
  1663. 'darkorchid': 0x9932CC,
  1664. 'darkred': 0x8B0000,
  1665. 'darksalmon': 0xE9967A,
  1666. 'darkseagreen': 0x8FBC8F,
  1667. 'darkslateblue': 0x483D8B,
  1668. 'darkslategray': 0x2F4F4F,
  1669. 'darkslategrey': 0x2F4F4F,
  1670. 'darkturquoise': 0x00CED1,
  1671. 'darkviolet': 0x9400D3,
  1672. 'deeppink': 0xFF1493,
  1673. 'deepskyblue': 0x00BFFF,
  1674. 'dimgray': 0x696969,
  1675. 'dimgrey': 0x696969,
  1676. 'dodgerblue': 0x1E90FF,
  1677. 'firebrick': 0xB22222,
  1678. 'floralwhite': 0xFFFAF0,
  1679. 'forestgreen': 0x228B22,
  1680. 'fuchsia': 0xFF00FF,
  1681. 'gainsboro': 0xDCDCDC,
  1682. 'ghostwhite': 0xF8F8FF,
  1683. 'gold': 0xFFD700,
  1684. 'goldenrod': 0xDAA520,
  1685. 'gray': 0x808080,
  1686. 'green': 0x008000,
  1687. 'greenyellow': 0xADFF2F,
  1688. 'grey': 0x808080,
  1689. 'honeydew': 0xF0FFF0,
  1690. 'hotpink': 0xFF69B4,
  1691. 'indianred': 0xCD5C5C,
  1692. 'indigo': 0x4B0082,
  1693. 'ivory': 0xFFFFF0,
  1694. 'khaki': 0xF0E68C,
  1695. 'lavender': 0xE6E6FA,
  1696. 'lavenderblush': 0xFFF0F5,
  1697. 'lawngreen': 0x7CFC00,
  1698. 'lemonchiffon': 0xFFFACD,
  1699. 'lightblue': 0xADD8E6,
  1700. 'lightcoral': 0xF08080,
  1701. 'lightcyan': 0xE0FFFF,
  1702. 'lightgoldenrodyellow': 0xFAFAD2,
  1703. 'lightgray': 0xD3D3D3,
  1704. 'lightgreen': 0x90EE90,
  1705. 'lightgrey': 0xD3D3D3,
  1706. 'lightpink': 0xFFB6C1,
  1707. 'lightsalmon': 0xFFA07A,
  1708. 'lightseagreen': 0x20B2AA,
  1709. 'lightskyblue': 0x87CEFA,
  1710. 'lightslategray': 0x778899,
  1711. 'lightslategrey': 0x778899,
  1712. 'lightsteelblue': 0xB0C4DE,
  1713. 'lightyellow': 0xFFFFE0,
  1714. 'lime': 0x00FF00,
  1715. 'limegreen': 0x32CD32,
  1716. 'linen': 0xFAF0E6,
  1717. 'magenta': 0xFF00FF,
  1718. 'maroon': 0x800000,
  1719. 'mediumaquamarine': 0x66CDAA,
  1720. 'mediumblue': 0x0000CD,
  1721. 'mediumorchid': 0xBA55D3,
  1722. 'mediumpurple': 0x9370DB,
  1723. 'mediumseagreen': 0x3CB371,
  1724. 'mediumslateblue': 0x7B68EE,
  1725. 'mediumspringgreen': 0x00FA9A,
  1726. 'mediumturquoise': 0x48D1CC,
  1727. 'mediumvioletred': 0xC71585,
  1728. 'midnightblue': 0x191970,
  1729. 'mintcream': 0xF5FFFA,
  1730. 'mistyrose': 0xFFE4E1,
  1731. 'moccasin': 0xFFE4B5,
  1732. 'navajowhite': 0xFFDEAD,
  1733. 'navy': 0x000080,
  1734. 'oldlace': 0xFDF5E6,
  1735. 'olive': 0x808000,
  1736. 'olivedrab': 0x6B8E23,
  1737. 'orange': 0xFFA500,
  1738. 'orangered': 0xFF4500,
  1739. 'orchid': 0xDA70D6,
  1740. 'palegoldenrod': 0xEEE8AA,
  1741. 'palegreen': 0x98FB98,
  1742. 'paleturquoise': 0xAFEEEE,
  1743. 'palevioletred': 0xDB7093,
  1744. 'papayawhip': 0xFFEFD5,
  1745. 'peachpuff': 0xFFDAB9,
  1746. 'peru': 0xCD853F,
  1747. 'pink': 0xFFC0CB,
  1748. 'plum': 0xDDA0DD,
  1749. 'powderblue': 0xB0E0E6,
  1750. 'purple': 0x800080,
  1751. 'rebeccapurple': 0x663399,
  1752. 'red': 0xFF0000,
  1753. 'rosybrown': 0xBC8F8F,
  1754. 'royalblue': 0x4169E1,
  1755. 'saddlebrown': 0x8B4513,
  1756. 'salmon': 0xFA8072,
  1757. 'sandybrown': 0xF4A460,
  1758. 'seagreen': 0x2E8B57,
  1759. 'seashell': 0xFFF5EE,
  1760. 'sienna': 0xA0522D,
  1761. 'silver': 0xC0C0C0,
  1762. 'skyblue': 0x87CEEB,
  1763. 'slateblue': 0x6A5ACD,
  1764. 'slategray': 0x708090,
  1765. 'slategrey': 0x708090,
  1766. 'snow': 0xFFFAFA,
  1767. 'springgreen': 0x00FF7F,
  1768. 'steelblue': 0x4682B4,
  1769. 'tan': 0xD2B48C,
  1770. 'teal': 0x008080,
  1771. 'thistle': 0xD8BFD8,
  1772. 'tomato': 0xFF6347,
  1773. 'turquoise': 0x40E0D0,
  1774. 'violet': 0xEE82EE,
  1775. 'wheat': 0xF5DEB3,
  1776. 'white': 0xFFFFFF,
  1777. 'whitesmoke': 0xF5F5F5,
  1778. 'yellow': 0xFFFF00,
  1779. 'yellowgreen': 0x9ACD32
  1780. };
  1781. const _rgb = {
  1782. r: 0,
  1783. g: 0,
  1784. b: 0
  1785. };
  1786. const _hslA = {
  1787. h: 0,
  1788. s: 0,
  1789. l: 0
  1790. };
  1791. const _hslB = {
  1792. h: 0,
  1793. s: 0,
  1794. l: 0
  1795. };
  1796. function hue2rgb(p, q, t) {
  1797. if (t < 0) t += 1;
  1798. if (t > 1) t -= 1;
  1799. if (t < 1 / 6) return p + (q - p) * 6 * t;
  1800. if (t < 1 / 2) return q;
  1801. if (t < 2 / 3) return p + (q - p) * 6 * (2 / 3 - t);
  1802. return p;
  1803. }
  1804. function toComponents(source, target) {
  1805. target.r = source.r;
  1806. target.g = source.g;
  1807. target.b = source.b;
  1808. return target;
  1809. }
  1810. class Color {
  1811. constructor(r, g, b) {
  1812. this.isColor = true;
  1813. this.r = 1;
  1814. this.g = 1;
  1815. this.b = 1;
  1816. if (g === undefined && b === undefined) {
  1817. // r is THREE.Color, hex or string
  1818. return this.set(r);
  1819. }
  1820. return this.setRGB(r, g, b);
  1821. }
  1822. set(value) {
  1823. if (value && value.isColor) {
  1824. this.copy(value);
  1825. } else if (typeof value === 'number') {
  1826. this.setHex(value);
  1827. } else if (typeof value === 'string') {
  1828. this.setStyle(value);
  1829. }
  1830. return this;
  1831. }
  1832. setScalar(scalar) {
  1833. this.r = scalar;
  1834. this.g = scalar;
  1835. this.b = scalar;
  1836. return this;
  1837. }
  1838. setHex(hex, colorSpace = SRGBColorSpace) {
  1839. hex = Math.floor(hex);
  1840. this.r = (hex >> 16 & 255) / 255;
  1841. this.g = (hex >> 8 & 255) / 255;
  1842. this.b = (hex & 255) / 255;
  1843. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1844. return this;
  1845. }
  1846. setRGB(r, g, b, colorSpace = LinearSRGBColorSpace) {
  1847. this.r = r;
  1848. this.g = g;
  1849. this.b = b;
  1850. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1851. return this;
  1852. }
  1853. setHSL(h, s, l, colorSpace = LinearSRGBColorSpace) {
  1854. // h,s,l ranges are in 0.0 - 1.0
  1855. h = euclideanModulo(h, 1);
  1856. s = clamp(s, 0, 1);
  1857. l = clamp(l, 0, 1);
  1858. if (s === 0) {
  1859. this.r = this.g = this.b = l;
  1860. } else {
  1861. const p = l <= 0.5 ? l * (1 + s) : l + s - l * s;
  1862. const q = 2 * l - p;
  1863. this.r = hue2rgb(q, p, h + 1 / 3);
  1864. this.g = hue2rgb(q, p, h);
  1865. this.b = hue2rgb(q, p, h - 1 / 3);
  1866. }
  1867. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1868. return this;
  1869. }
  1870. setStyle(style, colorSpace = SRGBColorSpace) {
  1871. function handleAlpha(string) {
  1872. if (string === undefined) return;
  1873. if (parseFloat(string) < 1) {
  1874. console.warn('THREE.Color: Alpha component of ' + style + ' will be ignored.');
  1875. }
  1876. }
  1877. let m;
  1878. if (m = /^((?:rgb|hsl)a?)\(([^\)]*)\)/.exec(style)) {
  1879. // rgb / hsl
  1880. let color;
  1881. const name = m[1];
  1882. const components = m[2];
  1883. switch (name) {
  1884. case 'rgb':
  1885. case 'rgba':
  1886. if (color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
  1887. // rgb(255,0,0) rgba(255,0,0,0.5)
  1888. this.r = Math.min(255, parseInt(color[1], 10)) / 255;
  1889. this.g = Math.min(255, parseInt(color[2], 10)) / 255;
  1890. this.b = Math.min(255, parseInt(color[3], 10)) / 255;
  1891. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1892. handleAlpha(color[4]);
  1893. return this;
  1894. }
  1895. if (color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
  1896. // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5)
  1897. this.r = Math.min(100, parseInt(color[1], 10)) / 100;
  1898. this.g = Math.min(100, parseInt(color[2], 10)) / 100;
  1899. this.b = Math.min(100, parseInt(color[3], 10)) / 100;
  1900. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1901. handleAlpha(color[4]);
  1902. return this;
  1903. }
  1904. break;
  1905. case 'hsl':
  1906. case 'hsla':
  1907. if (color = /^\s*(\d*\.?\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(components)) {
  1908. // hsl(120,50%,50%) hsla(120,50%,50%,0.5)
  1909. const h = parseFloat(color[1]) / 360;
  1910. const s = parseInt(color[2], 10) / 100;
  1911. const l = parseInt(color[3], 10) / 100;
  1912. handleAlpha(color[4]);
  1913. return this.setHSL(h, s, l, colorSpace);
  1914. }
  1915. break;
  1916. }
  1917. } else if (m = /^\#([A-Fa-f\d]+)$/.exec(style)) {
  1918. // hex color
  1919. const hex = m[1];
  1920. const size = hex.length;
  1921. if (size === 3) {
  1922. // #ff0
  1923. this.r = parseInt(hex.charAt(0) + hex.charAt(0), 16) / 255;
  1924. this.g = parseInt(hex.charAt(1) + hex.charAt(1), 16) / 255;
  1925. this.b = parseInt(hex.charAt(2) + hex.charAt(2), 16) / 255;
  1926. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1927. return this;
  1928. } else if (size === 6) {
  1929. // #ff0000
  1930. this.r = parseInt(hex.charAt(0) + hex.charAt(1), 16) / 255;
  1931. this.g = parseInt(hex.charAt(2) + hex.charAt(3), 16) / 255;
  1932. this.b = parseInt(hex.charAt(4) + hex.charAt(5), 16) / 255;
  1933. ColorManagement.toWorkingColorSpace(this, colorSpace);
  1934. return this;
  1935. }
  1936. }
  1937. if (style && style.length > 0) {
  1938. return this.setColorName(style, colorSpace);
  1939. }
  1940. return this;
  1941. }
  1942. setColorName(style, colorSpace = SRGBColorSpace) {
  1943. // color keywords
  1944. const hex = _colorKeywords[style.toLowerCase()];
  1945. if (hex !== undefined) {
  1946. // red
  1947. this.setHex(hex, colorSpace);
  1948. } else {
  1949. // unknown color
  1950. console.warn('THREE.Color: Unknown color ' + style);
  1951. }
  1952. return this;
  1953. }
  1954. clone() {
  1955. return new this.constructor(this.r, this.g, this.b);
  1956. }
  1957. copy(color) {
  1958. this.r = color.r;
  1959. this.g = color.g;
  1960. this.b = color.b;
  1961. return this;
  1962. }
  1963. copySRGBToLinear(color) {
  1964. this.r = SRGBToLinear(color.r);
  1965. this.g = SRGBToLinear(color.g);
  1966. this.b = SRGBToLinear(color.b);
  1967. return this;
  1968. }
  1969. copyLinearToSRGB(color) {
  1970. this.r = LinearToSRGB(color.r);
  1971. this.g = LinearToSRGB(color.g);
  1972. this.b = LinearToSRGB(color.b);
  1973. return this;
  1974. }
  1975. convertSRGBToLinear() {
  1976. this.copySRGBToLinear(this);
  1977. return this;
  1978. }
  1979. convertLinearToSRGB() {
  1980. this.copyLinearToSRGB(this);
  1981. return this;
  1982. }
  1983. getHex(colorSpace = SRGBColorSpace) {
  1984. ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace);
  1985. return clamp(_rgb.r * 255, 0, 255) << 16 ^ clamp(_rgb.g * 255, 0, 255) << 8 ^ clamp(_rgb.b * 255, 0, 255) << 0;
  1986. }
  1987. getHexString(colorSpace = SRGBColorSpace) {
  1988. return ('000000' + this.getHex(colorSpace).toString(16)).slice(-6);
  1989. }
  1990. getHSL(target, colorSpace = LinearSRGBColorSpace) {
  1991. // h,s,l ranges are in 0.0 - 1.0
  1992. ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace);
  1993. const r = _rgb.r,
  1994. g = _rgb.g,
  1995. b = _rgb.b;
  1996. const max = Math.max(r, g, b);
  1997. const min = Math.min(r, g, b);
  1998. let hue, saturation;
  1999. const lightness = (min + max) / 2.0;
  2000. if (min === max) {
  2001. hue = 0;
  2002. saturation = 0;
  2003. } else {
  2004. const delta = max - min;
  2005. saturation = lightness <= 0.5 ? delta / (max + min) : delta / (2 - max - min);
  2006. switch (max) {
  2007. case r:
  2008. hue = (g - b) / delta + (g < b ? 6 : 0);
  2009. break;
  2010. case g:
  2011. hue = (b - r) / delta + 2;
  2012. break;
  2013. case b:
  2014. hue = (r - g) / delta + 4;
  2015. break;
  2016. }
  2017. hue /= 6;
  2018. }
  2019. target.h = hue;
  2020. target.s = saturation;
  2021. target.l = lightness;
  2022. return target;
  2023. }
  2024. getRGB(target, colorSpace = LinearSRGBColorSpace) {
  2025. ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace);
  2026. target.r = _rgb.r;
  2027. target.g = _rgb.g;
  2028. target.b = _rgb.b;
  2029. return target;
  2030. }
  2031. getStyle(colorSpace = SRGBColorSpace) {
  2032. ColorManagement.fromWorkingColorSpace(toComponents(this, _rgb), colorSpace);
  2033. if (colorSpace !== SRGBColorSpace) {
  2034. // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/).
  2035. return `color(${colorSpace} ${_rgb.r} ${_rgb.g} ${_rgb.b})`;
  2036. }
  2037. return `rgb(${_rgb.r * 255 | 0},${_rgb.g * 255 | 0},${_rgb.b * 255 | 0})`;
  2038. }
  2039. offsetHSL(h, s, l) {
  2040. this.getHSL(_hslA);
  2041. _hslA.h += h;
  2042. _hslA.s += s;
  2043. _hslA.l += l;
  2044. this.setHSL(_hslA.h, _hslA.s, _hslA.l);
  2045. return this;
  2046. }
  2047. add(color) {
  2048. this.r += color.r;
  2049. this.g += color.g;
  2050. this.b += color.b;
  2051. return this;
  2052. }
  2053. addColors(color1, color2) {
  2054. this.r = color1.r + color2.r;
  2055. this.g = color1.g + color2.g;
  2056. this.b = color1.b + color2.b;
  2057. return this;
  2058. }
  2059. addScalar(s) {
  2060. this.r += s;
  2061. this.g += s;
  2062. this.b += s;
  2063. return this;
  2064. }
  2065. sub(color) {
  2066. this.r = Math.max(0, this.r - color.r);
  2067. this.g = Math.max(0, this.g - color.g);
  2068. this.b = Math.max(0, this.b - color.b);
  2069. return this;
  2070. }
  2071. multiply(color) {
  2072. this.r *= color.r;
  2073. this.g *= color.g;
  2074. this.b *= color.b;
  2075. return this;
  2076. }
  2077. multiplyScalar(s) {
  2078. this.r *= s;
  2079. this.g *= s;
  2080. this.b *= s;
  2081. return this;
  2082. }
  2083. lerp(color, alpha) {
  2084. this.r += (color.r - this.r) * alpha;
  2085. this.g += (color.g - this.g) * alpha;
  2086. this.b += (color.b - this.b) * alpha;
  2087. return this;
  2088. }
  2089. lerpColors(color1, color2, alpha) {
  2090. this.r = color1.r + (color2.r - color1.r) * alpha;
  2091. this.g = color1.g + (color2.g - color1.g) * alpha;
  2092. this.b = color1.b + (color2.b - color1.b) * alpha;
  2093. return this;
  2094. }
  2095. lerpHSL(color, alpha) {
  2096. this.getHSL(_hslA);
  2097. color.getHSL(_hslB);
  2098. const h = lerp(_hslA.h, _hslB.h, alpha);
  2099. const s = lerp(_hslA.s, _hslB.s, alpha);
  2100. const l = lerp(_hslA.l, _hslB.l, alpha);
  2101. this.setHSL(h, s, l);
  2102. return this;
  2103. }
  2104. equals(c) {
  2105. return c.r === this.r && c.g === this.g && c.b === this.b;
  2106. }
  2107. fromArray(array, offset = 0) {
  2108. this.r = array[offset];
  2109. this.g = array[offset + 1];
  2110. this.b = array[offset + 2];
  2111. return this;
  2112. }
  2113. toArray(array = [], offset = 0) {
  2114. array[offset] = this.r;
  2115. array[offset + 1] = this.g;
  2116. array[offset + 2] = this.b;
  2117. return array;
  2118. }
  2119. fromBufferAttribute(attribute, index) {
  2120. this.r = attribute.getX(index);
  2121. this.g = attribute.getY(index);
  2122. this.b = attribute.getZ(index);
  2123. if (attribute.normalized === true) {
  2124. // assuming Uint8Array
  2125. this.r /= 255;
  2126. this.g /= 255;
  2127. this.b /= 255;
  2128. }
  2129. return this;
  2130. }
  2131. toJSON() {
  2132. return this.getHex();
  2133. }
  2134. *[Symbol.iterator]() {
  2135. yield this.r;
  2136. yield this.g;
  2137. yield this.b;
  2138. }
  2139. }
  2140. Color.NAMES = _colorKeywords;
  2141. let _canvas;
  2142. class ImageUtils {
  2143. static getDataURL(image) {
  2144. if (/^data:/i.test(image.src)) {
  2145. return image.src;
  2146. }
  2147. if (typeof HTMLCanvasElement == 'undefined') {
  2148. return image.src;
  2149. }
  2150. let canvas;
  2151. if (image instanceof HTMLCanvasElement) {
  2152. canvas = image;
  2153. } else {
  2154. if (_canvas === undefined) _canvas = createElementNS('canvas');
  2155. _canvas.width = image.width;
  2156. _canvas.height = image.height;
  2157. const context = _canvas.getContext('2d');
  2158. if (image instanceof ImageData) {
  2159. context.putImageData(image, 0, 0);
  2160. } else {
  2161. context.drawImage(image, 0, 0, image.width, image.height);
  2162. }
  2163. canvas = _canvas;
  2164. }
  2165. if (canvas.width > 2048 || canvas.height > 2048) {
  2166. console.warn('THREE.ImageUtils.getDataURL: Image converted to jpg for performance reasons', image);
  2167. return canvas.toDataURL('image/jpeg', 0.6);
  2168. } else {
  2169. return canvas.toDataURL('image/png');
  2170. }
  2171. }
  2172. static sRGBToLinear(image) {
  2173. if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
  2174. const canvas = createElementNS('canvas');
  2175. canvas.width = image.width;
  2176. canvas.height = image.height;
  2177. const context = canvas.getContext('2d');
  2178. context.drawImage(image, 0, 0, image.width, image.height);
  2179. const imageData = context.getImageData(0, 0, image.width, image.height);
  2180. const data = imageData.data;
  2181. for (let i = 0; i < data.length; i++) {
  2182. data[i] = SRGBToLinear(data[i] / 255) * 255;
  2183. }
  2184. context.putImageData(imageData, 0, 0);
  2185. return canvas;
  2186. } else if (image.data) {
  2187. const data = image.data.slice(0);
  2188. for (let i = 0; i < data.length; i++) {
  2189. if (data instanceof Uint8Array || data instanceof Uint8ClampedArray) {
  2190. data[i] = Math.floor(SRGBToLinear(data[i] / 255) * 255);
  2191. } else {
  2192. // assuming float
  2193. data[i] = SRGBToLinear(data[i]);
  2194. }
  2195. }
  2196. return {
  2197. data: data,
  2198. width: image.width,
  2199. height: image.height
  2200. };
  2201. } else {
  2202. console.warn('THREE.ImageUtils.sRGBToLinear(): Unsupported image type. No color space conversion applied.');
  2203. return image;
  2204. }
  2205. }
  2206. }
  2207. class Source {
  2208. constructor(data = null) {
  2209. this.isSource = true;
  2210. this.uuid = generateUUID();
  2211. this.data = data;
  2212. this.version = 0;
  2213. }
  2214. set needsUpdate(value) {
  2215. if (value === true) this.version++;
  2216. }
  2217. toJSON(meta) {
  2218. const isRootObject = meta === undefined || typeof meta === 'string';
  2219. if (!isRootObject && meta.images[this.uuid] !== undefined) {
  2220. return meta.images[this.uuid];
  2221. }
  2222. const output = {
  2223. uuid: this.uuid,
  2224. url: ''
  2225. };
  2226. const data = this.data;
  2227. if (data !== null) {
  2228. let url;
  2229. if (Array.isArray(data)) {
  2230. // cube texture
  2231. url = [];
  2232. for (let i = 0, l = data.length; i < l; i++) {
  2233. if (data[i].isDataTexture) {
  2234. url.push(serializeImage(data[i].image));
  2235. } else {
  2236. url.push(serializeImage(data[i]));
  2237. }
  2238. }
  2239. } else {
  2240. // texture
  2241. url = serializeImage(data);
  2242. }
  2243. output.url = url;
  2244. }
  2245. if (!isRootObject) {
  2246. meta.images[this.uuid] = output;
  2247. }
  2248. return output;
  2249. }
  2250. }
  2251. function serializeImage(image) {
  2252. if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
  2253. // default images
  2254. return ImageUtils.getDataURL(image);
  2255. } else {
  2256. if (image.data) {
  2257. // images of DataTexture
  2258. return {
  2259. data: Array.from(image.data),
  2260. width: image.width,
  2261. height: image.height,
  2262. type: image.data.constructor.name
  2263. };
  2264. } else {
  2265. console.warn('THREE.Texture: Unable to serialize Texture.');
  2266. return {};
  2267. }
  2268. }
  2269. }
  2270. let textureId = 0;
  2271. class Texture extends EventDispatcher {
  2272. constructor(image = Texture.DEFAULT_IMAGE, mapping = Texture.DEFAULT_MAPPING, wrapS = ClampToEdgeWrapping, wrapT = ClampToEdgeWrapping, magFilter = LinearFilter, minFilter = LinearMipmapLinearFilter, format = RGBAFormat, type = UnsignedByteType, anisotropy = 1, encoding = LinearEncoding) {
  2273. super();
  2274. this.isTexture = true;
  2275. Object.defineProperty(this, 'id', {
  2276. value: textureId++
  2277. });
  2278. this.uuid = generateUUID();
  2279. this.name = '';
  2280. this.source = new Source(image);
  2281. this.mipmaps = [];
  2282. this.mapping = mapping;
  2283. this.wrapS = wrapS;
  2284. this.wrapT = wrapT;
  2285. this.magFilter = magFilter;
  2286. this.minFilter = minFilter;
  2287. this.anisotropy = anisotropy;
  2288. this.format = format;
  2289. this.internalFormat = null;
  2290. this.type = type;
  2291. this.offset = new Vector2(0, 0);
  2292. this.repeat = new Vector2(1, 1);
  2293. this.center = new Vector2(0, 0);
  2294. this.rotation = 0;
  2295. this.matrixAutoUpdate = true;
  2296. this.matrix = new Matrix3();
  2297. this.generateMipmaps = true;
  2298. this.premultiplyAlpha = false;
  2299. this.flipY = true;
  2300. this.unpackAlignment = 4; // valid values: 1, 2, 4, 8 (see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glPixelStorei.xml)
  2301. // Values of encoding !== THREE.LinearEncoding only supported on map, envMap and emissiveMap.
  2302. //
  2303. // Also changing the encoding after already used by a Material will not automatically make the Material
  2304. // update. You need to explicitly call Material.needsUpdate to trigger it to recompile.
  2305. this.encoding = encoding;
  2306. this.userData = {};
  2307. this.version = 0;
  2308. this.onUpdate = null;
  2309. this.isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not
  2310. this.needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures)
  2311. }
  2312. get image() {
  2313. return this.source.data;
  2314. }
  2315. set image(value) {
  2316. this.source.data = value;
  2317. }
  2318. updateMatrix() {
  2319. this.matrix.setUvTransform(this.offset.x, this.offset.y, this.repeat.x, this.repeat.y, this.rotation, this.center.x, this.center.y);
  2320. }
  2321. clone() {
  2322. return new this.constructor().copy(this);
  2323. }
  2324. copy(source) {
  2325. this.name = source.name;
  2326. this.source = source.source;
  2327. this.mipmaps = source.mipmaps.slice(0);
  2328. this.mapping = source.mapping;
  2329. this.wrapS = source.wrapS;
  2330. this.wrapT = source.wrapT;
  2331. this.magFilter = source.magFilter;
  2332. this.minFilter = source.minFilter;
  2333. this.anisotropy = source.anisotropy;
  2334. this.format = source.format;
  2335. this.internalFormat = source.internalFormat;
  2336. this.type = source.type;
  2337. this.offset.copy(source.offset);
  2338. this.repeat.copy(source.repeat);
  2339. this.center.copy(source.center);
  2340. this.rotation = source.rotation;
  2341. this.matrixAutoUpdate = source.matrixAutoUpdate;
  2342. this.matrix.copy(source.matrix);
  2343. this.generateMipmaps = source.generateMipmaps;
  2344. this.premultiplyAlpha = source.premultiplyAlpha;
  2345. this.flipY = source.flipY;
  2346. this.unpackAlignment = source.unpackAlignment;
  2347. this.encoding = source.encoding;
  2348. this.userData = JSON.parse(JSON.stringify(source.userData));
  2349. this.needsUpdate = true;
  2350. return this;
  2351. }
  2352. toJSON(meta) {
  2353. const isRootObject = meta === undefined || typeof meta === 'string';
  2354. if (!isRootObject && meta.textures[this.uuid] !== undefined) {
  2355. return meta.textures[this.uuid];
  2356. }
  2357. const output = {
  2358. metadata: {
  2359. version: 4.5,
  2360. type: 'Texture',
  2361. generator: 'Texture.toJSON'
  2362. },
  2363. uuid: this.uuid,
  2364. name: this.name,
  2365. image: this.source.toJSON(meta).uuid,
  2366. mapping: this.mapping,
  2367. repeat: [this.repeat.x, this.repeat.y],
  2368. offset: [this.offset.x, this.offset.y],
  2369. center: [this.center.x, this.center.y],
  2370. rotation: this.rotation,
  2371. wrap: [this.wrapS, this.wrapT],
  2372. format: this.format,
  2373. type: this.type,
  2374. encoding: this.encoding,
  2375. minFilter: this.minFilter,
  2376. magFilter: this.magFilter,
  2377. anisotropy: this.anisotropy,
  2378. flipY: this.flipY,
  2379. premultiplyAlpha: this.premultiplyAlpha,
  2380. unpackAlignment: this.unpackAlignment
  2381. };
  2382. if (JSON.stringify(this.userData) !== '{}') output.userData = this.userData;
  2383. if (!isRootObject) {
  2384. meta.textures[this.uuid] = output;
  2385. }
  2386. return output;
  2387. }
  2388. dispose() {
  2389. this.dispatchEvent({
  2390. type: 'dispose'
  2391. });
  2392. }
  2393. transformUv(uv) {
  2394. if (this.mapping !== UVMapping) return uv;
  2395. uv.applyMatrix3(this.matrix);
  2396. if (uv.x < 0 || uv.x > 1) {
  2397. switch (this.wrapS) {
  2398. case RepeatWrapping:
  2399. uv.x = uv.x - Math.floor(uv.x);
  2400. break;
  2401. case ClampToEdgeWrapping:
  2402. uv.x = uv.x < 0 ? 0 : 1;
  2403. break;
  2404. case MirroredRepeatWrapping:
  2405. if (Math.abs(Math.floor(uv.x) % 2) === 1) {
  2406. uv.x = Math.ceil(uv.x) - uv.x;
  2407. } else {
  2408. uv.x = uv.x - Math.floor(uv.x);
  2409. }
  2410. break;
  2411. }
  2412. }
  2413. if (uv.y < 0 || uv.y > 1) {
  2414. switch (this.wrapT) {
  2415. case RepeatWrapping:
  2416. uv.y = uv.y - Math.floor(uv.y);
  2417. break;
  2418. case ClampToEdgeWrapping:
  2419. uv.y = uv.y < 0 ? 0 : 1;
  2420. break;
  2421. case MirroredRepeatWrapping:
  2422. if (Math.abs(Math.floor(uv.y) % 2) === 1) {
  2423. uv.y = Math.ceil(uv.y) - uv.y;
  2424. } else {
  2425. uv.y = uv.y - Math.floor(uv.y);
  2426. }
  2427. break;
  2428. }
  2429. }
  2430. if (this.flipY) {
  2431. uv.y = 1 - uv.y;
  2432. }
  2433. return uv;
  2434. }
  2435. set needsUpdate(value) {
  2436. if (value === true) {
  2437. this.version++;
  2438. this.source.needsUpdate = true;
  2439. }
  2440. }
  2441. }
  2442. Texture.DEFAULT_IMAGE = null;
  2443. Texture.DEFAULT_MAPPING = UVMapping;
  2444. class Vector4 {
  2445. constructor(x = 0, y = 0, z = 0, w = 1) {
  2446. Vector4.prototype.isVector4 = true;
  2447. this.x = x;
  2448. this.y = y;
  2449. this.z = z;
  2450. this.w = w;
  2451. }
  2452. get width() {
  2453. return this.z;
  2454. }
  2455. set width(value) {
  2456. this.z = value;
  2457. }
  2458. get height() {
  2459. return this.w;
  2460. }
  2461. set height(value) {
  2462. this.w = value;
  2463. }
  2464. set(x, y, z, w) {
  2465. this.x = x;
  2466. this.y = y;
  2467. this.z = z;
  2468. this.w = w;
  2469. return this;
  2470. }
  2471. setScalar(scalar) {
  2472. this.x = scalar;
  2473. this.y = scalar;
  2474. this.z = scalar;
  2475. this.w = scalar;
  2476. return this;
  2477. }
  2478. setX(x) {
  2479. this.x = x;
  2480. return this;
  2481. }
  2482. setY(y) {
  2483. this.y = y;
  2484. return this;
  2485. }
  2486. setZ(z) {
  2487. this.z = z;
  2488. return this;
  2489. }
  2490. setW(w) {
  2491. this.w = w;
  2492. return this;
  2493. }
  2494. setComponent(index, value) {
  2495. switch (index) {
  2496. case 0:
  2497. this.x = value;
  2498. break;
  2499. case 1:
  2500. this.y = value;
  2501. break;
  2502. case 2:
  2503. this.z = value;
  2504. break;
  2505. case 3:
  2506. this.w = value;
  2507. break;
  2508. default:
  2509. throw new Error('index is out of range: ' + index);
  2510. }
  2511. return this;
  2512. }
  2513. getComponent(index) {
  2514. switch (index) {
  2515. case 0:
  2516. return this.x;
  2517. case 1:
  2518. return this.y;
  2519. case 2:
  2520. return this.z;
  2521. case 3:
  2522. return this.w;
  2523. default:
  2524. throw new Error('index is out of range: ' + index);
  2525. }
  2526. }
  2527. clone() {
  2528. return new this.constructor(this.x, this.y, this.z, this.w);
  2529. }
  2530. copy(v) {
  2531. this.x = v.x;
  2532. this.y = v.y;
  2533. this.z = v.z;
  2534. this.w = v.w !== undefined ? v.w : 1;
  2535. return this;
  2536. }
  2537. add(v) {
  2538. this.x += v.x;
  2539. this.y += v.y;
  2540. this.z += v.z;
  2541. this.w += v.w;
  2542. return this;
  2543. }
  2544. addScalar(s) {
  2545. this.x += s;
  2546. this.y += s;
  2547. this.z += s;
  2548. this.w += s;
  2549. return this;
  2550. }
  2551. addVectors(a, b) {
  2552. this.x = a.x + b.x;
  2553. this.y = a.y + b.y;
  2554. this.z = a.z + b.z;
  2555. this.w = a.w + b.w;
  2556. return this;
  2557. }
  2558. addScaledVector(v, s) {
  2559. this.x += v.x * s;
  2560. this.y += v.y * s;
  2561. this.z += v.z * s;
  2562. this.w += v.w * s;
  2563. return this;
  2564. }
  2565. sub(v) {
  2566. this.x -= v.x;
  2567. this.y -= v.y;
  2568. this.z -= v.z;
  2569. this.w -= v.w;
  2570. return this;
  2571. }
  2572. subScalar(s) {
  2573. this.x -= s;
  2574. this.y -= s;
  2575. this.z -= s;
  2576. this.w -= s;
  2577. return this;
  2578. }
  2579. subVectors(a, b) {
  2580. this.x = a.x - b.x;
  2581. this.y = a.y - b.y;
  2582. this.z = a.z - b.z;
  2583. this.w = a.w - b.w;
  2584. return this;
  2585. }
  2586. multiply(v) {
  2587. this.x *= v.x;
  2588. this.y *= v.y;
  2589. this.z *= v.z;
  2590. this.w *= v.w;
  2591. return this;
  2592. }
  2593. multiplyScalar(scalar) {
  2594. this.x *= scalar;
  2595. this.y *= scalar;
  2596. this.z *= scalar;
  2597. this.w *= scalar;
  2598. return this;
  2599. }
  2600. applyMatrix4(m) {
  2601. const x = this.x,
  2602. y = this.y,
  2603. z = this.z,
  2604. w = this.w;
  2605. const e = m.elements;
  2606. this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
  2607. this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
  2608. this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
  2609. this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;
  2610. return this;
  2611. }
  2612. divideScalar(scalar) {
  2613. return this.multiplyScalar(1 / scalar);
  2614. }
  2615. setAxisAngleFromQuaternion(q) {
  2616. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
  2617. // q is assumed to be normalized
  2618. this.w = 2 * Math.acos(q.w);
  2619. const s = Math.sqrt(1 - q.w * q.w);
  2620. if (s < 0.0001) {
  2621. this.x = 1;
  2622. this.y = 0;
  2623. this.z = 0;
  2624. } else {
  2625. this.x = q.x / s;
  2626. this.y = q.y / s;
  2627. this.z = q.z / s;
  2628. }
  2629. return this;
  2630. }
  2631. setAxisAngleFromRotationMatrix(m) {
  2632. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
  2633. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  2634. let angle, x, y, z; // variables for result
  2635. const epsilon = 0.01,
  2636. // margin to allow for rounding errors
  2637. epsilon2 = 0.1,
  2638. // margin to distinguish between 0 and 180 degrees
  2639. te = m.elements,
  2640. m11 = te[0],
  2641. m12 = te[4],
  2642. m13 = te[8],
  2643. m21 = te[1],
  2644. m22 = te[5],
  2645. m23 = te[9],
  2646. m31 = te[2],
  2647. m32 = te[6],
  2648. m33 = te[10];
  2649. if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) {
  2650. // singularity found
  2651. // first check for identity matrix which must have +1 for all terms
  2652. // in leading diagonal and zero in other terms
  2653. if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) {
  2654. // this singularity is identity matrix so angle = 0
  2655. this.set(1, 0, 0, 0);
  2656. return this; // zero angle, arbitrary axis
  2657. } // otherwise this singularity is angle = 180
  2658. angle = Math.PI;
  2659. const xx = (m11 + 1) / 2;
  2660. const yy = (m22 + 1) / 2;
  2661. const zz = (m33 + 1) / 2;
  2662. const xy = (m12 + m21) / 4;
  2663. const xz = (m13 + m31) / 4;
  2664. const yz = (m23 + m32) / 4;
  2665. if (xx > yy && xx > zz) {
  2666. // m11 is the largest diagonal term
  2667. if (xx < epsilon) {
  2668. x = 0;
  2669. y = 0.707106781;
  2670. z = 0.707106781;
  2671. } else {
  2672. x = Math.sqrt(xx);
  2673. y = xy / x;
  2674. z = xz / x;
  2675. }
  2676. } else if (yy > zz) {
  2677. // m22 is the largest diagonal term
  2678. if (yy < epsilon) {
  2679. x = 0.707106781;
  2680. y = 0;
  2681. z = 0.707106781;
  2682. } else {
  2683. y = Math.sqrt(yy);
  2684. x = xy / y;
  2685. z = yz / y;
  2686. }
  2687. } else {
  2688. // m33 is the largest diagonal term so base result on this
  2689. if (zz < epsilon) {
  2690. x = 0.707106781;
  2691. y = 0.707106781;
  2692. z = 0;
  2693. } else {
  2694. z = Math.sqrt(zz);
  2695. x = xz / z;
  2696. y = yz / z;
  2697. }
  2698. }
  2699. this.set(x, y, z, angle);
  2700. return this; // return 180 deg rotation
  2701. } // as we have reached here there are no singularities so we can handle normally
  2702. let s = Math.sqrt((m32 - m23) * (m32 - m23) + (m13 - m31) * (m13 - m31) + (m21 - m12) * (m21 - m12)); // used to normalize
  2703. if (Math.abs(s) < 0.001) s = 1; // prevent divide by zero, should not happen if matrix is orthogonal and should be
  2704. // caught by singularity test above, but I've left it in just in case
  2705. this.x = (m32 - m23) / s;
  2706. this.y = (m13 - m31) / s;
  2707. this.z = (m21 - m12) / s;
  2708. this.w = Math.acos((m11 + m22 + m33 - 1) / 2);
  2709. return this;
  2710. }
  2711. min(v) {
  2712. this.x = Math.min(this.x, v.x);
  2713. this.y = Math.min(this.y, v.y);
  2714. this.z = Math.min(this.z, v.z);
  2715. this.w = Math.min(this.w, v.w);
  2716. return this;
  2717. }
  2718. max(v) {
  2719. this.x = Math.max(this.x, v.x);
  2720. this.y = Math.max(this.y, v.y);
  2721. this.z = Math.max(this.z, v.z);
  2722. this.w = Math.max(this.w, v.w);
  2723. return this;
  2724. }
  2725. clamp(min, max) {
  2726. // assumes min < max, componentwise
  2727. this.x = Math.max(min.x, Math.min(max.x, this.x));
  2728. this.y = Math.max(min.y, Math.min(max.y, this.y));
  2729. this.z = Math.max(min.z, Math.min(max.z, this.z));
  2730. this.w = Math.max(min.w, Math.min(max.w, this.w));
  2731. return this;
  2732. }
  2733. clampScalar(minVal, maxVal) {
  2734. this.x = Math.max(minVal, Math.min(maxVal, this.x));
  2735. this.y = Math.max(minVal, Math.min(maxVal, this.y));
  2736. this.z = Math.max(minVal, Math.min(maxVal, this.z));
  2737. this.w = Math.max(minVal, Math.min(maxVal, this.w));
  2738. return this;
  2739. }
  2740. clampLength(min, max) {
  2741. const length = this.length();
  2742. return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
  2743. }
  2744. floor() {
  2745. this.x = Math.floor(this.x);
  2746. this.y = Math.floor(this.y);
  2747. this.z = Math.floor(this.z);
  2748. this.w = Math.floor(this.w);
  2749. return this;
  2750. }
  2751. ceil() {
  2752. this.x = Math.ceil(this.x);
  2753. this.y = Math.ceil(this.y);
  2754. this.z = Math.ceil(this.z);
  2755. this.w = Math.ceil(this.w);
  2756. return this;
  2757. }
  2758. round() {
  2759. this.x = Math.round(this.x);
  2760. this.y = Math.round(this.y);
  2761. this.z = Math.round(this.z);
  2762. this.w = Math.round(this.w);
  2763. return this;
  2764. }
  2765. roundToZero() {
  2766. this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
  2767. this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
  2768. this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
  2769. this.w = this.w < 0 ? Math.ceil(this.w) : Math.floor(this.w);
  2770. return this;
  2771. }
  2772. negate() {
  2773. this.x = -this.x;
  2774. this.y = -this.y;
  2775. this.z = -this.z;
  2776. this.w = -this.w;
  2777. return this;
  2778. }
  2779. dot(v) {
  2780. return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w;
  2781. }
  2782. lengthSq() {
  2783. return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w;
  2784. }
  2785. length() {
  2786. return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w);
  2787. }
  2788. manhattanLength() {
  2789. return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z) + Math.abs(this.w);
  2790. }
  2791. normalize() {
  2792. return this.divideScalar(this.length() || 1);
  2793. }
  2794. setLength(length) {
  2795. return this.normalize().multiplyScalar(length);
  2796. }
  2797. lerp(v, alpha) {
  2798. this.x += (v.x - this.x) * alpha;
  2799. this.y += (v.y - this.y) * alpha;
  2800. this.z += (v.z - this.z) * alpha;
  2801. this.w += (v.w - this.w) * alpha;
  2802. return this;
  2803. }
  2804. lerpVectors(v1, v2, alpha) {
  2805. this.x = v1.x + (v2.x - v1.x) * alpha;
  2806. this.y = v1.y + (v2.y - v1.y) * alpha;
  2807. this.z = v1.z + (v2.z - v1.z) * alpha;
  2808. this.w = v1.w + (v2.w - v1.w) * alpha;
  2809. return this;
  2810. }
  2811. equals(v) {
  2812. return v.x === this.x && v.y === this.y && v.z === this.z && v.w === this.w;
  2813. }
  2814. fromArray(array, offset = 0) {
  2815. this.x = array[offset];
  2816. this.y = array[offset + 1];
  2817. this.z = array[offset + 2];
  2818. this.w = array[offset + 3];
  2819. return this;
  2820. }
  2821. toArray(array = [], offset = 0) {
  2822. array[offset] = this.x;
  2823. array[offset + 1] = this.y;
  2824. array[offset + 2] = this.z;
  2825. array[offset + 3] = this.w;
  2826. return array;
  2827. }
  2828. fromBufferAttribute(attribute, index) {
  2829. this.x = attribute.getX(index);
  2830. this.y = attribute.getY(index);
  2831. this.z = attribute.getZ(index);
  2832. this.w = attribute.getW(index);
  2833. return this;
  2834. }
  2835. random() {
  2836. this.x = Math.random();
  2837. this.y = Math.random();
  2838. this.z = Math.random();
  2839. this.w = Math.random();
  2840. return this;
  2841. }
  2842. *[Symbol.iterator]() {
  2843. yield this.x;
  2844. yield this.y;
  2845. yield this.z;
  2846. yield this.w;
  2847. }
  2848. }
  2849. /*
  2850. In options, we can specify:
  2851. * Texture parameters for an auto-generated target texture
  2852. * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers
  2853. */
  2854. class WebGLRenderTarget extends EventDispatcher {
  2855. constructor(width, height, options = {}) {
  2856. super();
  2857. this.isWebGLRenderTarget = true;
  2858. this.width = width;
  2859. this.height = height;
  2860. this.depth = 1;
  2861. this.scissor = new Vector4(0, 0, width, height);
  2862. this.scissorTest = false;
  2863. this.viewport = new Vector4(0, 0, width, height);
  2864. const image = {
  2865. width: width,
  2866. height: height,
  2867. depth: 1
  2868. };
  2869. this.texture = new Texture(image, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding);
  2870. this.texture.isRenderTargetTexture = true;
  2871. this.texture.flipY = false;
  2872. this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
  2873. this.texture.internalFormat = options.internalFormat !== undefined ? options.internalFormat : null;
  2874. this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
  2875. this.depthBuffer = options.depthBuffer !== undefined ? options.depthBuffer : true;
  2876. this.stencilBuffer = options.stencilBuffer !== undefined ? options.stencilBuffer : false;
  2877. this.depthTexture = options.depthTexture !== undefined ? options.depthTexture : null;
  2878. this.samples = options.samples !== undefined ? options.samples : 0;
  2879. }
  2880. setSize(width, height, depth = 1) {
  2881. if (this.width !== width || this.height !== height || this.depth !== depth) {
  2882. this.width = width;
  2883. this.height = height;
  2884. this.depth = depth;
  2885. this.texture.image.width = width;
  2886. this.texture.image.height = height;
  2887. this.texture.image.depth = depth;
  2888. this.dispose();
  2889. }
  2890. this.viewport.set(0, 0, width, height);
  2891. this.scissor.set(0, 0, width, height);
  2892. }
  2893. clone() {
  2894. return new this.constructor().copy(this);
  2895. }
  2896. copy(source) {
  2897. this.width = source.width;
  2898. this.height = source.height;
  2899. this.depth = source.depth;
  2900. this.viewport.copy(source.viewport);
  2901. this.texture = source.texture.clone();
  2902. this.texture.isRenderTargetTexture = true; // ensure image object is not shared, see #20328
  2903. const image = Object.assign({}, source.texture.image);
  2904. this.texture.source = new Source(image);
  2905. this.depthBuffer = source.depthBuffer;
  2906. this.stencilBuffer = source.stencilBuffer;
  2907. if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone();
  2908. this.samples = source.samples;
  2909. return this;
  2910. }
  2911. dispose() {
  2912. this.dispatchEvent({
  2913. type: 'dispose'
  2914. });
  2915. }
  2916. }
  2917. class DataArrayTexture extends Texture {
  2918. constructor(data = null, width = 1, height = 1, depth = 1) {
  2919. super(null);
  2920. this.isDataArrayTexture = true;
  2921. this.image = {
  2922. data,
  2923. width,
  2924. height,
  2925. depth
  2926. };
  2927. this.magFilter = NearestFilter;
  2928. this.minFilter = NearestFilter;
  2929. this.wrapR = ClampToEdgeWrapping;
  2930. this.generateMipmaps = false;
  2931. this.flipY = false;
  2932. this.unpackAlignment = 1;
  2933. }
  2934. }
  2935. class WebGLArrayRenderTarget extends WebGLRenderTarget {
  2936. constructor(width, height, depth) {
  2937. super(width, height);
  2938. this.isWebGLArrayRenderTarget = true;
  2939. this.depth = depth;
  2940. this.texture = new DataArrayTexture(null, width, height, depth);
  2941. this.texture.isRenderTargetTexture = true;
  2942. }
  2943. }
  2944. class Data3DTexture extends Texture {
  2945. constructor(data = null, width = 1, height = 1, depth = 1) {
  2946. // We're going to add .setXXX() methods for setting properties later.
  2947. // Users can still set in DataTexture3D directly.
  2948. //
  2949. // const texture = new THREE.DataTexture3D( data, width, height, depth );
  2950. // texture.anisotropy = 16;
  2951. //
  2952. // See #14839
  2953. super(null);
  2954. this.isData3DTexture = true;
  2955. this.image = {
  2956. data,
  2957. width,
  2958. height,
  2959. depth
  2960. };
  2961. this.magFilter = NearestFilter;
  2962. this.minFilter = NearestFilter;
  2963. this.wrapR = ClampToEdgeWrapping;
  2964. this.generateMipmaps = false;
  2965. this.flipY = false;
  2966. this.unpackAlignment = 1;
  2967. }
  2968. }
  2969. class WebGL3DRenderTarget extends WebGLRenderTarget {
  2970. constructor(width, height, depth) {
  2971. super(width, height);
  2972. this.isWebGL3DRenderTarget = true;
  2973. this.depth = depth;
  2974. this.texture = new Data3DTexture(null, width, height, depth);
  2975. this.texture.isRenderTargetTexture = true;
  2976. }
  2977. }
  2978. class WebGLMultipleRenderTargets extends WebGLRenderTarget {
  2979. constructor(width, height, count, options = {}) {
  2980. super(width, height, options);
  2981. this.isWebGLMultipleRenderTargets = true;
  2982. const texture = this.texture;
  2983. this.texture = [];
  2984. for (let i = 0; i < count; i++) {
  2985. this.texture[i] = texture.clone();
  2986. this.texture[i].isRenderTargetTexture = true;
  2987. }
  2988. }
  2989. setSize(width, height, depth = 1) {
  2990. if (this.width !== width || this.height !== height || this.depth !== depth) {
  2991. this.width = width;
  2992. this.height = height;
  2993. this.depth = depth;
  2994. for (let i = 0, il = this.texture.length; i < il; i++) {
  2995. this.texture[i].image.width = width;
  2996. this.texture[i].image.height = height;
  2997. this.texture[i].image.depth = depth;
  2998. }
  2999. this.dispose();
  3000. }
  3001. this.viewport.set(0, 0, width, height);
  3002. this.scissor.set(0, 0, width, height);
  3003. return this;
  3004. }
  3005. copy(source) {
  3006. this.dispose();
  3007. this.width = source.width;
  3008. this.height = source.height;
  3009. this.depth = source.depth;
  3010. this.viewport.set(0, 0, this.width, this.height);
  3011. this.scissor.set(0, 0, this.width, this.height);
  3012. this.depthBuffer = source.depthBuffer;
  3013. this.stencilBuffer = source.stencilBuffer;
  3014. if (source.depthTexture !== null) this.depthTexture = source.depthTexture.clone();
  3015. this.texture.length = 0;
  3016. for (let i = 0, il = source.texture.length; i < il; i++) {
  3017. this.texture[i] = source.texture[i].clone();
  3018. this.texture[i].isRenderTargetTexture = true;
  3019. }
  3020. return this;
  3021. }
  3022. }
  3023. class Quaternion {
  3024. constructor(x = 0, y = 0, z = 0, w = 1) {
  3025. this.isQuaternion = true;
  3026. this._x = x;
  3027. this._y = y;
  3028. this._z = z;
  3029. this._w = w;
  3030. }
  3031. static slerpFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1, t) {
  3032. // fuzz-free, array-based Quaternion SLERP operation
  3033. let x0 = src0[srcOffset0 + 0],
  3034. y0 = src0[srcOffset0 + 1],
  3035. z0 = src0[srcOffset0 + 2],
  3036. w0 = src0[srcOffset0 + 3];
  3037. const x1 = src1[srcOffset1 + 0],
  3038. y1 = src1[srcOffset1 + 1],
  3039. z1 = src1[srcOffset1 + 2],
  3040. w1 = src1[srcOffset1 + 3];
  3041. if (t === 0) {
  3042. dst[dstOffset + 0] = x0;
  3043. dst[dstOffset + 1] = y0;
  3044. dst[dstOffset + 2] = z0;
  3045. dst[dstOffset + 3] = w0;
  3046. return;
  3047. }
  3048. if (t === 1) {
  3049. dst[dstOffset + 0] = x1;
  3050. dst[dstOffset + 1] = y1;
  3051. dst[dstOffset + 2] = z1;
  3052. dst[dstOffset + 3] = w1;
  3053. return;
  3054. }
  3055. if (w0 !== w1 || x0 !== x1 || y0 !== y1 || z0 !== z1) {
  3056. let s = 1 - t;
  3057. const cos = x0 * x1 + y0 * y1 + z0 * z1 + w0 * w1,
  3058. dir = cos >= 0 ? 1 : -1,
  3059. sqrSin = 1 - cos * cos; // Skip the Slerp for tiny steps to avoid numeric problems:
  3060. if (sqrSin > Number.EPSILON) {
  3061. const sin = Math.sqrt(sqrSin),
  3062. len = Math.atan2(sin, cos * dir);
  3063. s = Math.sin(s * len) / sin;
  3064. t = Math.sin(t * len) / sin;
  3065. }
  3066. const tDir = t * dir;
  3067. x0 = x0 * s + x1 * tDir;
  3068. y0 = y0 * s + y1 * tDir;
  3069. z0 = z0 * s + z1 * tDir;
  3070. w0 = w0 * s + w1 * tDir; // Normalize in case we just did a lerp:
  3071. if (s === 1 - t) {
  3072. const f = 1 / Math.sqrt(x0 * x0 + y0 * y0 + z0 * z0 + w0 * w0);
  3073. x0 *= f;
  3074. y0 *= f;
  3075. z0 *= f;
  3076. w0 *= f;
  3077. }
  3078. }
  3079. dst[dstOffset] = x0;
  3080. dst[dstOffset + 1] = y0;
  3081. dst[dstOffset + 2] = z0;
  3082. dst[dstOffset + 3] = w0;
  3083. }
  3084. static multiplyQuaternionsFlat(dst, dstOffset, src0, srcOffset0, src1, srcOffset1) {
  3085. const x0 = src0[srcOffset0];
  3086. const y0 = src0[srcOffset0 + 1];
  3087. const z0 = src0[srcOffset0 + 2];
  3088. const w0 = src0[srcOffset0 + 3];
  3089. const x1 = src1[srcOffset1];
  3090. const y1 = src1[srcOffset1 + 1];
  3091. const z1 = src1[srcOffset1 + 2];
  3092. const w1 = src1[srcOffset1 + 3];
  3093. dst[dstOffset] = x0 * w1 + w0 * x1 + y0 * z1 - z0 * y1;
  3094. dst[dstOffset + 1] = y0 * w1 + w0 * y1 + z0 * x1 - x0 * z1;
  3095. dst[dstOffset + 2] = z0 * w1 + w0 * z1 + x0 * y1 - y0 * x1;
  3096. dst[dstOffset + 3] = w0 * w1 - x0 * x1 - y0 * y1 - z0 * z1;
  3097. return dst;
  3098. }
  3099. get x() {
  3100. return this._x;
  3101. }
  3102. set x(value) {
  3103. this._x = value;
  3104. this._onChangeCallback();
  3105. }
  3106. get y() {
  3107. return this._y;
  3108. }
  3109. set y(value) {
  3110. this._y = value;
  3111. this._onChangeCallback();
  3112. }
  3113. get z() {
  3114. return this._z;
  3115. }
  3116. set z(value) {
  3117. this._z = value;
  3118. this._onChangeCallback();
  3119. }
  3120. get w() {
  3121. return this._w;
  3122. }
  3123. set w(value) {
  3124. this._w = value;
  3125. this._onChangeCallback();
  3126. }
  3127. set(x, y, z, w) {
  3128. this._x = x;
  3129. this._y = y;
  3130. this._z = z;
  3131. this._w = w;
  3132. this._onChangeCallback();
  3133. return this;
  3134. }
  3135. clone() {
  3136. return new this.constructor(this._x, this._y, this._z, this._w);
  3137. }
  3138. copy(quaternion) {
  3139. this._x = quaternion.x;
  3140. this._y = quaternion.y;
  3141. this._z = quaternion.z;
  3142. this._w = quaternion.w;
  3143. this._onChangeCallback();
  3144. return this;
  3145. }
  3146. setFromEuler(euler, update) {
  3147. if (!(euler && euler.isEuler)) {
  3148. throw new Error('THREE.Quaternion: .setFromEuler() now expects an Euler rotation rather than a Vector3 and order.');
  3149. }
  3150. const x = euler._x,
  3151. y = euler._y,
  3152. z = euler._z,
  3153. order = euler._order; // http://www.mathworks.com/matlabcentral/fileexchange/
  3154. // 20696-function-to-convert-between-dcm-euler-angles-quaternions-and-euler-vectors/
  3155. // content/SpinCalc.m
  3156. const cos = Math.cos;
  3157. const sin = Math.sin;
  3158. const c1 = cos(x / 2);
  3159. const c2 = cos(y / 2);
  3160. const c3 = cos(z / 2);
  3161. const s1 = sin(x / 2);
  3162. const s2 = sin(y / 2);
  3163. const s3 = sin(z / 2);
  3164. switch (order) {
  3165. case 'XYZ':
  3166. this._x = s1 * c2 * c3 + c1 * s2 * s3;
  3167. this._y = c1 * s2 * c3 - s1 * c2 * s3;
  3168. this._z = c1 * c2 * s3 + s1 * s2 * c3;
  3169. this._w = c1 * c2 * c3 - s1 * s2 * s3;
  3170. break;
  3171. case 'YXZ':
  3172. this._x = s1 * c2 * c3 + c1 * s2 * s3;
  3173. this._y = c1 * s2 * c3 - s1 * c2 * s3;
  3174. this._z = c1 * c2 * s3 - s1 * s2 * c3;
  3175. this._w = c1 * c2 * c3 + s1 * s2 * s3;
  3176. break;
  3177. case 'ZXY':
  3178. this._x = s1 * c2 * c3 - c1 * s2 * s3;
  3179. this._y = c1 * s2 * c3 + s1 * c2 * s3;
  3180. this._z = c1 * c2 * s3 + s1 * s2 * c3;
  3181. this._w = c1 * c2 * c3 - s1 * s2 * s3;
  3182. break;
  3183. case 'ZYX':
  3184. this._x = s1 * c2 * c3 - c1 * s2 * s3;
  3185. this._y = c1 * s2 * c3 + s1 * c2 * s3;
  3186. this._z = c1 * c2 * s3 - s1 * s2 * c3;
  3187. this._w = c1 * c2 * c3 + s1 * s2 * s3;
  3188. break;
  3189. case 'YZX':
  3190. this._x = s1 * c2 * c3 + c1 * s2 * s3;
  3191. this._y = c1 * s2 * c3 + s1 * c2 * s3;
  3192. this._z = c1 * c2 * s3 - s1 * s2 * c3;
  3193. this._w = c1 * c2 * c3 - s1 * s2 * s3;
  3194. break;
  3195. case 'XZY':
  3196. this._x = s1 * c2 * c3 - c1 * s2 * s3;
  3197. this._y = c1 * s2 * c3 - s1 * c2 * s3;
  3198. this._z = c1 * c2 * s3 + s1 * s2 * c3;
  3199. this._w = c1 * c2 * c3 + s1 * s2 * s3;
  3200. break;
  3201. default:
  3202. console.warn('THREE.Quaternion: .setFromEuler() encountered an unknown order: ' + order);
  3203. }
  3204. if (update !== false) this._onChangeCallback();
  3205. return this;
  3206. }
  3207. setFromAxisAngle(axis, angle) {
  3208. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
  3209. // assumes axis is normalized
  3210. const halfAngle = angle / 2,
  3211. s = Math.sin(halfAngle);
  3212. this._x = axis.x * s;
  3213. this._y = axis.y * s;
  3214. this._z = axis.z * s;
  3215. this._w = Math.cos(halfAngle);
  3216. this._onChangeCallback();
  3217. return this;
  3218. }
  3219. setFromRotationMatrix(m) {
  3220. // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
  3221. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  3222. const te = m.elements,
  3223. m11 = te[0],
  3224. m12 = te[4],
  3225. m13 = te[8],
  3226. m21 = te[1],
  3227. m22 = te[5],
  3228. m23 = te[9],
  3229. m31 = te[2],
  3230. m32 = te[6],
  3231. m33 = te[10],
  3232. trace = m11 + m22 + m33;
  3233. if (trace > 0) {
  3234. const s = 0.5 / Math.sqrt(trace + 1.0);
  3235. this._w = 0.25 / s;
  3236. this._x = (m32 - m23) * s;
  3237. this._y = (m13 - m31) * s;
  3238. this._z = (m21 - m12) * s;
  3239. } else if (m11 > m22 && m11 > m33) {
  3240. const s = 2.0 * Math.sqrt(1.0 + m11 - m22 - m33);
  3241. this._w = (m32 - m23) / s;
  3242. this._x = 0.25 * s;
  3243. this._y = (m12 + m21) / s;
  3244. this._z = (m13 + m31) / s;
  3245. } else if (m22 > m33) {
  3246. const s = 2.0 * Math.sqrt(1.0 + m22 - m11 - m33);
  3247. this._w = (m13 - m31) / s;
  3248. this._x = (m12 + m21) / s;
  3249. this._y = 0.25 * s;
  3250. this._z = (m23 + m32) / s;
  3251. } else {
  3252. const s = 2.0 * Math.sqrt(1.0 + m33 - m11 - m22);
  3253. this._w = (m21 - m12) / s;
  3254. this._x = (m13 + m31) / s;
  3255. this._y = (m23 + m32) / s;
  3256. this._z = 0.25 * s;
  3257. }
  3258. this._onChangeCallback();
  3259. return this;
  3260. }
  3261. setFromUnitVectors(vFrom, vTo) {
  3262. // assumes direction vectors vFrom and vTo are normalized
  3263. let r = vFrom.dot(vTo) + 1;
  3264. if (r < Number.EPSILON) {
  3265. // vFrom and vTo point in opposite directions
  3266. r = 0;
  3267. if (Math.abs(vFrom.x) > Math.abs(vFrom.z)) {
  3268. this._x = -vFrom.y;
  3269. this._y = vFrom.x;
  3270. this._z = 0;
  3271. this._w = r;
  3272. } else {
  3273. this._x = 0;
  3274. this._y = -vFrom.z;
  3275. this._z = vFrom.y;
  3276. this._w = r;
  3277. }
  3278. } else {
  3279. // crossVectors( vFrom, vTo ); // inlined to avoid cyclic dependency on Vector3
  3280. this._x = vFrom.y * vTo.z - vFrom.z * vTo.y;
  3281. this._y = vFrom.z * vTo.x - vFrom.x * vTo.z;
  3282. this._z = vFrom.x * vTo.y - vFrom.y * vTo.x;
  3283. this._w = r;
  3284. }
  3285. return this.normalize();
  3286. }
  3287. angleTo(q) {
  3288. return 2 * Math.acos(Math.abs(clamp(this.dot(q), -1, 1)));
  3289. }
  3290. rotateTowards(q, step) {
  3291. const angle = this.angleTo(q);
  3292. if (angle === 0) return this;
  3293. const t = Math.min(1, step / angle);
  3294. this.slerp(q, t);
  3295. return this;
  3296. }
  3297. identity() {
  3298. return this.set(0, 0, 0, 1);
  3299. }
  3300. invert() {
  3301. // quaternion is assumed to have unit length
  3302. return this.conjugate();
  3303. }
  3304. conjugate() {
  3305. this._x *= -1;
  3306. this._y *= -1;
  3307. this._z *= -1;
  3308. this._onChangeCallback();
  3309. return this;
  3310. }
  3311. dot(v) {
  3312. return this._x * v._x + this._y * v._y + this._z * v._z + this._w * v._w;
  3313. }
  3314. lengthSq() {
  3315. return this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w;
  3316. }
  3317. length() {
  3318. return Math.sqrt(this._x * this._x + this._y * this._y + this._z * this._z + this._w * this._w);
  3319. }
  3320. normalize() {
  3321. let l = this.length();
  3322. if (l === 0) {
  3323. this._x = 0;
  3324. this._y = 0;
  3325. this._z = 0;
  3326. this._w = 1;
  3327. } else {
  3328. l = 1 / l;
  3329. this._x = this._x * l;
  3330. this._y = this._y * l;
  3331. this._z = this._z * l;
  3332. this._w = this._w * l;
  3333. }
  3334. this._onChangeCallback();
  3335. return this;
  3336. }
  3337. multiply(q) {
  3338. return this.multiplyQuaternions(this, q);
  3339. }
  3340. premultiply(q) {
  3341. return this.multiplyQuaternions(q, this);
  3342. }
  3343. multiplyQuaternions(a, b) {
  3344. // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
  3345. const qax = a._x,
  3346. qay = a._y,
  3347. qaz = a._z,
  3348. qaw = a._w;
  3349. const qbx = b._x,
  3350. qby = b._y,
  3351. qbz = b._z,
  3352. qbw = b._w;
  3353. this._x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
  3354. this._y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
  3355. this._z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
  3356. this._w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
  3357. this._onChangeCallback();
  3358. return this;
  3359. }
  3360. slerp(qb, t) {
  3361. if (t === 0) return this;
  3362. if (t === 1) return this.copy(qb);
  3363. const x = this._x,
  3364. y = this._y,
  3365. z = this._z,
  3366. w = this._w; // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
  3367. let cosHalfTheta = w * qb._w + x * qb._x + y * qb._y + z * qb._z;
  3368. if (cosHalfTheta < 0) {
  3369. this._w = -qb._w;
  3370. this._x = -qb._x;
  3371. this._y = -qb._y;
  3372. this._z = -qb._z;
  3373. cosHalfTheta = -cosHalfTheta;
  3374. } else {
  3375. this.copy(qb);
  3376. }
  3377. if (cosHalfTheta >= 1.0) {
  3378. this._w = w;
  3379. this._x = x;
  3380. this._y = y;
  3381. this._z = z;
  3382. return this;
  3383. }
  3384. const sqrSinHalfTheta = 1.0 - cosHalfTheta * cosHalfTheta;
  3385. if (sqrSinHalfTheta <= Number.EPSILON) {
  3386. const s = 1 - t;
  3387. this._w = s * w + t * this._w;
  3388. this._x = s * x + t * this._x;
  3389. this._y = s * y + t * this._y;
  3390. this._z = s * z + t * this._z;
  3391. this.normalize();
  3392. this._onChangeCallback();
  3393. return this;
  3394. }
  3395. const sinHalfTheta = Math.sqrt(sqrSinHalfTheta);
  3396. const halfTheta = Math.atan2(sinHalfTheta, cosHalfTheta);
  3397. const ratioA = Math.sin((1 - t) * halfTheta) / sinHalfTheta,
  3398. ratioB = Math.sin(t * halfTheta) / sinHalfTheta;
  3399. this._w = w * ratioA + this._w * ratioB;
  3400. this._x = x * ratioA + this._x * ratioB;
  3401. this._y = y * ratioA + this._y * ratioB;
  3402. this._z = z * ratioA + this._z * ratioB;
  3403. this._onChangeCallback();
  3404. return this;
  3405. }
  3406. slerpQuaternions(qa, qb, t) {
  3407. return this.copy(qa).slerp(qb, t);
  3408. }
  3409. random() {
  3410. // Derived from http://planning.cs.uiuc.edu/node198.html
  3411. // Note, this source uses w, x, y, z ordering,
  3412. // so we swap the order below.
  3413. const u1 = Math.random();
  3414. const sqrt1u1 = Math.sqrt(1 - u1);
  3415. const sqrtu1 = Math.sqrt(u1);
  3416. const u2 = 2 * Math.PI * Math.random();
  3417. const u3 = 2 * Math.PI * Math.random();
  3418. return this.set(sqrt1u1 * Math.cos(u2), sqrtu1 * Math.sin(u3), sqrtu1 * Math.cos(u3), sqrt1u1 * Math.sin(u2));
  3419. }
  3420. equals(quaternion) {
  3421. return quaternion._x === this._x && quaternion._y === this._y && quaternion._z === this._z && quaternion._w === this._w;
  3422. }
  3423. fromArray(array, offset = 0) {
  3424. this._x = array[offset];
  3425. this._y = array[offset + 1];
  3426. this._z = array[offset + 2];
  3427. this._w = array[offset + 3];
  3428. this._onChangeCallback();
  3429. return this;
  3430. }
  3431. toArray(array = [], offset = 0) {
  3432. array[offset] = this._x;
  3433. array[offset + 1] = this._y;
  3434. array[offset + 2] = this._z;
  3435. array[offset + 3] = this._w;
  3436. return array;
  3437. }
  3438. fromBufferAttribute(attribute, index) {
  3439. this._x = attribute.getX(index);
  3440. this._y = attribute.getY(index);
  3441. this._z = attribute.getZ(index);
  3442. this._w = attribute.getW(index);
  3443. return this;
  3444. }
  3445. _onChange(callback) {
  3446. this._onChangeCallback = callback;
  3447. return this;
  3448. }
  3449. _onChangeCallback() {}
  3450. *[Symbol.iterator]() {
  3451. yield this._x;
  3452. yield this._y;
  3453. yield this._z;
  3454. yield this._w;
  3455. }
  3456. }
  3457. class Vector3 {
  3458. constructor(x = 0, y = 0, z = 0) {
  3459. Vector3.prototype.isVector3 = true;
  3460. this.x = x;
  3461. this.y = y;
  3462. this.z = z;
  3463. }
  3464. set(x, y, z) {
  3465. if (z === undefined) z = this.z; // sprite.scale.set(x,y)
  3466. this.x = x;
  3467. this.y = y;
  3468. this.z = z;
  3469. return this;
  3470. }
  3471. setScalar(scalar) {
  3472. this.x = scalar;
  3473. this.y = scalar;
  3474. this.z = scalar;
  3475. return this;
  3476. }
  3477. setX(x) {
  3478. this.x = x;
  3479. return this;
  3480. }
  3481. setY(y) {
  3482. this.y = y;
  3483. return this;
  3484. }
  3485. setZ(z) {
  3486. this.z = z;
  3487. return this;
  3488. }
  3489. setComponent(index, value) {
  3490. switch (index) {
  3491. case 0:
  3492. this.x = value;
  3493. break;
  3494. case 1:
  3495. this.y = value;
  3496. break;
  3497. case 2:
  3498. this.z = value;
  3499. break;
  3500. default:
  3501. throw new Error('index is out of range: ' + index);
  3502. }
  3503. return this;
  3504. }
  3505. getComponent(index) {
  3506. switch (index) {
  3507. case 0:
  3508. return this.x;
  3509. case 1:
  3510. return this.y;
  3511. case 2:
  3512. return this.z;
  3513. default:
  3514. throw new Error('index is out of range: ' + index);
  3515. }
  3516. }
  3517. clone() {
  3518. return new this.constructor(this.x, this.y, this.z);
  3519. }
  3520. copy(v) {
  3521. this.x = v.x;
  3522. this.y = v.y;
  3523. this.z = v.z;
  3524. return this;
  3525. }
  3526. add(v) {
  3527. this.x += v.x;
  3528. this.y += v.y;
  3529. this.z += v.z;
  3530. return this;
  3531. }
  3532. addScalar(s) {
  3533. this.x += s;
  3534. this.y += s;
  3535. this.z += s;
  3536. return this;
  3537. }
  3538. addVectors(a, b) {
  3539. this.x = a.x + b.x;
  3540. this.y = a.y + b.y;
  3541. this.z = a.z + b.z;
  3542. return this;
  3543. }
  3544. addScaledVector(v, s) {
  3545. this.x += v.x * s;
  3546. this.y += v.y * s;
  3547. this.z += v.z * s;
  3548. return this;
  3549. }
  3550. sub(v) {
  3551. this.x -= v.x;
  3552. this.y -= v.y;
  3553. this.z -= v.z;
  3554. return this;
  3555. }
  3556. subScalar(s) {
  3557. this.x -= s;
  3558. this.y -= s;
  3559. this.z -= s;
  3560. return this;
  3561. }
  3562. subVectors(a, b) {
  3563. this.x = a.x - b.x;
  3564. this.y = a.y - b.y;
  3565. this.z = a.z - b.z;
  3566. return this;
  3567. }
  3568. multiply(v) {
  3569. this.x *= v.x;
  3570. this.y *= v.y;
  3571. this.z *= v.z;
  3572. return this;
  3573. }
  3574. multiplyScalar(scalar) {
  3575. this.x *= scalar;
  3576. this.y *= scalar;
  3577. this.z *= scalar;
  3578. return this;
  3579. }
  3580. multiplyVectors(a, b) {
  3581. this.x = a.x * b.x;
  3582. this.y = a.y * b.y;
  3583. this.z = a.z * b.z;
  3584. return this;
  3585. }
  3586. applyEuler(euler) {
  3587. return this.applyQuaternion(_quaternion$4.setFromEuler(euler));
  3588. }
  3589. applyAxisAngle(axis, angle) {
  3590. return this.applyQuaternion(_quaternion$4.setFromAxisAngle(axis, angle));
  3591. }
  3592. applyMatrix3(m) {
  3593. const x = this.x,
  3594. y = this.y,
  3595. z = this.z;
  3596. const e = m.elements;
  3597. this.x = e[0] * x + e[3] * y + e[6] * z;
  3598. this.y = e[1] * x + e[4] * y + e[7] * z;
  3599. this.z = e[2] * x + e[5] * y + e[8] * z;
  3600. return this;
  3601. }
  3602. applyNormalMatrix(m) {
  3603. return this.applyMatrix3(m).normalize();
  3604. }
  3605. applyMatrix4(m) {
  3606. const x = this.x,
  3607. y = this.y,
  3608. z = this.z;
  3609. const e = m.elements;
  3610. const w = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]);
  3611. this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * w;
  3612. this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * w;
  3613. this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * w;
  3614. return this;
  3615. }
  3616. applyQuaternion(q) {
  3617. const x = this.x,
  3618. y = this.y,
  3619. z = this.z;
  3620. const qx = q.x,
  3621. qy = q.y,
  3622. qz = q.z,
  3623. qw = q.w; // calculate quat * vector
  3624. const ix = qw * x + qy * z - qz * y;
  3625. const iy = qw * y + qz * x - qx * z;
  3626. const iz = qw * z + qx * y - qy * x;
  3627. const iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat
  3628. this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  3629. this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  3630. this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  3631. return this;
  3632. }
  3633. project(camera) {
  3634. return this.applyMatrix4(camera.matrixWorldInverse).applyMatrix4(camera.projectionMatrix);
  3635. }
  3636. unproject(camera) {
  3637. return this.applyMatrix4(camera.projectionMatrixInverse).applyMatrix4(camera.matrixWorld);
  3638. }
  3639. transformDirection(m) {
  3640. // input: THREE.Matrix4 affine matrix
  3641. // vector interpreted as a direction
  3642. const x = this.x,
  3643. y = this.y,
  3644. z = this.z;
  3645. const e = m.elements;
  3646. this.x = e[0] * x + e[4] * y + e[8] * z;
  3647. this.y = e[1] * x + e[5] * y + e[9] * z;
  3648. this.z = e[2] * x + e[6] * y + e[10] * z;
  3649. return this.normalize();
  3650. }
  3651. divide(v) {
  3652. this.x /= v.x;
  3653. this.y /= v.y;
  3654. this.z /= v.z;
  3655. return this;
  3656. }
  3657. divideScalar(scalar) {
  3658. return this.multiplyScalar(1 / scalar);
  3659. }
  3660. min(v) {
  3661. this.x = Math.min(this.x, v.x);
  3662. this.y = Math.min(this.y, v.y);
  3663. this.z = Math.min(this.z, v.z);
  3664. return this;
  3665. }
  3666. max(v) {
  3667. this.x = Math.max(this.x, v.x);
  3668. this.y = Math.max(this.y, v.y);
  3669. this.z = Math.max(this.z, v.z);
  3670. return this;
  3671. }
  3672. clamp(min, max) {
  3673. // assumes min < max, componentwise
  3674. this.x = Math.max(min.x, Math.min(max.x, this.x));
  3675. this.y = Math.max(min.y, Math.min(max.y, this.y));
  3676. this.z = Math.max(min.z, Math.min(max.z, this.z));
  3677. return this;
  3678. }
  3679. clampScalar(minVal, maxVal) {
  3680. this.x = Math.max(minVal, Math.min(maxVal, this.x));
  3681. this.y = Math.max(minVal, Math.min(maxVal, this.y));
  3682. this.z = Math.max(minVal, Math.min(maxVal, this.z));
  3683. return this;
  3684. }
  3685. clampLength(min, max) {
  3686. const length = this.length();
  3687. return this.divideScalar(length || 1).multiplyScalar(Math.max(min, Math.min(max, length)));
  3688. }
  3689. floor() {
  3690. this.x = Math.floor(this.x);
  3691. this.y = Math.floor(this.y);
  3692. this.z = Math.floor(this.z);
  3693. return this;
  3694. }
  3695. ceil() {
  3696. this.x = Math.ceil(this.x);
  3697. this.y = Math.ceil(this.y);
  3698. this.z = Math.ceil(this.z);
  3699. return this;
  3700. }
  3701. round() {
  3702. this.x = Math.round(this.x);
  3703. this.y = Math.round(this.y);
  3704. this.z = Math.round(this.z);
  3705. return this;
  3706. }
  3707. roundToZero() {
  3708. this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
  3709. this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
  3710. this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
  3711. return this;
  3712. }
  3713. negate() {
  3714. this.x = -this.x;
  3715. this.y = -this.y;
  3716. this.z = -this.z;
  3717. return this;
  3718. }
  3719. dot(v) {
  3720. return this.x * v.x + this.y * v.y + this.z * v.z;
  3721. } // TODO lengthSquared?
  3722. lengthSq() {
  3723. return this.x * this.x + this.y * this.y + this.z * this.z;
  3724. }
  3725. length() {
  3726. return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
  3727. }
  3728. manhattanLength() {
  3729. return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
  3730. }
  3731. normalize() {
  3732. return this.divideScalar(this.length() || 1);
  3733. }
  3734. setLength(length) {
  3735. return this.normalize().multiplyScalar(length);
  3736. }
  3737. lerp(v, alpha) {
  3738. this.x += (v.x - this.x) * alpha;
  3739. this.y += (v.y - this.y) * alpha;
  3740. this.z += (v.z - this.z) * alpha;
  3741. return this;
  3742. }
  3743. lerpVectors(v1, v2, alpha) {
  3744. this.x = v1.x + (v2.x - v1.x) * alpha;
  3745. this.y = v1.y + (v2.y - v1.y) * alpha;
  3746. this.z = v1.z + (v2.z - v1.z) * alpha;
  3747. return this;
  3748. }
  3749. cross(v) {
  3750. return this.crossVectors(this, v);
  3751. }
  3752. crossVectors(a, b) {
  3753. const ax = a.x,
  3754. ay = a.y,
  3755. az = a.z;
  3756. const bx = b.x,
  3757. by = b.y,
  3758. bz = b.z;
  3759. this.x = ay * bz - az * by;
  3760. this.y = az * bx - ax * bz;
  3761. this.z = ax * by - ay * bx;
  3762. return this;
  3763. }
  3764. projectOnVector(v) {
  3765. const denominator = v.lengthSq();
  3766. if (denominator === 0) return this.set(0, 0, 0);
  3767. const scalar = v.dot(this) / denominator;
  3768. return this.copy(v).multiplyScalar(scalar);
  3769. }
  3770. projectOnPlane(planeNormal) {
  3771. _vector$c.copy(this).projectOnVector(planeNormal);
  3772. return this.sub(_vector$c);
  3773. }
  3774. reflect(normal) {
  3775. // reflect incident vector off plane orthogonal to normal
  3776. // normal is assumed to have unit length
  3777. return this.sub(_vector$c.copy(normal).multiplyScalar(2 * this.dot(normal)));
  3778. }
  3779. angleTo(v) {
  3780. const denominator = Math.sqrt(this.lengthSq() * v.lengthSq());
  3781. if (denominator === 0) return Math.PI / 2;
  3782. const theta = this.dot(v) / denominator; // clamp, to handle numerical problems
  3783. return Math.acos(clamp(theta, -1, 1));
  3784. }
  3785. distanceTo(v) {
  3786. return Math.sqrt(this.distanceToSquared(v));
  3787. }
  3788. distanceToSquared(v) {
  3789. const dx = this.x - v.x,
  3790. dy = this.y - v.y,
  3791. dz = this.z - v.z;
  3792. return dx * dx + dy * dy + dz * dz;
  3793. }
  3794. manhattanDistanceTo(v) {
  3795. return Math.abs(this.x - v.x) + Math.abs(this.y - v.y) + Math.abs(this.z - v.z);
  3796. }
  3797. setFromSpherical(s) {
  3798. return this.setFromSphericalCoords(s.radius, s.phi, s.theta);
  3799. }
  3800. setFromSphericalCoords(radius, phi, theta) {
  3801. const sinPhiRadius = Math.sin(phi) * radius;
  3802. this.x = sinPhiRadius * Math.sin(theta);
  3803. this.y = Math.cos(phi) * radius;
  3804. this.z = sinPhiRadius * Math.cos(theta);
  3805. return this;
  3806. }
  3807. setFromCylindrical(c) {
  3808. return this.setFromCylindricalCoords(c.radius, c.theta, c.y);
  3809. }
  3810. setFromCylindricalCoords(radius, theta, y) {
  3811. this.x = radius * Math.sin(theta);
  3812. this.y = y;
  3813. this.z = radius * Math.cos(theta);
  3814. return this;
  3815. }
  3816. setFromMatrixPosition(m) {
  3817. const e = m.elements;
  3818. this.x = e[12];
  3819. this.y = e[13];
  3820. this.z = e[14];
  3821. return this;
  3822. }
  3823. setFromMatrixScale(m) {
  3824. const sx = this.setFromMatrixColumn(m, 0).length();
  3825. const sy = this.setFromMatrixColumn(m, 1).length();
  3826. const sz = this.setFromMatrixColumn(m, 2).length();
  3827. this.x = sx;
  3828. this.y = sy;
  3829. this.z = sz;
  3830. return this;
  3831. }
  3832. setFromMatrixColumn(m, index) {
  3833. return this.fromArray(m.elements, index * 4);
  3834. }
  3835. setFromMatrix3Column(m, index) {
  3836. return this.fromArray(m.elements, index * 3);
  3837. }
  3838. setFromEuler(e) {
  3839. this.x = e._x;
  3840. this.y = e._y;
  3841. this.z = e._z;
  3842. return this;
  3843. }
  3844. equals(v) {
  3845. return v.x === this.x && v.y === this.y && v.z === this.z;
  3846. }
  3847. fromArray(array, offset = 0) {
  3848. this.x = array[offset];
  3849. this.y = array[offset + 1];
  3850. this.z = array[offset + 2];
  3851. return this;
  3852. }
  3853. toArray(array = [], offset = 0) {
  3854. array[offset] = this.x;
  3855. array[offset + 1] = this.y;
  3856. array[offset + 2] = this.z;
  3857. return array;
  3858. }
  3859. fromBufferAttribute(attribute, index) {
  3860. this.x = attribute.getX(index);
  3861. this.y = attribute.getY(index);
  3862. this.z = attribute.getZ(index);
  3863. return this;
  3864. }
  3865. random() {
  3866. this.x = Math.random();
  3867. this.y = Math.random();
  3868. this.z = Math.random();
  3869. return this;
  3870. }
  3871. randomDirection() {
  3872. // Derived from https://mathworld.wolfram.com/SpherePointPicking.html
  3873. const u = (Math.random() - 0.5) * 2;
  3874. const t = Math.random() * Math.PI * 2;
  3875. const f = Math.sqrt(1 - u ** 2);
  3876. this.x = f * Math.cos(t);
  3877. this.y = f * Math.sin(t);
  3878. this.z = u;
  3879. return this;
  3880. }
  3881. *[Symbol.iterator]() {
  3882. yield this.x;
  3883. yield this.y;
  3884. yield this.z;
  3885. }
  3886. }
  3887. const _vector$c = /*@__PURE__*/new Vector3();
  3888. const _quaternion$4 = /*@__PURE__*/new Quaternion();
  3889. class Box3 {
  3890. constructor(min = new Vector3(+Infinity, +Infinity, +Infinity), max = new Vector3(-Infinity, -Infinity, -Infinity)) {
  3891. this.isBox3 = true;
  3892. this.min = min;
  3893. this.max = max;
  3894. }
  3895. set(min, max) {
  3896. this.min.copy(min);
  3897. this.max.copy(max);
  3898. return this;
  3899. }
  3900. setFromArray(array) {
  3901. let minX = +Infinity;
  3902. let minY = +Infinity;
  3903. let minZ = +Infinity;
  3904. let maxX = -Infinity;
  3905. let maxY = -Infinity;
  3906. let maxZ = -Infinity;
  3907. for (let i = 0, l = array.length; i < l; i += 3) {
  3908. const x = array[i];
  3909. const y = array[i + 1];
  3910. const z = array[i + 2];
  3911. if (x < minX) minX = x;
  3912. if (y < minY) minY = y;
  3913. if (z < minZ) minZ = z;
  3914. if (x > maxX) maxX = x;
  3915. if (y > maxY) maxY = y;
  3916. if (z > maxZ) maxZ = z;
  3917. }
  3918. this.min.set(minX, minY, minZ);
  3919. this.max.set(maxX, maxY, maxZ);
  3920. return this;
  3921. }
  3922. setFromBufferAttribute(attribute) {
  3923. let minX = +Infinity;
  3924. let minY = +Infinity;
  3925. let minZ = +Infinity;
  3926. let maxX = -Infinity;
  3927. let maxY = -Infinity;
  3928. let maxZ = -Infinity;
  3929. for (let i = 0, l = attribute.count; i < l; i++) {
  3930. const x = attribute.getX(i);
  3931. const y = attribute.getY(i);
  3932. const z = attribute.getZ(i);
  3933. if (x < minX) minX = x;
  3934. if (y < minY) minY = y;
  3935. if (z < minZ) minZ = z;
  3936. if (x > maxX) maxX = x;
  3937. if (y > maxY) maxY = y;
  3938. if (z > maxZ) maxZ = z;
  3939. }
  3940. this.min.set(minX, minY, minZ);
  3941. this.max.set(maxX, maxY, maxZ);
  3942. return this;
  3943. }
  3944. setFromPoints(points) {
  3945. this.makeEmpty();
  3946. for (let i = 0, il = points.length; i < il; i++) {
  3947. this.expandByPoint(points[i]);
  3948. }
  3949. return this;
  3950. }
  3951. setFromCenterAndSize(center, size) {
  3952. const halfSize = _vector$b.copy(size).multiplyScalar(0.5);
  3953. this.min.copy(center).sub(halfSize);
  3954. this.max.copy(center).add(halfSize);
  3955. return this;
  3956. }
  3957. setFromObject(object, precise = false) {
  3958. this.makeEmpty();
  3959. return this.expandByObject(object, precise);
  3960. }
  3961. clone() {
  3962. return new this.constructor().copy(this);
  3963. }
  3964. copy(box) {
  3965. this.min.copy(box.min);
  3966. this.max.copy(box.max);
  3967. return this;
  3968. }
  3969. makeEmpty() {
  3970. this.min.x = this.min.y = this.min.z = +Infinity;
  3971. this.max.x = this.max.y = this.max.z = -Infinity;
  3972. return this;
  3973. }
  3974. isEmpty() {
  3975. // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
  3976. return this.max.x < this.min.x || this.max.y < this.min.y || this.max.z < this.min.z;
  3977. }
  3978. getCenter(target) {
  3979. return this.isEmpty() ? target.set(0, 0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
  3980. }
  3981. getSize(target) {
  3982. return this.isEmpty() ? target.set(0, 0, 0) : target.subVectors(this.max, this.min);
  3983. }
  3984. expandByPoint(point) {
  3985. this.min.min(point);
  3986. this.max.max(point);
  3987. return this;
  3988. }
  3989. expandByVector(vector) {
  3990. this.min.sub(vector);
  3991. this.max.add(vector);
  3992. return this;
  3993. }
  3994. expandByScalar(scalar) {
  3995. this.min.addScalar(-scalar);
  3996. this.max.addScalar(scalar);
  3997. return this;
  3998. }
  3999. expandByObject(object, precise = false) {
  4000. // Computes the world-axis-aligned bounding box of an object (including its children),
  4001. // accounting for both the object's, and children's, world transforms
  4002. object.updateWorldMatrix(false, false);
  4003. const geometry = object.geometry;
  4004. if (geometry !== undefined) {
  4005. if (precise && geometry.attributes != undefined && geometry.attributes.position !== undefined) {
  4006. const position = geometry.attributes.position;
  4007. for (let i = 0, l = position.count; i < l; i++) {
  4008. _vector$b.fromBufferAttribute(position, i).applyMatrix4(object.matrixWorld);
  4009. this.expandByPoint(_vector$b);
  4010. }
  4011. } else {
  4012. if (geometry.boundingBox === null) {
  4013. geometry.computeBoundingBox();
  4014. }
  4015. _box$3.copy(geometry.boundingBox);
  4016. _box$3.applyMatrix4(object.matrixWorld);
  4017. this.union(_box$3);
  4018. }
  4019. }
  4020. const children = object.children;
  4021. for (let i = 0, l = children.length; i < l; i++) {
  4022. this.expandByObject(children[i], precise);
  4023. }
  4024. return this;
  4025. }
  4026. containsPoint(point) {
  4027. return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y || point.z < this.min.z || point.z > this.max.z ? false : true;
  4028. }
  4029. containsBox(box) {
  4030. return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y && this.min.z <= box.min.z && box.max.z <= this.max.z;
  4031. }
  4032. getParameter(point, target) {
  4033. // This can potentially have a divide by zero if the box
  4034. // has a size dimension of 0.
  4035. return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y), (point.z - this.min.z) / (this.max.z - this.min.z));
  4036. }
  4037. intersectsBox(box) {
  4038. // using 6 splitting planes to rule out intersections.
  4039. return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y || box.max.z < this.min.z || box.min.z > this.max.z ? false : true;
  4040. }
  4041. intersectsSphere(sphere) {
  4042. // Find the point on the AABB closest to the sphere center.
  4043. this.clampPoint(sphere.center, _vector$b); // If that point is inside the sphere, the AABB and sphere intersect.
  4044. return _vector$b.distanceToSquared(sphere.center) <= sphere.radius * sphere.radius;
  4045. }
  4046. intersectsPlane(plane) {
  4047. // We compute the minimum and maximum dot product values. If those values
  4048. // are on the same side (back or front) of the plane, then there is no intersection.
  4049. let min, max;
  4050. if (plane.normal.x > 0) {
  4051. min = plane.normal.x * this.min.x;
  4052. max = plane.normal.x * this.max.x;
  4053. } else {
  4054. min = plane.normal.x * this.max.x;
  4055. max = plane.normal.x * this.min.x;
  4056. }
  4057. if (plane.normal.y > 0) {
  4058. min += plane.normal.y * this.min.y;
  4059. max += plane.normal.y * this.max.y;
  4060. } else {
  4061. min += plane.normal.y * this.max.y;
  4062. max += plane.normal.y * this.min.y;
  4063. }
  4064. if (plane.normal.z > 0) {
  4065. min += plane.normal.z * this.min.z;
  4066. max += plane.normal.z * this.max.z;
  4067. } else {
  4068. min += plane.normal.z * this.max.z;
  4069. max += plane.normal.z * this.min.z;
  4070. }
  4071. return min <= -plane.constant && max >= -plane.constant;
  4072. }
  4073. intersectsTriangle(triangle) {
  4074. if (this.isEmpty()) {
  4075. return false;
  4076. } // compute box center and extents
  4077. this.getCenter(_center);
  4078. _extents.subVectors(this.max, _center); // translate triangle to aabb origin
  4079. _v0$2.subVectors(triangle.a, _center);
  4080. _v1$7.subVectors(triangle.b, _center);
  4081. _v2$3.subVectors(triangle.c, _center); // compute edge vectors for triangle
  4082. _f0.subVectors(_v1$7, _v0$2);
  4083. _f1.subVectors(_v2$3, _v1$7);
  4084. _f2.subVectors(_v0$2, _v2$3); // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb
  4085. // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation
  4086. // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned)
  4087. let axes = [0, -_f0.z, _f0.y, 0, -_f1.z, _f1.y, 0, -_f2.z, _f2.y, _f0.z, 0, -_f0.x, _f1.z, 0, -_f1.x, _f2.z, 0, -_f2.x, -_f0.y, _f0.x, 0, -_f1.y, _f1.x, 0, -_f2.y, _f2.x, 0];
  4088. if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) {
  4089. return false;
  4090. } // test 3 face normals from the aabb
  4091. axes = [1, 0, 0, 0, 1, 0, 0, 0, 1];
  4092. if (!satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents)) {
  4093. return false;
  4094. } // finally testing the face normal of the triangle
  4095. // use already existing triangle edge vectors here
  4096. _triangleNormal.crossVectors(_f0, _f1);
  4097. axes = [_triangleNormal.x, _triangleNormal.y, _triangleNormal.z];
  4098. return satForAxes(axes, _v0$2, _v1$7, _v2$3, _extents);
  4099. }
  4100. clampPoint(point, target) {
  4101. return target.copy(point).clamp(this.min, this.max);
  4102. }
  4103. distanceToPoint(point) {
  4104. const clampedPoint = _vector$b.copy(point).clamp(this.min, this.max);
  4105. return clampedPoint.sub(point).length();
  4106. }
  4107. getBoundingSphere(target) {
  4108. this.getCenter(target.center);
  4109. target.radius = this.getSize(_vector$b).length() * 0.5;
  4110. return target;
  4111. }
  4112. intersect(box) {
  4113. this.min.max(box.min);
  4114. this.max.min(box.max); // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values.
  4115. if (this.isEmpty()) this.makeEmpty();
  4116. return this;
  4117. }
  4118. union(box) {
  4119. this.min.min(box.min);
  4120. this.max.max(box.max);
  4121. return this;
  4122. }
  4123. applyMatrix4(matrix) {
  4124. // transform of empty box is an empty box.
  4125. if (this.isEmpty()) return this; // NOTE: I am using a binary pattern to specify all 2^3 combinations below
  4126. _points[0].set(this.min.x, this.min.y, this.min.z).applyMatrix4(matrix); // 000
  4127. _points[1].set(this.min.x, this.min.y, this.max.z).applyMatrix4(matrix); // 001
  4128. _points[2].set(this.min.x, this.max.y, this.min.z).applyMatrix4(matrix); // 010
  4129. _points[3].set(this.min.x, this.max.y, this.max.z).applyMatrix4(matrix); // 011
  4130. _points[4].set(this.max.x, this.min.y, this.min.z).applyMatrix4(matrix); // 100
  4131. _points[5].set(this.max.x, this.min.y, this.max.z).applyMatrix4(matrix); // 101
  4132. _points[6].set(this.max.x, this.max.y, this.min.z).applyMatrix4(matrix); // 110
  4133. _points[7].set(this.max.x, this.max.y, this.max.z).applyMatrix4(matrix); // 111
  4134. this.setFromPoints(_points);
  4135. return this;
  4136. }
  4137. translate(offset) {
  4138. this.min.add(offset);
  4139. this.max.add(offset);
  4140. return this;
  4141. }
  4142. equals(box) {
  4143. return box.min.equals(this.min) && box.max.equals(this.max);
  4144. }
  4145. }
  4146. const _points = [/*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3(), /*@__PURE__*/new Vector3()];
  4147. const _vector$b = /*@__PURE__*/new Vector3();
  4148. const _box$3 = /*@__PURE__*/new Box3(); // triangle centered vertices
  4149. const _v0$2 = /*@__PURE__*/new Vector3();
  4150. const _v1$7 = /*@__PURE__*/new Vector3();
  4151. const _v2$3 = /*@__PURE__*/new Vector3(); // triangle edge vectors
  4152. const _f0 = /*@__PURE__*/new Vector3();
  4153. const _f1 = /*@__PURE__*/new Vector3();
  4154. const _f2 = /*@__PURE__*/new Vector3();
  4155. const _center = /*@__PURE__*/new Vector3();
  4156. const _extents = /*@__PURE__*/new Vector3();
  4157. const _triangleNormal = /*@__PURE__*/new Vector3();
  4158. const _testAxis = /*@__PURE__*/new Vector3();
  4159. function satForAxes(axes, v0, v1, v2, extents) {
  4160. for (let i = 0, j = axes.length - 3; i <= j; i += 3) {
  4161. _testAxis.fromArray(axes, i); // project the aabb onto the separating axis
  4162. const r = extents.x * Math.abs(_testAxis.x) + extents.y * Math.abs(_testAxis.y) + extents.z * Math.abs(_testAxis.z); // project all 3 vertices of the triangle onto the separating axis
  4163. const p0 = v0.dot(_testAxis);
  4164. const p1 = v1.dot(_testAxis);
  4165. const p2 = v2.dot(_testAxis); // actual test, basically see if either of the most extreme of the triangle points intersects r
  4166. if (Math.max(-Math.max(p0, p1, p2), Math.min(p0, p1, p2)) > r) {
  4167. // points of the projected triangle are outside the projected half-length of the aabb
  4168. // the axis is separating and we can exit
  4169. return false;
  4170. }
  4171. }
  4172. return true;
  4173. }
  4174. const _box$2 = /*@__PURE__*/new Box3();
  4175. const _v1$6 = /*@__PURE__*/new Vector3();
  4176. const _toFarthestPoint = /*@__PURE__*/new Vector3();
  4177. const _toPoint = /*@__PURE__*/new Vector3();
  4178. class Sphere {
  4179. constructor(center = new Vector3(), radius = -1) {
  4180. this.center = center;
  4181. this.radius = radius;
  4182. }
  4183. set(center, radius) {
  4184. this.center.copy(center);
  4185. this.radius = radius;
  4186. return this;
  4187. }
  4188. setFromPoints(points, optionalCenter) {
  4189. const center = this.center;
  4190. if (optionalCenter !== undefined) {
  4191. center.copy(optionalCenter);
  4192. } else {
  4193. _box$2.setFromPoints(points).getCenter(center);
  4194. }
  4195. let maxRadiusSq = 0;
  4196. for (let i = 0, il = points.length; i < il; i++) {
  4197. maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(points[i]));
  4198. }
  4199. this.radius = Math.sqrt(maxRadiusSq);
  4200. return this;
  4201. }
  4202. copy(sphere) {
  4203. this.center.copy(sphere.center);
  4204. this.radius = sphere.radius;
  4205. return this;
  4206. }
  4207. isEmpty() {
  4208. return this.radius < 0;
  4209. }
  4210. makeEmpty() {
  4211. this.center.set(0, 0, 0);
  4212. this.radius = -1;
  4213. return this;
  4214. }
  4215. containsPoint(point) {
  4216. return point.distanceToSquared(this.center) <= this.radius * this.radius;
  4217. }
  4218. distanceToPoint(point) {
  4219. return point.distanceTo(this.center) - this.radius;
  4220. }
  4221. intersectsSphere(sphere) {
  4222. const radiusSum = this.radius + sphere.radius;
  4223. return sphere.center.distanceToSquared(this.center) <= radiusSum * radiusSum;
  4224. }
  4225. intersectsBox(box) {
  4226. return box.intersectsSphere(this);
  4227. }
  4228. intersectsPlane(plane) {
  4229. return Math.abs(plane.distanceToPoint(this.center)) <= this.radius;
  4230. }
  4231. clampPoint(point, target) {
  4232. const deltaLengthSq = this.center.distanceToSquared(point);
  4233. target.copy(point);
  4234. if (deltaLengthSq > this.radius * this.radius) {
  4235. target.sub(this.center).normalize();
  4236. target.multiplyScalar(this.radius).add(this.center);
  4237. }
  4238. return target;
  4239. }
  4240. getBoundingBox(target) {
  4241. if (this.isEmpty()) {
  4242. // Empty sphere produces empty bounding box
  4243. target.makeEmpty();
  4244. return target;
  4245. }
  4246. target.set(this.center, this.center);
  4247. target.expandByScalar(this.radius);
  4248. return target;
  4249. }
  4250. applyMatrix4(matrix) {
  4251. this.center.applyMatrix4(matrix);
  4252. this.radius = this.radius * matrix.getMaxScaleOnAxis();
  4253. return this;
  4254. }
  4255. translate(offset) {
  4256. this.center.add(offset);
  4257. return this;
  4258. }
  4259. expandByPoint(point) {
  4260. // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671
  4261. _toPoint.subVectors(point, this.center);
  4262. const lengthSq = _toPoint.lengthSq();
  4263. if (lengthSq > this.radius * this.radius) {
  4264. const length = Math.sqrt(lengthSq);
  4265. const missingRadiusHalf = (length - this.radius) * 0.5; // Nudge this sphere towards the target point. Add half the missing distance to radius,
  4266. // and the other half to position. This gives a tighter enclosure, instead of if
  4267. // the whole missing distance were just added to radius.
  4268. this.center.add(_toPoint.multiplyScalar(missingRadiusHalf / length));
  4269. this.radius += missingRadiusHalf;
  4270. }
  4271. return this;
  4272. }
  4273. union(sphere) {
  4274. // from https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L759-L769
  4275. // To enclose another sphere into this sphere, we only need to enclose two points:
  4276. // 1) Enclose the farthest point on the other sphere into this sphere.
  4277. // 2) Enclose the opposite point of the farthest point into this sphere.
  4278. if (this.center.equals(sphere.center) === true) {
  4279. _toFarthestPoint.set(0, 0, 1).multiplyScalar(sphere.radius);
  4280. } else {
  4281. _toFarthestPoint.subVectors(sphere.center, this.center).normalize().multiplyScalar(sphere.radius);
  4282. }
  4283. this.expandByPoint(_v1$6.copy(sphere.center).add(_toFarthestPoint));
  4284. this.expandByPoint(_v1$6.copy(sphere.center).sub(_toFarthestPoint));
  4285. return this;
  4286. }
  4287. equals(sphere) {
  4288. return sphere.center.equals(this.center) && sphere.radius === this.radius;
  4289. }
  4290. clone() {
  4291. return new this.constructor().copy(this);
  4292. }
  4293. }
  4294. const _vector$a = /*@__PURE__*/new Vector3();
  4295. const _segCenter = /*@__PURE__*/new Vector3();
  4296. const _segDir = /*@__PURE__*/new Vector3();
  4297. const _diff = /*@__PURE__*/new Vector3();
  4298. const _edge1 = /*@__PURE__*/new Vector3();
  4299. const _edge2 = /*@__PURE__*/new Vector3();
  4300. const _normal$1 = /*@__PURE__*/new Vector3();
  4301. class Ray {
  4302. constructor(origin = new Vector3(), direction = new Vector3(0, 0, -1)) {
  4303. this.origin = origin;
  4304. this.direction = direction;
  4305. }
  4306. set(origin, direction) {
  4307. this.origin.copy(origin);
  4308. this.direction.copy(direction);
  4309. return this;
  4310. }
  4311. copy(ray) {
  4312. this.origin.copy(ray.origin);
  4313. this.direction.copy(ray.direction);
  4314. return this;
  4315. }
  4316. at(t, target) {
  4317. return target.copy(this.direction).multiplyScalar(t).add(this.origin);
  4318. }
  4319. lookAt(v) {
  4320. this.direction.copy(v).sub(this.origin).normalize();
  4321. return this;
  4322. }
  4323. recast(t) {
  4324. this.origin.copy(this.at(t, _vector$a));
  4325. return this;
  4326. }
  4327. closestPointToPoint(point, target) {
  4328. target.subVectors(point, this.origin);
  4329. const directionDistance = target.dot(this.direction);
  4330. if (directionDistance < 0) {
  4331. return target.copy(this.origin);
  4332. }
  4333. return target.copy(this.direction).multiplyScalar(directionDistance).add(this.origin);
  4334. }
  4335. distanceToPoint(point) {
  4336. return Math.sqrt(this.distanceSqToPoint(point));
  4337. }
  4338. distanceSqToPoint(point) {
  4339. const directionDistance = _vector$a.subVectors(point, this.origin).dot(this.direction); // point behind the ray
  4340. if (directionDistance < 0) {
  4341. return this.origin.distanceToSquared(point);
  4342. }
  4343. _vector$a.copy(this.direction).multiplyScalar(directionDistance).add(this.origin);
  4344. return _vector$a.distanceToSquared(point);
  4345. }
  4346. distanceSqToSegment(v0, v1, optionalPointOnRay, optionalPointOnSegment) {
  4347. // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h
  4348. // It returns the min distance between the ray and the segment
  4349. // defined by v0 and v1
  4350. // It can also set two optional targets :
  4351. // - The closest point on the ray
  4352. // - The closest point on the segment
  4353. _segCenter.copy(v0).add(v1).multiplyScalar(0.5);
  4354. _segDir.copy(v1).sub(v0).normalize();
  4355. _diff.copy(this.origin).sub(_segCenter);
  4356. const segExtent = v0.distanceTo(v1) * 0.5;
  4357. const a01 = -this.direction.dot(_segDir);
  4358. const b0 = _diff.dot(this.direction);
  4359. const b1 = -_diff.dot(_segDir);
  4360. const c = _diff.lengthSq();
  4361. const det = Math.abs(1 - a01 * a01);
  4362. let s0, s1, sqrDist, extDet;
  4363. if (det > 0) {
  4364. // The ray and segment are not parallel.
  4365. s0 = a01 * b1 - b0;
  4366. s1 = a01 * b0 - b1;
  4367. extDet = segExtent * det;
  4368. if (s0 >= 0) {
  4369. if (s1 >= -extDet) {
  4370. if (s1 <= extDet) {
  4371. // region 0
  4372. // Minimum at interior points of ray and segment.
  4373. const invDet = 1 / det;
  4374. s0 *= invDet;
  4375. s1 *= invDet;
  4376. sqrDist = s0 * (s0 + a01 * s1 + 2 * b0) + s1 * (a01 * s0 + s1 + 2 * b1) + c;
  4377. } else {
  4378. // region 1
  4379. s1 = segExtent;
  4380. s0 = Math.max(0, -(a01 * s1 + b0));
  4381. sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
  4382. }
  4383. } else {
  4384. // region 5
  4385. s1 = -segExtent;
  4386. s0 = Math.max(0, -(a01 * s1 + b0));
  4387. sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
  4388. }
  4389. } else {
  4390. if (s1 <= -extDet) {
  4391. // region 4
  4392. s0 = Math.max(0, -(-a01 * segExtent + b0));
  4393. s1 = s0 > 0 ? -segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
  4394. sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
  4395. } else if (s1 <= extDet) {
  4396. // region 3
  4397. s0 = 0;
  4398. s1 = Math.min(Math.max(-segExtent, -b1), segExtent);
  4399. sqrDist = s1 * (s1 + 2 * b1) + c;
  4400. } else {
  4401. // region 2
  4402. s0 = Math.max(0, -(a01 * segExtent + b0));
  4403. s1 = s0 > 0 ? segExtent : Math.min(Math.max(-segExtent, -b1), segExtent);
  4404. sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
  4405. }
  4406. }
  4407. } else {
  4408. // Ray and segment are parallel.
  4409. s1 = a01 > 0 ? -segExtent : segExtent;
  4410. s0 = Math.max(0, -(a01 * s1 + b0));
  4411. sqrDist = -s0 * s0 + s1 * (s1 + 2 * b1) + c;
  4412. }
  4413. if (optionalPointOnRay) {
  4414. optionalPointOnRay.copy(this.direction).multiplyScalar(s0).add(this.origin);
  4415. }
  4416. if (optionalPointOnSegment) {
  4417. optionalPointOnSegment.copy(_segDir).multiplyScalar(s1).add(_segCenter);
  4418. }
  4419. return sqrDist;
  4420. }
  4421. intersectSphere(sphere, target) {
  4422. _vector$a.subVectors(sphere.center, this.origin);
  4423. const tca = _vector$a.dot(this.direction);
  4424. const d2 = _vector$a.dot(_vector$a) - tca * tca;
  4425. const radius2 = sphere.radius * sphere.radius;
  4426. if (d2 > radius2) return null;
  4427. const thc = Math.sqrt(radius2 - d2); // t0 = first intersect point - entrance on front of sphere
  4428. const t0 = tca - thc; // t1 = second intersect point - exit point on back of sphere
  4429. const t1 = tca + thc; // test to see if both t0 and t1 are behind the ray - if so, return null
  4430. if (t0 < 0 && t1 < 0) return null; // test to see if t0 is behind the ray:
  4431. // if it is, the ray is inside the sphere, so return the second exit point scaled by t1,
  4432. // in order to always return an intersect point that is in front of the ray.
  4433. if (t0 < 0) return this.at(t1, target); // else t0 is in front of the ray, so return the first collision point scaled by t0
  4434. return this.at(t0, target);
  4435. }
  4436. intersectsSphere(sphere) {
  4437. return this.distanceSqToPoint(sphere.center) <= sphere.radius * sphere.radius;
  4438. }
  4439. distanceToPlane(plane) {
  4440. const denominator = plane.normal.dot(this.direction);
  4441. if (denominator === 0) {
  4442. // line is coplanar, return origin
  4443. if (plane.distanceToPoint(this.origin) === 0) {
  4444. return 0;
  4445. } // Null is preferable to undefined since undefined means.... it is undefined
  4446. return null;
  4447. }
  4448. const t = -(this.origin.dot(plane.normal) + plane.constant) / denominator; // Return if the ray never intersects the plane
  4449. return t >= 0 ? t : null;
  4450. }
  4451. intersectPlane(plane, target) {
  4452. const t = this.distanceToPlane(plane);
  4453. if (t === null) {
  4454. return null;
  4455. }
  4456. return this.at(t, target);
  4457. }
  4458. intersectsPlane(plane) {
  4459. // check if the ray lies on the plane first
  4460. const distToPoint = plane.distanceToPoint(this.origin);
  4461. if (distToPoint === 0) {
  4462. return true;
  4463. }
  4464. const denominator = plane.normal.dot(this.direction);
  4465. if (denominator * distToPoint < 0) {
  4466. return true;
  4467. } // ray origin is behind the plane (and is pointing behind it)
  4468. return false;
  4469. }
  4470. intersectBox(box, target) {
  4471. let tmin, tmax, tymin, tymax, tzmin, tzmax;
  4472. const invdirx = 1 / this.direction.x,
  4473. invdiry = 1 / this.direction.y,
  4474. invdirz = 1 / this.direction.z;
  4475. const origin = this.origin;
  4476. if (invdirx >= 0) {
  4477. tmin = (box.min.x - origin.x) * invdirx;
  4478. tmax = (box.max.x - origin.x) * invdirx;
  4479. } else {
  4480. tmin = (box.max.x - origin.x) * invdirx;
  4481. tmax = (box.min.x - origin.x) * invdirx;
  4482. }
  4483. if (invdiry >= 0) {
  4484. tymin = (box.min.y - origin.y) * invdiry;
  4485. tymax = (box.max.y - origin.y) * invdiry;
  4486. } else {
  4487. tymin = (box.max.y - origin.y) * invdiry;
  4488. tymax = (box.min.y - origin.y) * invdiry;
  4489. }
  4490. if (tmin > tymax || tymin > tmax) return null; // These lines also handle the case where tmin or tmax is NaN
  4491. // (result of 0 * Infinity). x !== x returns true if x is NaN
  4492. if (tymin > tmin || tmin !== tmin) tmin = tymin;
  4493. if (tymax < tmax || tmax !== tmax) tmax = tymax;
  4494. if (invdirz >= 0) {
  4495. tzmin = (box.min.z - origin.z) * invdirz;
  4496. tzmax = (box.max.z - origin.z) * invdirz;
  4497. } else {
  4498. tzmin = (box.max.z - origin.z) * invdirz;
  4499. tzmax = (box.min.z - origin.z) * invdirz;
  4500. }
  4501. if (tmin > tzmax || tzmin > tmax) return null;
  4502. if (tzmin > tmin || tmin !== tmin) tmin = tzmin;
  4503. if (tzmax < tmax || tmax !== tmax) tmax = tzmax; //return point closest to the ray (positive side)
  4504. if (tmax < 0) return null;
  4505. return this.at(tmin >= 0 ? tmin : tmax, target);
  4506. }
  4507. intersectsBox(box) {
  4508. return this.intersectBox(box, _vector$a) !== null;
  4509. }
  4510. intersectTriangle(a, b, c, backfaceCulling, target) {
  4511. // Compute the offset origin, edges, and normal.
  4512. // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h
  4513. _edge1.subVectors(b, a);
  4514. _edge2.subVectors(c, a);
  4515. _normal$1.crossVectors(_edge1, _edge2); // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction,
  4516. // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by
  4517. // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2))
  4518. // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q))
  4519. // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N)
  4520. let DdN = this.direction.dot(_normal$1);
  4521. let sign;
  4522. if (DdN > 0) {
  4523. if (backfaceCulling) return null;
  4524. sign = 1;
  4525. } else if (DdN < 0) {
  4526. sign = -1;
  4527. DdN = -DdN;
  4528. } else {
  4529. return null;
  4530. }
  4531. _diff.subVectors(this.origin, a);
  4532. const DdQxE2 = sign * this.direction.dot(_edge2.crossVectors(_diff, _edge2)); // b1 < 0, no intersection
  4533. if (DdQxE2 < 0) {
  4534. return null;
  4535. }
  4536. const DdE1xQ = sign * this.direction.dot(_edge1.cross(_diff)); // b2 < 0, no intersection
  4537. if (DdE1xQ < 0) {
  4538. return null;
  4539. } // b1+b2 > 1, no intersection
  4540. if (DdQxE2 + DdE1xQ > DdN) {
  4541. return null;
  4542. } // Line intersects triangle, check if ray does.
  4543. const QdN = -sign * _diff.dot(_normal$1); // t < 0, no intersection
  4544. if (QdN < 0) {
  4545. return null;
  4546. } // Ray intersects triangle.
  4547. return this.at(QdN / DdN, target);
  4548. }
  4549. applyMatrix4(matrix4) {
  4550. this.origin.applyMatrix4(matrix4);
  4551. this.direction.transformDirection(matrix4);
  4552. return this;
  4553. }
  4554. equals(ray) {
  4555. return ray.origin.equals(this.origin) && ray.direction.equals(this.direction);
  4556. }
  4557. clone() {
  4558. return new this.constructor().copy(this);
  4559. }
  4560. }
  4561. class Matrix4 {
  4562. constructor() {
  4563. Matrix4.prototype.isMatrix4 = true;
  4564. this.elements = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
  4565. }
  4566. set(n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44) {
  4567. const te = this.elements;
  4568. te[0] = n11;
  4569. te[4] = n12;
  4570. te[8] = n13;
  4571. te[12] = n14;
  4572. te[1] = n21;
  4573. te[5] = n22;
  4574. te[9] = n23;
  4575. te[13] = n24;
  4576. te[2] = n31;
  4577. te[6] = n32;
  4578. te[10] = n33;
  4579. te[14] = n34;
  4580. te[3] = n41;
  4581. te[7] = n42;
  4582. te[11] = n43;
  4583. te[15] = n44;
  4584. return this;
  4585. }
  4586. identity() {
  4587. this.set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
  4588. return this;
  4589. }
  4590. clone() {
  4591. return new Matrix4().fromArray(this.elements);
  4592. }
  4593. copy(m) {
  4594. const te = this.elements;
  4595. const me = m.elements;
  4596. te[0] = me[0];
  4597. te[1] = me[1];
  4598. te[2] = me[2];
  4599. te[3] = me[3];
  4600. te[4] = me[4];
  4601. te[5] = me[5];
  4602. te[6] = me[6];
  4603. te[7] = me[7];
  4604. te[8] = me[8];
  4605. te[9] = me[9];
  4606. te[10] = me[10];
  4607. te[11] = me[11];
  4608. te[12] = me[12];
  4609. te[13] = me[13];
  4610. te[14] = me[14];
  4611. te[15] = me[15];
  4612. return this;
  4613. }
  4614. copyPosition(m) {
  4615. const te = this.elements,
  4616. me = m.elements;
  4617. te[12] = me[12];
  4618. te[13] = me[13];
  4619. te[14] = me[14];
  4620. return this;
  4621. }
  4622. setFromMatrix3(m) {
  4623. const me = m.elements;
  4624. this.set(me[0], me[3], me[6], 0, me[1], me[4], me[7], 0, me[2], me[5], me[8], 0, 0, 0, 0, 1);
  4625. return this;
  4626. }
  4627. extractBasis(xAxis, yAxis, zAxis) {
  4628. xAxis.setFromMatrixColumn(this, 0);
  4629. yAxis.setFromMatrixColumn(this, 1);
  4630. zAxis.setFromMatrixColumn(this, 2);
  4631. return this;
  4632. }
  4633. makeBasis(xAxis, yAxis, zAxis) {
  4634. this.set(xAxis.x, yAxis.x, zAxis.x, 0, xAxis.y, yAxis.y, zAxis.y, 0, xAxis.z, yAxis.z, zAxis.z, 0, 0, 0, 0, 1);
  4635. return this;
  4636. }
  4637. extractRotation(m) {
  4638. // this method does not support reflection matrices
  4639. const te = this.elements;
  4640. const me = m.elements;
  4641. const scaleX = 1 / _v1$5.setFromMatrixColumn(m, 0).length();
  4642. const scaleY = 1 / _v1$5.setFromMatrixColumn(m, 1).length();
  4643. const scaleZ = 1 / _v1$5.setFromMatrixColumn(m, 2).length();
  4644. te[0] = me[0] * scaleX;
  4645. te[1] = me[1] * scaleX;
  4646. te[2] = me[2] * scaleX;
  4647. te[3] = 0;
  4648. te[4] = me[4] * scaleY;
  4649. te[5] = me[5] * scaleY;
  4650. te[6] = me[6] * scaleY;
  4651. te[7] = 0;
  4652. te[8] = me[8] * scaleZ;
  4653. te[9] = me[9] * scaleZ;
  4654. te[10] = me[10] * scaleZ;
  4655. te[11] = 0;
  4656. te[12] = 0;
  4657. te[13] = 0;
  4658. te[14] = 0;
  4659. te[15] = 1;
  4660. return this;
  4661. }
  4662. makeRotationFromEuler(euler) {
  4663. const te = this.elements;
  4664. const x = euler.x,
  4665. y = euler.y,
  4666. z = euler.z;
  4667. const a = Math.cos(x),
  4668. b = Math.sin(x);
  4669. const c = Math.cos(y),
  4670. d = Math.sin(y);
  4671. const e = Math.cos(z),
  4672. f = Math.sin(z);
  4673. if (euler.order === 'XYZ') {
  4674. const ae = a * e,
  4675. af = a * f,
  4676. be = b * e,
  4677. bf = b * f;
  4678. te[0] = c * e;
  4679. te[4] = -c * f;
  4680. te[8] = d;
  4681. te[1] = af + be * d;
  4682. te[5] = ae - bf * d;
  4683. te[9] = -b * c;
  4684. te[2] = bf - ae * d;
  4685. te[6] = be + af * d;
  4686. te[10] = a * c;
  4687. } else if (euler.order === 'YXZ') {
  4688. const ce = c * e,
  4689. cf = c * f,
  4690. de = d * e,
  4691. df = d * f;
  4692. te[0] = ce + df * b;
  4693. te[4] = de * b - cf;
  4694. te[8] = a * d;
  4695. te[1] = a * f;
  4696. te[5] = a * e;
  4697. te[9] = -b;
  4698. te[2] = cf * b - de;
  4699. te[6] = df + ce * b;
  4700. te[10] = a * c;
  4701. } else if (euler.order === 'ZXY') {
  4702. const ce = c * e,
  4703. cf = c * f,
  4704. de = d * e,
  4705. df = d * f;
  4706. te[0] = ce - df * b;
  4707. te[4] = -a * f;
  4708. te[8] = de + cf * b;
  4709. te[1] = cf + de * b;
  4710. te[5] = a * e;
  4711. te[9] = df - ce * b;
  4712. te[2] = -a * d;
  4713. te[6] = b;
  4714. te[10] = a * c;
  4715. } else if (euler.order === 'ZYX') {
  4716. const ae = a * e,
  4717. af = a * f,
  4718. be = b * e,
  4719. bf = b * f;
  4720. te[0] = c * e;
  4721. te[4] = be * d - af;
  4722. te[8] = ae * d + bf;
  4723. te[1] = c * f;
  4724. te[5] = bf * d + ae;
  4725. te[9] = af * d - be;
  4726. te[2] = -d;
  4727. te[6] = b * c;
  4728. te[10] = a * c;
  4729. } else if (euler.order === 'YZX') {
  4730. const ac = a * c,
  4731. ad = a * d,
  4732. bc = b * c,
  4733. bd = b * d;
  4734. te[0] = c * e;
  4735. te[4] = bd - ac * f;
  4736. te[8] = bc * f + ad;
  4737. te[1] = f;
  4738. te[5] = a * e;
  4739. te[9] = -b * e;
  4740. te[2] = -d * e;
  4741. te[6] = ad * f + bc;
  4742. te[10] = ac - bd * f;
  4743. } else if (euler.order === 'XZY') {
  4744. const ac = a * c,
  4745. ad = a * d,
  4746. bc = b * c,
  4747. bd = b * d;
  4748. te[0] = c * e;
  4749. te[4] = -f;
  4750. te[8] = d * e;
  4751. te[1] = ac * f + bd;
  4752. te[5] = a * e;
  4753. te[9] = ad * f - bc;
  4754. te[2] = bc * f - ad;
  4755. te[6] = b * e;
  4756. te[10] = bd * f + ac;
  4757. } // bottom row
  4758. te[3] = 0;
  4759. te[7] = 0;
  4760. te[11] = 0; // last column
  4761. te[12] = 0;
  4762. te[13] = 0;
  4763. te[14] = 0;
  4764. te[15] = 1;
  4765. return this;
  4766. }
  4767. makeRotationFromQuaternion(q) {
  4768. return this.compose(_zero, q, _one);
  4769. }
  4770. lookAt(eye, target, up) {
  4771. const te = this.elements;
  4772. _z.subVectors(eye, target);
  4773. if (_z.lengthSq() === 0) {
  4774. // eye and target are in the same position
  4775. _z.z = 1;
  4776. }
  4777. _z.normalize();
  4778. _x.crossVectors(up, _z);
  4779. if (_x.lengthSq() === 0) {
  4780. // up and z are parallel
  4781. if (Math.abs(up.z) === 1) {
  4782. _z.x += 0.0001;
  4783. } else {
  4784. _z.z += 0.0001;
  4785. }
  4786. _z.normalize();
  4787. _x.crossVectors(up, _z);
  4788. }
  4789. _x.normalize();
  4790. _y.crossVectors(_z, _x);
  4791. te[0] = _x.x;
  4792. te[4] = _y.x;
  4793. te[8] = _z.x;
  4794. te[1] = _x.y;
  4795. te[5] = _y.y;
  4796. te[9] = _z.y;
  4797. te[2] = _x.z;
  4798. te[6] = _y.z;
  4799. te[10] = _z.z;
  4800. return this;
  4801. }
  4802. multiply(m) {
  4803. return this.multiplyMatrices(this, m);
  4804. }
  4805. premultiply(m) {
  4806. return this.multiplyMatrices(m, this);
  4807. }
  4808. multiplyMatrices(a, b) {
  4809. const ae = a.elements;
  4810. const be = b.elements;
  4811. const te = this.elements;
  4812. const a11 = ae[0],
  4813. a12 = ae[4],
  4814. a13 = ae[8],
  4815. a14 = ae[12];
  4816. const a21 = ae[1],
  4817. a22 = ae[5],
  4818. a23 = ae[9],
  4819. a24 = ae[13];
  4820. const a31 = ae[2],
  4821. a32 = ae[6],
  4822. a33 = ae[10],
  4823. a34 = ae[14];
  4824. const a41 = ae[3],
  4825. a42 = ae[7],
  4826. a43 = ae[11],
  4827. a44 = ae[15];
  4828. const b11 = be[0],
  4829. b12 = be[4],
  4830. b13 = be[8],
  4831. b14 = be[12];
  4832. const b21 = be[1],
  4833. b22 = be[5],
  4834. b23 = be[9],
  4835. b24 = be[13];
  4836. const b31 = be[2],
  4837. b32 = be[6],
  4838. b33 = be[10],
  4839. b34 = be[14];
  4840. const b41 = be[3],
  4841. b42 = be[7],
  4842. b43 = be[11],
  4843. b44 = be[15];
  4844. te[0] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41;
  4845. te[4] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42;
  4846. te[8] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43;
  4847. te[12] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44;
  4848. te[1] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41;
  4849. te[5] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42;
  4850. te[9] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43;
  4851. te[13] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44;
  4852. te[2] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41;
  4853. te[6] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42;
  4854. te[10] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43;
  4855. te[14] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44;
  4856. te[3] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41;
  4857. te[7] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42;
  4858. te[11] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43;
  4859. te[15] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44;
  4860. return this;
  4861. }
  4862. multiplyScalar(s) {
  4863. const te = this.elements;
  4864. te[0] *= s;
  4865. te[4] *= s;
  4866. te[8] *= s;
  4867. te[12] *= s;
  4868. te[1] *= s;
  4869. te[5] *= s;
  4870. te[9] *= s;
  4871. te[13] *= s;
  4872. te[2] *= s;
  4873. te[6] *= s;
  4874. te[10] *= s;
  4875. te[14] *= s;
  4876. te[3] *= s;
  4877. te[7] *= s;
  4878. te[11] *= s;
  4879. te[15] *= s;
  4880. return this;
  4881. }
  4882. determinant() {
  4883. const te = this.elements;
  4884. const n11 = te[0],
  4885. n12 = te[4],
  4886. n13 = te[8],
  4887. n14 = te[12];
  4888. const n21 = te[1],
  4889. n22 = te[5],
  4890. n23 = te[9],
  4891. n24 = te[13];
  4892. const n31 = te[2],
  4893. n32 = te[6],
  4894. n33 = te[10],
  4895. n34 = te[14];
  4896. const n41 = te[3],
  4897. n42 = te[7],
  4898. n43 = te[11],
  4899. n44 = te[15]; //TODO: make this more efficient
  4900. //( based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm )
  4901. return n41 * (+n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34) + n42 * (+n11 * n23 * n34 - n11 * n24 * n33 + n14 * n21 * n33 - n13 * n21 * n34 + n13 * n24 * n31 - n14 * n23 * n31) + n43 * (+n11 * n24 * n32 - n11 * n22 * n34 - n14 * n21 * n32 + n12 * n21 * n34 + n14 * n22 * n31 - n12 * n24 * n31) + n44 * (-n13 * n22 * n31 - n11 * n23 * n32 + n11 * n22 * n33 + n13 * n21 * n32 - n12 * n21 * n33 + n12 * n23 * n31);
  4902. }
  4903. transpose() {
  4904. const te = this.elements;
  4905. let tmp;
  4906. tmp = te[1];
  4907. te[1] = te[4];
  4908. te[4] = tmp;
  4909. tmp = te[2];
  4910. te[2] = te[8];
  4911. te[8] = tmp;
  4912. tmp = te[6];
  4913. te[6] = te[9];
  4914. te[9] = tmp;
  4915. tmp = te[3];
  4916. te[3] = te[12];
  4917. te[12] = tmp;
  4918. tmp = te[7];
  4919. te[7] = te[13];
  4920. te[13] = tmp;
  4921. tmp = te[11];
  4922. te[11] = te[14];
  4923. te[14] = tmp;
  4924. return this;
  4925. }
  4926. setPosition(x, y, z) {
  4927. const te = this.elements;
  4928. if (x.isVector3) {
  4929. te[12] = x.x;
  4930. te[13] = x.y;
  4931. te[14] = x.z;
  4932. } else {
  4933. te[12] = x;
  4934. te[13] = y;
  4935. te[14] = z;
  4936. }
  4937. return this;
  4938. }
  4939. invert() {
  4940. // based on http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
  4941. const te = this.elements,
  4942. n11 = te[0],
  4943. n21 = te[1],
  4944. n31 = te[2],
  4945. n41 = te[3],
  4946. n12 = te[4],
  4947. n22 = te[5],
  4948. n32 = te[6],
  4949. n42 = te[7],
  4950. n13 = te[8],
  4951. n23 = te[9],
  4952. n33 = te[10],
  4953. n43 = te[11],
  4954. n14 = te[12],
  4955. n24 = te[13],
  4956. n34 = te[14],
  4957. n44 = te[15],
  4958. t11 = n23 * n34 * n42 - n24 * n33 * n42 + n24 * n32 * n43 - n22 * n34 * n43 - n23 * n32 * n44 + n22 * n33 * n44,
  4959. t12 = n14 * n33 * n42 - n13 * n34 * n42 - n14 * n32 * n43 + n12 * n34 * n43 + n13 * n32 * n44 - n12 * n33 * n44,
  4960. t13 = n13 * n24 * n42 - n14 * n23 * n42 + n14 * n22 * n43 - n12 * n24 * n43 - n13 * n22 * n44 + n12 * n23 * n44,
  4961. t14 = n14 * n23 * n32 - n13 * n24 * n32 - n14 * n22 * n33 + n12 * n24 * n33 + n13 * n22 * n34 - n12 * n23 * n34;
  4962. const det = n11 * t11 + n21 * t12 + n31 * t13 + n41 * t14;
  4963. if (det === 0) return this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
  4964. const detInv = 1 / det;
  4965. te[0] = t11 * detInv;
  4966. te[1] = (n24 * n33 * n41 - n23 * n34 * n41 - n24 * n31 * n43 + n21 * n34 * n43 + n23 * n31 * n44 - n21 * n33 * n44) * detInv;
  4967. te[2] = (n22 * n34 * n41 - n24 * n32 * n41 + n24 * n31 * n42 - n21 * n34 * n42 - n22 * n31 * n44 + n21 * n32 * n44) * detInv;
  4968. te[3] = (n23 * n32 * n41 - n22 * n33 * n41 - n23 * n31 * n42 + n21 * n33 * n42 + n22 * n31 * n43 - n21 * n32 * n43) * detInv;
  4969. te[4] = t12 * detInv;
  4970. te[5] = (n13 * n34 * n41 - n14 * n33 * n41 + n14 * n31 * n43 - n11 * n34 * n43 - n13 * n31 * n44 + n11 * n33 * n44) * detInv;
  4971. te[6] = (n14 * n32 * n41 - n12 * n34 * n41 - n14 * n31 * n42 + n11 * n34 * n42 + n12 * n31 * n44 - n11 * n32 * n44) * detInv;
  4972. te[7] = (n12 * n33 * n41 - n13 * n32 * n41 + n13 * n31 * n42 - n11 * n33 * n42 - n12 * n31 * n43 + n11 * n32 * n43) * detInv;
  4973. te[8] = t13 * detInv;
  4974. te[9] = (n14 * n23 * n41 - n13 * n24 * n41 - n14 * n21 * n43 + n11 * n24 * n43 + n13 * n21 * n44 - n11 * n23 * n44) * detInv;
  4975. te[10] = (n12 * n24 * n41 - n14 * n22 * n41 + n14 * n21 * n42 - n11 * n24 * n42 - n12 * n21 * n44 + n11 * n22 * n44) * detInv;
  4976. te[11] = (n13 * n22 * n41 - n12 * n23 * n41 - n13 * n21 * n42 + n11 * n23 * n42 + n12 * n21 * n43 - n11 * n22 * n43) * detInv;
  4977. te[12] = t14 * detInv;
  4978. te[13] = (n13 * n24 * n31 - n14 * n23 * n31 + n14 * n21 * n33 - n11 * n24 * n33 - n13 * n21 * n34 + n11 * n23 * n34) * detInv;
  4979. te[14] = (n14 * n22 * n31 - n12 * n24 * n31 - n14 * n21 * n32 + n11 * n24 * n32 + n12 * n21 * n34 - n11 * n22 * n34) * detInv;
  4980. te[15] = (n12 * n23 * n31 - n13 * n22 * n31 + n13 * n21 * n32 - n11 * n23 * n32 - n12 * n21 * n33 + n11 * n22 * n33) * detInv;
  4981. return this;
  4982. }
  4983. scale(v) {
  4984. const te = this.elements;
  4985. const x = v.x,
  4986. y = v.y,
  4987. z = v.z;
  4988. te[0] *= x;
  4989. te[4] *= y;
  4990. te[8] *= z;
  4991. te[1] *= x;
  4992. te[5] *= y;
  4993. te[9] *= z;
  4994. te[2] *= x;
  4995. te[6] *= y;
  4996. te[10] *= z;
  4997. te[3] *= x;
  4998. te[7] *= y;
  4999. te[11] *= z;
  5000. return this;
  5001. }
  5002. getMaxScaleOnAxis() {
  5003. const te = this.elements;
  5004. const scaleXSq = te[0] * te[0] + te[1] * te[1] + te[2] * te[2];
  5005. const scaleYSq = te[4] * te[4] + te[5] * te[5] + te[6] * te[6];
  5006. const scaleZSq = te[8] * te[8] + te[9] * te[9] + te[10] * te[10];
  5007. return Math.sqrt(Math.max(scaleXSq, scaleYSq, scaleZSq));
  5008. }
  5009. makeTranslation(x, y, z) {
  5010. this.set(1, 0, 0, x, 0, 1, 0, y, 0, 0, 1, z, 0, 0, 0, 1);
  5011. return this;
  5012. }
  5013. makeRotationX(theta) {
  5014. const c = Math.cos(theta),
  5015. s = Math.sin(theta);
  5016. this.set(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1);
  5017. return this;
  5018. }
  5019. makeRotationY(theta) {
  5020. const c = Math.cos(theta),
  5021. s = Math.sin(theta);
  5022. this.set(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1);
  5023. return this;
  5024. }
  5025. makeRotationZ(theta) {
  5026. const c = Math.cos(theta),
  5027. s = Math.sin(theta);
  5028. this.set(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
  5029. return this;
  5030. }
  5031. makeRotationAxis(axis, angle) {
  5032. // Based on http://www.gamedev.net/reference/articles/article1199.asp
  5033. const c = Math.cos(angle);
  5034. const s = Math.sin(angle);
  5035. const t = 1 - c;
  5036. const x = axis.x,
  5037. y = axis.y,
  5038. z = axis.z;
  5039. const tx = t * x,
  5040. ty = t * y;
  5041. this.set(tx * x + c, tx * y - s * z, tx * z + s * y, 0, tx * y + s * z, ty * y + c, ty * z - s * x, 0, tx * z - s * y, ty * z + s * x, t * z * z + c, 0, 0, 0, 0, 1);
  5042. return this;
  5043. }
  5044. makeScale(x, y, z) {
  5045. this.set(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1);
  5046. return this;
  5047. }
  5048. makeShear(xy, xz, yx, yz, zx, zy) {
  5049. this.set(1, yx, zx, 0, xy, 1, zy, 0, xz, yz, 1, 0, 0, 0, 0, 1);
  5050. return this;
  5051. }
  5052. compose(position, quaternion, scale) {
  5053. const te = this.elements;
  5054. const x = quaternion._x,
  5055. y = quaternion._y,
  5056. z = quaternion._z,
  5057. w = quaternion._w;
  5058. const x2 = x + x,
  5059. y2 = y + y,
  5060. z2 = z + z;
  5061. const xx = x * x2,
  5062. xy = x * y2,
  5063. xz = x * z2;
  5064. const yy = y * y2,
  5065. yz = y * z2,
  5066. zz = z * z2;
  5067. const wx = w * x2,
  5068. wy = w * y2,
  5069. wz = w * z2;
  5070. const sx = scale.x,
  5071. sy = scale.y,
  5072. sz = scale.z;
  5073. te[0] = (1 - (yy + zz)) * sx;
  5074. te[1] = (xy + wz) * sx;
  5075. te[2] = (xz - wy) * sx;
  5076. te[3] = 0;
  5077. te[4] = (xy - wz) * sy;
  5078. te[5] = (1 - (xx + zz)) * sy;
  5079. te[6] = (yz + wx) * sy;
  5080. te[7] = 0;
  5081. te[8] = (xz + wy) * sz;
  5082. te[9] = (yz - wx) * sz;
  5083. te[10] = (1 - (xx + yy)) * sz;
  5084. te[11] = 0;
  5085. te[12] = position.x;
  5086. te[13] = position.y;
  5087. te[14] = position.z;
  5088. te[15] = 1;
  5089. return this;
  5090. }
  5091. decompose(position, quaternion, scale) {
  5092. const te = this.elements;
  5093. let sx = _v1$5.set(te[0], te[1], te[2]).length();
  5094. const sy = _v1$5.set(te[4], te[5], te[6]).length();
  5095. const sz = _v1$5.set(te[8], te[9], te[10]).length(); // if determine is negative, we need to invert one scale
  5096. const det = this.determinant();
  5097. if (det < 0) sx = -sx;
  5098. position.x = te[12];
  5099. position.y = te[13];
  5100. position.z = te[14]; // scale the rotation part
  5101. _m1$2.copy(this);
  5102. const invSX = 1 / sx;
  5103. const invSY = 1 / sy;
  5104. const invSZ = 1 / sz;
  5105. _m1$2.elements[0] *= invSX;
  5106. _m1$2.elements[1] *= invSX;
  5107. _m1$2.elements[2] *= invSX;
  5108. _m1$2.elements[4] *= invSY;
  5109. _m1$2.elements[5] *= invSY;
  5110. _m1$2.elements[6] *= invSY;
  5111. _m1$2.elements[8] *= invSZ;
  5112. _m1$2.elements[9] *= invSZ;
  5113. _m1$2.elements[10] *= invSZ;
  5114. quaternion.setFromRotationMatrix(_m1$2);
  5115. scale.x = sx;
  5116. scale.y = sy;
  5117. scale.z = sz;
  5118. return this;
  5119. }
  5120. makePerspective(left, right, top, bottom, near, far) {
  5121. const te = this.elements;
  5122. const x = 2 * near / (right - left);
  5123. const y = 2 * near / (top - bottom);
  5124. const a = (right + left) / (right - left);
  5125. const b = (top + bottom) / (top - bottom);
  5126. const c = -(far + near) / (far - near);
  5127. const d = -2 * far * near / (far - near);
  5128. te[0] = x;
  5129. te[4] = 0;
  5130. te[8] = a;
  5131. te[12] = 0;
  5132. te[1] = 0;
  5133. te[5] = y;
  5134. te[9] = b;
  5135. te[13] = 0;
  5136. te[2] = 0;
  5137. te[6] = 0;
  5138. te[10] = c;
  5139. te[14] = d;
  5140. te[3] = 0;
  5141. te[7] = 0;
  5142. te[11] = -1;
  5143. te[15] = 0;
  5144. return this;
  5145. }
  5146. makeOrthographic(left, right, top, bottom, near, far) {
  5147. const te = this.elements;
  5148. const w = 1.0 / (right - left);
  5149. const h = 1.0 / (top - bottom);
  5150. const p = 1.0 / (far - near);
  5151. const x = (right + left) * w;
  5152. const y = (top + bottom) * h;
  5153. const z = (far + near) * p;
  5154. te[0] = 2 * w;
  5155. te[4] = 0;
  5156. te[8] = 0;
  5157. te[12] = -x;
  5158. te[1] = 0;
  5159. te[5] = 2 * h;
  5160. te[9] = 0;
  5161. te[13] = -y;
  5162. te[2] = 0;
  5163. te[6] = 0;
  5164. te[10] = -2 * p;
  5165. te[14] = -z;
  5166. te[3] = 0;
  5167. te[7] = 0;
  5168. te[11] = 0;
  5169. te[15] = 1;
  5170. return this;
  5171. }
  5172. equals(matrix) {
  5173. const te = this.elements;
  5174. const me = matrix.elements;
  5175. for (let i = 0; i < 16; i++) {
  5176. if (te[i] !== me[i]) return false;
  5177. }
  5178. return true;
  5179. }
  5180. fromArray(array, offset = 0) {
  5181. for (let i = 0; i < 16; i++) {
  5182. this.elements[i] = array[i + offset];
  5183. }
  5184. return this;
  5185. }
  5186. toArray(array = [], offset = 0) {
  5187. const te = this.elements;
  5188. array[offset] = te[0];
  5189. array[offset + 1] = te[1];
  5190. array[offset + 2] = te[2];
  5191. array[offset + 3] = te[3];
  5192. array[offset + 4] = te[4];
  5193. array[offset + 5] = te[5];
  5194. array[offset + 6] = te[6];
  5195. array[offset + 7] = te[7];
  5196. array[offset + 8] = te[8];
  5197. array[offset + 9] = te[9];
  5198. array[offset + 10] = te[10];
  5199. array[offset + 11] = te[11];
  5200. array[offset + 12] = te[12];
  5201. array[offset + 13] = te[13];
  5202. array[offset + 14] = te[14];
  5203. array[offset + 15] = te[15];
  5204. return array;
  5205. }
  5206. }
  5207. const _v1$5 = /*@__PURE__*/new Vector3();
  5208. const _m1$2 = /*@__PURE__*/new Matrix4();
  5209. const _zero = /*@__PURE__*/new Vector3(0, 0, 0);
  5210. const _one = /*@__PURE__*/new Vector3(1, 1, 1);
  5211. const _x = /*@__PURE__*/new Vector3();
  5212. const _y = /*@__PURE__*/new Vector3();
  5213. const _z = /*@__PURE__*/new Vector3();
  5214. const _matrix$1 = /*@__PURE__*/new Matrix4();
  5215. const _quaternion$3 = /*@__PURE__*/new Quaternion();
  5216. class Euler {
  5217. constructor(x = 0, y = 0, z = 0, order = Euler.DefaultOrder) {
  5218. this.isEuler = true;
  5219. this._x = x;
  5220. this._y = y;
  5221. this._z = z;
  5222. this._order = order;
  5223. }
  5224. get x() {
  5225. return this._x;
  5226. }
  5227. set x(value) {
  5228. this._x = value;
  5229. this._onChangeCallback();
  5230. }
  5231. get y() {
  5232. return this._y;
  5233. }
  5234. set y(value) {
  5235. this._y = value;
  5236. this._onChangeCallback();
  5237. }
  5238. get z() {
  5239. return this._z;
  5240. }
  5241. set z(value) {
  5242. this._z = value;
  5243. this._onChangeCallback();
  5244. }
  5245. get order() {
  5246. return this._order;
  5247. }
  5248. set order(value) {
  5249. this._order = value;
  5250. this._onChangeCallback();
  5251. }
  5252. set(x, y, z, order = this._order) {
  5253. this._x = x;
  5254. this._y = y;
  5255. this._z = z;
  5256. this._order = order;
  5257. this._onChangeCallback();
  5258. return this;
  5259. }
  5260. clone() {
  5261. return new this.constructor(this._x, this._y, this._z, this._order);
  5262. }
  5263. copy(euler) {
  5264. this._x = euler._x;
  5265. this._y = euler._y;
  5266. this._z = euler._z;
  5267. this._order = euler._order;
  5268. this._onChangeCallback();
  5269. return this;
  5270. }
  5271. setFromRotationMatrix(m, order = this._order, update = true) {
  5272. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  5273. const te = m.elements;
  5274. const m11 = te[0],
  5275. m12 = te[4],
  5276. m13 = te[8];
  5277. const m21 = te[1],
  5278. m22 = te[5],
  5279. m23 = te[9];
  5280. const m31 = te[2],
  5281. m32 = te[6],
  5282. m33 = te[10];
  5283. switch (order) {
  5284. case 'XYZ':
  5285. this._y = Math.asin(clamp(m13, -1, 1));
  5286. if (Math.abs(m13) < 0.9999999) {
  5287. this._x = Math.atan2(-m23, m33);
  5288. this._z = Math.atan2(-m12, m11);
  5289. } else {
  5290. this._x = Math.atan2(m32, m22);
  5291. this._z = 0;
  5292. }
  5293. break;
  5294. case 'YXZ':
  5295. this._x = Math.asin(-clamp(m23, -1, 1));
  5296. if (Math.abs(m23) < 0.9999999) {
  5297. this._y = Math.atan2(m13, m33);
  5298. this._z = Math.atan2(m21, m22);
  5299. } else {
  5300. this._y = Math.atan2(-m31, m11);
  5301. this._z = 0;
  5302. }
  5303. break;
  5304. case 'ZXY':
  5305. this._x = Math.asin(clamp(m32, -1, 1));
  5306. if (Math.abs(m32) < 0.9999999) {
  5307. this._y = Math.atan2(-m31, m33);
  5308. this._z = Math.atan2(-m12, m22);
  5309. } else {
  5310. this._y = 0;
  5311. this._z = Math.atan2(m21, m11);
  5312. }
  5313. break;
  5314. case 'ZYX':
  5315. this._y = Math.asin(-clamp(m31, -1, 1));
  5316. if (Math.abs(m31) < 0.9999999) {
  5317. this._x = Math.atan2(m32, m33);
  5318. this._z = Math.atan2(m21, m11);
  5319. } else {
  5320. this._x = 0;
  5321. this._z = Math.atan2(-m12, m22);
  5322. }
  5323. break;
  5324. case 'YZX':
  5325. this._z = Math.asin(clamp(m21, -1, 1));
  5326. if (Math.abs(m21) < 0.9999999) {
  5327. this._x = Math.atan2(-m23, m22);
  5328. this._y = Math.atan2(-m31, m11);
  5329. } else {
  5330. this._x = 0;
  5331. this._y = Math.atan2(m13, m33);
  5332. }
  5333. break;
  5334. case 'XZY':
  5335. this._z = Math.asin(-clamp(m12, -1, 1));
  5336. if (Math.abs(m12) < 0.9999999) {
  5337. this._x = Math.atan2(m32, m22);
  5338. this._y = Math.atan2(m13, m11);
  5339. } else {
  5340. this._x = Math.atan2(-m23, m33);
  5341. this._y = 0;
  5342. }
  5343. break;
  5344. default:
  5345. console.warn('THREE.Euler: .setFromRotationMatrix() encountered an unknown order: ' + order);
  5346. }
  5347. this._order = order;
  5348. if (update === true) this._onChangeCallback();
  5349. return this;
  5350. }
  5351. setFromQuaternion(q, order, update) {
  5352. _matrix$1.makeRotationFromQuaternion(q);
  5353. return this.setFromRotationMatrix(_matrix$1, order, update);
  5354. }
  5355. setFromVector3(v, order = this._order) {
  5356. return this.set(v.x, v.y, v.z, order);
  5357. }
  5358. reorder(newOrder) {
  5359. // WARNING: this discards revolution information -bhouston
  5360. _quaternion$3.setFromEuler(this);
  5361. return this.setFromQuaternion(_quaternion$3, newOrder);
  5362. }
  5363. equals(euler) {
  5364. return euler._x === this._x && euler._y === this._y && euler._z === this._z && euler._order === this._order;
  5365. }
  5366. fromArray(array) {
  5367. this._x = array[0];
  5368. this._y = array[1];
  5369. this._z = array[2];
  5370. if (array[3] !== undefined) this._order = array[3];
  5371. this._onChangeCallback();
  5372. return this;
  5373. }
  5374. toArray(array = [], offset = 0) {
  5375. array[offset] = this._x;
  5376. array[offset + 1] = this._y;
  5377. array[offset + 2] = this._z;
  5378. array[offset + 3] = this._order;
  5379. return array;
  5380. }
  5381. _onChange(callback) {
  5382. this._onChangeCallback = callback;
  5383. return this;
  5384. }
  5385. _onChangeCallback() {}
  5386. *[Symbol.iterator]() {
  5387. yield this._x;
  5388. yield this._y;
  5389. yield this._z;
  5390. yield this._order;
  5391. } // @deprecated since r138, 02cf0df1cb4575d5842fef9c85bb5a89fe020d53
  5392. toVector3() {
  5393. console.error('THREE.Euler: .toVector3() has been removed. Use Vector3.setFromEuler() instead');
  5394. }
  5395. }
  5396. Euler.DefaultOrder = 'XYZ';
  5397. Euler.RotationOrders = ['XYZ', 'YZX', 'ZXY', 'XZY', 'YXZ', 'ZYX'];
  5398. class Layers {
  5399. constructor() {
  5400. this.mask = 1 | 0;
  5401. }
  5402. set(channel) {
  5403. this.mask = (1 << channel | 0) >>> 0;
  5404. }
  5405. enable(channel) {
  5406. this.mask |= 1 << channel | 0;
  5407. }
  5408. enableAll() {
  5409. this.mask = 0xffffffff | 0;
  5410. }
  5411. toggle(channel) {
  5412. this.mask ^= 1 << channel | 0;
  5413. }
  5414. disable(channel) {
  5415. this.mask &= ~(1 << channel | 0);
  5416. }
  5417. disableAll() {
  5418. this.mask = 0;
  5419. }
  5420. test(layers) {
  5421. return (this.mask & layers.mask) !== 0;
  5422. }
  5423. isEnabled(channel) {
  5424. return (this.mask & (1 << channel | 0)) !== 0;
  5425. }
  5426. }
  5427. let _object3DId = 0;
  5428. const _v1$4 = /*@__PURE__*/new Vector3();
  5429. const _q1 = /*@__PURE__*/new Quaternion();
  5430. const _m1$1 = /*@__PURE__*/new Matrix4();
  5431. const _target = /*@__PURE__*/new Vector3();
  5432. const _position$3 = /*@__PURE__*/new Vector3();
  5433. const _scale$2 = /*@__PURE__*/new Vector3();
  5434. const _quaternion$2 = /*@__PURE__*/new Quaternion();
  5435. const _xAxis = /*@__PURE__*/new Vector3(1, 0, 0);
  5436. const _yAxis = /*@__PURE__*/new Vector3(0, 1, 0);
  5437. const _zAxis = /*@__PURE__*/new Vector3(0, 0, 1);
  5438. const _addedEvent = {
  5439. type: 'added'
  5440. };
  5441. const _removedEvent = {
  5442. type: 'removed'
  5443. };
  5444. class Object3D extends EventDispatcher {
  5445. constructor() {
  5446. super();
  5447. this.isObject3D = true;
  5448. Object.defineProperty(this, 'id', {
  5449. value: _object3DId++
  5450. });
  5451. this.uuid = generateUUID();
  5452. this.name = '';
  5453. this.type = 'Object3D';
  5454. this.parent = null;
  5455. this.children = [];
  5456. this.up = Object3D.DefaultUp.clone();
  5457. const position = new Vector3();
  5458. const rotation = new Euler();
  5459. const quaternion = new Quaternion();
  5460. const scale = new Vector3(1, 1, 1);
  5461. function onRotationChange() {
  5462. quaternion.setFromEuler(rotation, false);
  5463. }
  5464. function onQuaternionChange() {
  5465. rotation.setFromQuaternion(quaternion, undefined, false);
  5466. }
  5467. rotation._onChange(onRotationChange);
  5468. quaternion._onChange(onQuaternionChange);
  5469. Object.defineProperties(this, {
  5470. position: {
  5471. configurable: true,
  5472. enumerable: true,
  5473. value: position
  5474. },
  5475. rotation: {
  5476. configurable: true,
  5477. enumerable: true,
  5478. value: rotation
  5479. },
  5480. quaternion: {
  5481. configurable: true,
  5482. enumerable: true,
  5483. value: quaternion
  5484. },
  5485. scale: {
  5486. configurable: true,
  5487. enumerable: true,
  5488. value: scale
  5489. },
  5490. modelViewMatrix: {
  5491. value: new Matrix4()
  5492. },
  5493. normalMatrix: {
  5494. value: new Matrix3()
  5495. }
  5496. });
  5497. this.matrix = new Matrix4();
  5498. this.matrixWorld = new Matrix4();
  5499. this.matrixAutoUpdate = Object3D.DefaultMatrixAutoUpdate;
  5500. this.matrixWorldNeedsUpdate = false;
  5501. this.layers = new Layers();
  5502. this.visible = true;
  5503. this.castShadow = false;
  5504. this.receiveShadow = false;
  5505. this.frustumCulled = true;
  5506. this.renderOrder = 0;
  5507. this.animations = [];
  5508. this.userData = {};
  5509. }
  5510. onBeforeRender() {}
  5511. onAfterRender() {}
  5512. applyMatrix4(matrix) {
  5513. if (this.matrixAutoUpdate) this.updateMatrix();
  5514. this.matrix.premultiply(matrix);
  5515. this.matrix.decompose(this.position, this.quaternion, this.scale);
  5516. }
  5517. applyQuaternion(q) {
  5518. this.quaternion.premultiply(q);
  5519. return this;
  5520. }
  5521. setRotationFromAxisAngle(axis, angle) {
  5522. // assumes axis is normalized
  5523. this.quaternion.setFromAxisAngle(axis, angle);
  5524. }
  5525. setRotationFromEuler(euler) {
  5526. this.quaternion.setFromEuler(euler, true);
  5527. }
  5528. setRotationFromMatrix(m) {
  5529. // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
  5530. this.quaternion.setFromRotationMatrix(m);
  5531. }
  5532. setRotationFromQuaternion(q) {
  5533. // assumes q is normalized
  5534. this.quaternion.copy(q);
  5535. }
  5536. rotateOnAxis(axis, angle) {
  5537. // rotate object on axis in object space
  5538. // axis is assumed to be normalized
  5539. _q1.setFromAxisAngle(axis, angle);
  5540. this.quaternion.multiply(_q1);
  5541. return this;
  5542. }
  5543. rotateOnWorldAxis(axis, angle) {
  5544. // rotate object on axis in world space
  5545. // axis is assumed to be normalized
  5546. // method assumes no rotated parent
  5547. _q1.setFromAxisAngle(axis, angle);
  5548. this.quaternion.premultiply(_q1);
  5549. return this;
  5550. }
  5551. rotateX(angle) {
  5552. return this.rotateOnAxis(_xAxis, angle);
  5553. }
  5554. rotateY(angle) {
  5555. return this.rotateOnAxis(_yAxis, angle);
  5556. }
  5557. rotateZ(angle) {
  5558. return this.rotateOnAxis(_zAxis, angle);
  5559. }
  5560. translateOnAxis(axis, distance) {
  5561. // translate object by distance along axis in object space
  5562. // axis is assumed to be normalized
  5563. _v1$4.copy(axis).applyQuaternion(this.quaternion);
  5564. this.position.add(_v1$4.multiplyScalar(distance));
  5565. return this;
  5566. }
  5567. translateX(distance) {
  5568. return this.translateOnAxis(_xAxis, distance);
  5569. }
  5570. translateY(distance) {
  5571. return this.translateOnAxis(_yAxis, distance);
  5572. }
  5573. translateZ(distance) {
  5574. return this.translateOnAxis(_zAxis, distance);
  5575. }
  5576. localToWorld(vector) {
  5577. return vector.applyMatrix4(this.matrixWorld);
  5578. }
  5579. worldToLocal(vector) {
  5580. return vector.applyMatrix4(_m1$1.copy(this.matrixWorld).invert());
  5581. }
  5582. lookAt(x, y, z) {
  5583. // This method does not support objects having non-uniformly-scaled parent(s)
  5584. if (x.isVector3) {
  5585. _target.copy(x);
  5586. } else {
  5587. _target.set(x, y, z);
  5588. }
  5589. const parent = this.parent;
  5590. this.updateWorldMatrix(true, false);
  5591. _position$3.setFromMatrixPosition(this.matrixWorld);
  5592. if (this.isCamera || this.isLight) {
  5593. _m1$1.lookAt(_position$3, _target, this.up);
  5594. } else {
  5595. _m1$1.lookAt(_target, _position$3, this.up);
  5596. }
  5597. this.quaternion.setFromRotationMatrix(_m1$1);
  5598. if (parent) {
  5599. _m1$1.extractRotation(parent.matrixWorld);
  5600. _q1.setFromRotationMatrix(_m1$1);
  5601. this.quaternion.premultiply(_q1.invert());
  5602. }
  5603. }
  5604. add(object) {
  5605. if (arguments.length > 1) {
  5606. for (let i = 0; i < arguments.length; i++) {
  5607. this.add(arguments[i]);
  5608. }
  5609. return this;
  5610. }
  5611. if (object === this) {
  5612. console.error('THREE.Object3D.add: object can\'t be added as a child of itself.', object);
  5613. return this;
  5614. }
  5615. if (object && object.isObject3D) {
  5616. if (object.parent !== null) {
  5617. object.parent.remove(object);
  5618. }
  5619. object.parent = this;
  5620. this.children.push(object);
  5621. object.dispatchEvent(_addedEvent);
  5622. } else {
  5623. console.error('THREE.Object3D.add: object not an instance of THREE.Object3D.', object);
  5624. }
  5625. return this;
  5626. }
  5627. remove(object) {
  5628. if (arguments.length > 1) {
  5629. for (let i = 0; i < arguments.length; i++) {
  5630. this.remove(arguments[i]);
  5631. }
  5632. return this;
  5633. }
  5634. const index = this.children.indexOf(object);
  5635. if (index !== -1) {
  5636. object.parent = null;
  5637. this.children.splice(index, 1);
  5638. object.dispatchEvent(_removedEvent);
  5639. }
  5640. return this;
  5641. }
  5642. removeFromParent() {
  5643. const parent = this.parent;
  5644. if (parent !== null) {
  5645. parent.remove(this);
  5646. }
  5647. return this;
  5648. }
  5649. clear() {
  5650. for (let i = 0; i < this.children.length; i++) {
  5651. const object = this.children[i];
  5652. object.parent = null;
  5653. object.dispatchEvent(_removedEvent);
  5654. }
  5655. this.children.length = 0;
  5656. return this;
  5657. }
  5658. attach(object) {
  5659. // adds object as a child of this, while maintaining the object's world transform
  5660. // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s)
  5661. this.updateWorldMatrix(true, false);
  5662. _m1$1.copy(this.matrixWorld).invert();
  5663. if (object.parent !== null) {
  5664. object.parent.updateWorldMatrix(true, false);
  5665. _m1$1.multiply(object.parent.matrixWorld);
  5666. }
  5667. object.applyMatrix4(_m1$1);
  5668. this.add(object);
  5669. object.updateWorldMatrix(false, true);
  5670. return this;
  5671. }
  5672. getObjectById(id) {
  5673. return this.getObjectByProperty('id', id);
  5674. }
  5675. getObjectByName(name) {
  5676. return this.getObjectByProperty('name', name);
  5677. }
  5678. getObjectByProperty(name, value) {
  5679. if (this[name] === value) return this;
  5680. for (let i = 0, l = this.children.length; i < l; i++) {
  5681. const child = this.children[i];
  5682. const object = child.getObjectByProperty(name, value);
  5683. if (object !== undefined) {
  5684. return object;
  5685. }
  5686. }
  5687. return undefined;
  5688. }
  5689. getWorldPosition(target) {
  5690. this.updateWorldMatrix(true, false);
  5691. return target.setFromMatrixPosition(this.matrixWorld);
  5692. }
  5693. getWorldQuaternion(target) {
  5694. this.updateWorldMatrix(true, false);
  5695. this.matrixWorld.decompose(_position$3, target, _scale$2);
  5696. return target;
  5697. }
  5698. getWorldScale(target) {
  5699. this.updateWorldMatrix(true, false);
  5700. this.matrixWorld.decompose(_position$3, _quaternion$2, target);
  5701. return target;
  5702. }
  5703. getWorldDirection(target) {
  5704. this.updateWorldMatrix(true, false);
  5705. const e = this.matrixWorld.elements;
  5706. return target.set(e[8], e[9], e[10]).normalize();
  5707. }
  5708. raycast() {}
  5709. traverse(callback) {
  5710. callback(this);
  5711. const children = this.children;
  5712. for (let i = 0, l = children.length; i < l; i++) {
  5713. children[i].traverse(callback);
  5714. }
  5715. }
  5716. traverseVisible(callback) {
  5717. if (this.visible === false) return;
  5718. callback(this);
  5719. const children = this.children;
  5720. for (let i = 0, l = children.length; i < l; i++) {
  5721. children[i].traverseVisible(callback);
  5722. }
  5723. }
  5724. traverseAncestors(callback) {
  5725. const parent = this.parent;
  5726. if (parent !== null) {
  5727. callback(parent);
  5728. parent.traverseAncestors(callback);
  5729. }
  5730. }
  5731. updateMatrix() {
  5732. this.matrix.compose(this.position, this.quaternion, this.scale);
  5733. this.matrixWorldNeedsUpdate = true;
  5734. }
  5735. updateMatrixWorld(force) {
  5736. if (this.matrixAutoUpdate) this.updateMatrix();
  5737. if (this.matrixWorldNeedsUpdate || force) {
  5738. if (this.parent === null) {
  5739. this.matrixWorld.copy(this.matrix);
  5740. } else {
  5741. this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
  5742. }
  5743. this.matrixWorldNeedsUpdate = false;
  5744. force = true;
  5745. } // update children
  5746. const children = this.children;
  5747. for (let i = 0, l = children.length; i < l; i++) {
  5748. children[i].updateMatrixWorld(force);
  5749. }
  5750. }
  5751. updateWorldMatrix(updateParents, updateChildren) {
  5752. const parent = this.parent;
  5753. if (updateParents === true && parent !== null) {
  5754. parent.updateWorldMatrix(true, false);
  5755. }
  5756. if (this.matrixAutoUpdate) this.updateMatrix();
  5757. if (this.parent === null) {
  5758. this.matrixWorld.copy(this.matrix);
  5759. } else {
  5760. this.matrixWorld.multiplyMatrices(this.parent.matrixWorld, this.matrix);
  5761. } // update children
  5762. if (updateChildren === true) {
  5763. const children = this.children;
  5764. for (let i = 0, l = children.length; i < l; i++) {
  5765. children[i].updateWorldMatrix(false, true);
  5766. }
  5767. }
  5768. }
  5769. toJSON(meta) {
  5770. // meta is a string when called from JSON.stringify
  5771. const isRootObject = meta === undefined || typeof meta === 'string';
  5772. const output = {}; // meta is a hash used to collect geometries, materials.
  5773. // not providing it implies that this is the root object
  5774. // being serialized.
  5775. if (isRootObject) {
  5776. // initialize meta obj
  5777. meta = {
  5778. geometries: {},
  5779. materials: {},
  5780. textures: {},
  5781. images: {},
  5782. shapes: {},
  5783. skeletons: {},
  5784. animations: {},
  5785. nodes: {}
  5786. };
  5787. output.metadata = {
  5788. version: 4.5,
  5789. type: 'Object',
  5790. generator: 'Object3D.toJSON'
  5791. };
  5792. } // standard Object3D serialization
  5793. const object = {};
  5794. object.uuid = this.uuid;
  5795. object.type = this.type;
  5796. if (this.name !== '') object.name = this.name;
  5797. if (this.castShadow === true) object.castShadow = true;
  5798. if (this.receiveShadow === true) object.receiveShadow = true;
  5799. if (this.visible === false) object.visible = false;
  5800. if (this.frustumCulled === false) object.frustumCulled = false;
  5801. if (this.renderOrder !== 0) object.renderOrder = this.renderOrder;
  5802. if (JSON.stringify(this.userData) !== '{}') object.userData = this.userData;
  5803. object.layers = this.layers.mask;
  5804. object.matrix = this.matrix.toArray();
  5805. if (this.matrixAutoUpdate === false) object.matrixAutoUpdate = false; // object specific properties
  5806. if (this.isInstancedMesh) {
  5807. object.type = 'InstancedMesh';
  5808. object.count = this.count;
  5809. object.instanceMatrix = this.instanceMatrix.toJSON();
  5810. if (this.instanceColor !== null) object.instanceColor = this.instanceColor.toJSON();
  5811. } //
  5812. function serialize(library, element) {
  5813. if (library[element.uuid] === undefined) {
  5814. library[element.uuid] = element.toJSON(meta);
  5815. }
  5816. return element.uuid;
  5817. }
  5818. if (this.isScene) {
  5819. if (this.background) {
  5820. if (this.background.isColor) {
  5821. object.background = this.background.toJSON();
  5822. } else if (this.background.isTexture) {
  5823. object.background = this.background.toJSON(meta).uuid;
  5824. }
  5825. }
  5826. if (this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true) {
  5827. object.environment = this.environment.toJSON(meta).uuid;
  5828. }
  5829. } else if (this.isMesh || this.isLine || this.isPoints) {
  5830. object.geometry = serialize(meta.geometries, this.geometry);
  5831. const parameters = this.geometry.parameters;
  5832. if (parameters !== undefined && parameters.shapes !== undefined) {
  5833. const shapes = parameters.shapes;
  5834. if (Array.isArray(shapes)) {
  5835. for (let i = 0, l = shapes.length; i < l; i++) {
  5836. const shape = shapes[i];
  5837. serialize(meta.shapes, shape);
  5838. }
  5839. } else {
  5840. serialize(meta.shapes, shapes);
  5841. }
  5842. }
  5843. }
  5844. if (this.isSkinnedMesh) {
  5845. object.bindMode = this.bindMode;
  5846. object.bindMatrix = this.bindMatrix.toArray();
  5847. if (this.skeleton !== undefined) {
  5848. serialize(meta.skeletons, this.skeleton);
  5849. object.skeleton = this.skeleton.uuid;
  5850. }
  5851. }
  5852. if (this.material !== undefined) {
  5853. if (Array.isArray(this.material)) {
  5854. const uuids = [];
  5855. for (let i = 0, l = this.material.length; i < l; i++) {
  5856. uuids.push(serialize(meta.materials, this.material[i]));
  5857. }
  5858. object.material = uuids;
  5859. } else {
  5860. object.material = serialize(meta.materials, this.material);
  5861. }
  5862. } //
  5863. if (this.children.length > 0) {
  5864. object.children = [];
  5865. for (let i = 0; i < this.children.length; i++) {
  5866. object.children.push(this.children[i].toJSON(meta).object);
  5867. }
  5868. } //
  5869. if (this.animations.length > 0) {
  5870. object.animations = [];
  5871. for (let i = 0; i < this.animations.length; i++) {
  5872. const animation = this.animations[i];
  5873. object.animations.push(serialize(meta.animations, animation));
  5874. }
  5875. }
  5876. if (isRootObject) {
  5877. const geometries = extractFromCache(meta.geometries);
  5878. const materials = extractFromCache(meta.materials);
  5879. const textures = extractFromCache(meta.textures);
  5880. const images = extractFromCache(meta.images);
  5881. const shapes = extractFromCache(meta.shapes);
  5882. const skeletons = extractFromCache(meta.skeletons);
  5883. const animations = extractFromCache(meta.animations);
  5884. const nodes = extractFromCache(meta.nodes);
  5885. if (geometries.length > 0) output.geometries = geometries;
  5886. if (materials.length > 0) output.materials = materials;
  5887. if (textures.length > 0) output.textures = textures;
  5888. if (images.length > 0) output.images = images;
  5889. if (shapes.length > 0) output.shapes = shapes;
  5890. if (skeletons.length > 0) output.skeletons = skeletons;
  5891. if (animations.length > 0) output.animations = animations;
  5892. if (nodes.length > 0) output.nodes = nodes;
  5893. }
  5894. output.object = object;
  5895. return output; // extract data from the cache hash
  5896. // remove metadata on each item
  5897. // and return as array
  5898. function extractFromCache(cache) {
  5899. const values = [];
  5900. for (const key in cache) {
  5901. const data = cache[key];
  5902. delete data.metadata;
  5903. values.push(data);
  5904. }
  5905. return values;
  5906. }
  5907. }
  5908. clone(recursive) {
  5909. return new this.constructor().copy(this, recursive);
  5910. }
  5911. copy(source, recursive = true) {
  5912. this.name = source.name;
  5913. this.up.copy(source.up);
  5914. this.position.copy(source.position);
  5915. this.rotation.order = source.rotation.order;
  5916. this.quaternion.copy(source.quaternion);
  5917. this.scale.copy(source.scale);
  5918. this.matrix.copy(source.matrix);
  5919. this.matrixWorld.copy(source.matrixWorld);
  5920. this.matrixAutoUpdate = source.matrixAutoUpdate;
  5921. this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate;
  5922. this.layers.mask = source.layers.mask;
  5923. this.visible = source.visible;
  5924. this.castShadow = source.castShadow;
  5925. this.receiveShadow = source.receiveShadow;
  5926. this.frustumCulled = source.frustumCulled;
  5927. this.renderOrder = source.renderOrder;
  5928. this.userData = JSON.parse(JSON.stringify(source.userData));
  5929. if (recursive === true) {
  5930. for (let i = 0; i < source.children.length; i++) {
  5931. const child = source.children[i];
  5932. this.add(child.clone());
  5933. }
  5934. }
  5935. return this;
  5936. }
  5937. }
  5938. Object3D.DefaultUp = /*@__PURE__*/new Vector3(0, 1, 0);
  5939. Object3D.DefaultMatrixAutoUpdate = true;
  5940. const _v0$1 = /*@__PURE__*/new Vector3();
  5941. const _v1$3 = /*@__PURE__*/new Vector3();
  5942. const _v2$2 = /*@__PURE__*/new Vector3();
  5943. const _v3$1 = /*@__PURE__*/new Vector3();
  5944. const _vab = /*@__PURE__*/new Vector3();
  5945. const _vac = /*@__PURE__*/new Vector3();
  5946. const _vbc = /*@__PURE__*/new Vector3();
  5947. const _vap = /*@__PURE__*/new Vector3();
  5948. const _vbp = /*@__PURE__*/new Vector3();
  5949. const _vcp = /*@__PURE__*/new Vector3();
  5950. class Triangle {
  5951. constructor(a = new Vector3(), b = new Vector3(), c = new Vector3()) {
  5952. this.a = a;
  5953. this.b = b;
  5954. this.c = c;
  5955. }
  5956. static getNormal(a, b, c, target) {
  5957. target.subVectors(c, b);
  5958. _v0$1.subVectors(a, b);
  5959. target.cross(_v0$1);
  5960. const targetLengthSq = target.lengthSq();
  5961. if (targetLengthSq > 0) {
  5962. return target.multiplyScalar(1 / Math.sqrt(targetLengthSq));
  5963. }
  5964. return target.set(0, 0, 0);
  5965. } // static/instance method to calculate barycentric coordinates
  5966. // based on: http://www.blackpawn.com/texts/pointinpoly/default.html
  5967. static getBarycoord(point, a, b, c, target) {
  5968. _v0$1.subVectors(c, a);
  5969. _v1$3.subVectors(b, a);
  5970. _v2$2.subVectors(point, a);
  5971. const dot00 = _v0$1.dot(_v0$1);
  5972. const dot01 = _v0$1.dot(_v1$3);
  5973. const dot02 = _v0$1.dot(_v2$2);
  5974. const dot11 = _v1$3.dot(_v1$3);
  5975. const dot12 = _v1$3.dot(_v2$2);
  5976. const denom = dot00 * dot11 - dot01 * dot01; // collinear or singular triangle
  5977. if (denom === 0) {
  5978. // arbitrary location outside of triangle?
  5979. // not sure if this is the best idea, maybe should be returning undefined
  5980. return target.set(-2, -1, -1);
  5981. }
  5982. const invDenom = 1 / denom;
  5983. const u = (dot11 * dot02 - dot01 * dot12) * invDenom;
  5984. const v = (dot00 * dot12 - dot01 * dot02) * invDenom; // barycentric coordinates must always sum to 1
  5985. return target.set(1 - u - v, v, u);
  5986. }
  5987. static containsPoint(point, a, b, c) {
  5988. this.getBarycoord(point, a, b, c, _v3$1);
  5989. return _v3$1.x >= 0 && _v3$1.y >= 0 && _v3$1.x + _v3$1.y <= 1;
  5990. }
  5991. static getUV(point, p1, p2, p3, uv1, uv2, uv3, target) {
  5992. this.getBarycoord(point, p1, p2, p3, _v3$1);
  5993. target.set(0, 0);
  5994. target.addScaledVector(uv1, _v3$1.x);
  5995. target.addScaledVector(uv2, _v3$1.y);
  5996. target.addScaledVector(uv3, _v3$1.z);
  5997. return target;
  5998. }
  5999. static isFrontFacing(a, b, c, direction) {
  6000. _v0$1.subVectors(c, b);
  6001. _v1$3.subVectors(a, b); // strictly front facing
  6002. return _v0$1.cross(_v1$3).dot(direction) < 0 ? true : false;
  6003. }
  6004. set(a, b, c) {
  6005. this.a.copy(a);
  6006. this.b.copy(b);
  6007. this.c.copy(c);
  6008. return this;
  6009. }
  6010. setFromPointsAndIndices(points, i0, i1, i2) {
  6011. this.a.copy(points[i0]);
  6012. this.b.copy(points[i1]);
  6013. this.c.copy(points[i2]);
  6014. return this;
  6015. }
  6016. setFromAttributeAndIndices(attribute, i0, i1, i2) {
  6017. this.a.fromBufferAttribute(attribute, i0);
  6018. this.b.fromBufferAttribute(attribute, i1);
  6019. this.c.fromBufferAttribute(attribute, i2);
  6020. return this;
  6021. }
  6022. clone() {
  6023. return new this.constructor().copy(this);
  6024. }
  6025. copy(triangle) {
  6026. this.a.copy(triangle.a);
  6027. this.b.copy(triangle.b);
  6028. this.c.copy(triangle.c);
  6029. return this;
  6030. }
  6031. getArea() {
  6032. _v0$1.subVectors(this.c, this.b);
  6033. _v1$3.subVectors(this.a, this.b);
  6034. return _v0$1.cross(_v1$3).length() * 0.5;
  6035. }
  6036. getMidpoint(target) {
  6037. return target.addVectors(this.a, this.b).add(this.c).multiplyScalar(1 / 3);
  6038. }
  6039. getNormal(target) {
  6040. return Triangle.getNormal(this.a, this.b, this.c, target);
  6041. }
  6042. getPlane(target) {
  6043. return target.setFromCoplanarPoints(this.a, this.b, this.c);
  6044. }
  6045. getBarycoord(point, target) {
  6046. return Triangle.getBarycoord(point, this.a, this.b, this.c, target);
  6047. }
  6048. getUV(point, uv1, uv2, uv3, target) {
  6049. return Triangle.getUV(point, this.a, this.b, this.c, uv1, uv2, uv3, target);
  6050. }
  6051. containsPoint(point) {
  6052. return Triangle.containsPoint(point, this.a, this.b, this.c);
  6053. }
  6054. isFrontFacing(direction) {
  6055. return Triangle.isFrontFacing(this.a, this.b, this.c, direction);
  6056. }
  6057. intersectsBox(box) {
  6058. return box.intersectsTriangle(this);
  6059. }
  6060. closestPointToPoint(p, target) {
  6061. const a = this.a,
  6062. b = this.b,
  6063. c = this.c;
  6064. let v, w; // algorithm thanks to Real-Time Collision Detection by Christer Ericson,
  6065. // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc.,
  6066. // under the accompanying license; see chapter 5.1.5 for detailed explanation.
  6067. // basically, we're distinguishing which of the voronoi regions of the triangle
  6068. // the point lies in with the minimum amount of redundant computation.
  6069. _vab.subVectors(b, a);
  6070. _vac.subVectors(c, a);
  6071. _vap.subVectors(p, a);
  6072. const d1 = _vab.dot(_vap);
  6073. const d2 = _vac.dot(_vap);
  6074. if (d1 <= 0 && d2 <= 0) {
  6075. // vertex region of A; barycentric coords (1, 0, 0)
  6076. return target.copy(a);
  6077. }
  6078. _vbp.subVectors(p, b);
  6079. const d3 = _vab.dot(_vbp);
  6080. const d4 = _vac.dot(_vbp);
  6081. if (d3 >= 0 && d4 <= d3) {
  6082. // vertex region of B; barycentric coords (0, 1, 0)
  6083. return target.copy(b);
  6084. }
  6085. const vc = d1 * d4 - d3 * d2;
  6086. if (vc <= 0 && d1 >= 0 && d3 <= 0) {
  6087. v = d1 / (d1 - d3); // edge region of AB; barycentric coords (1-v, v, 0)
  6088. return target.copy(a).addScaledVector(_vab, v);
  6089. }
  6090. _vcp.subVectors(p, c);
  6091. const d5 = _vab.dot(_vcp);
  6092. const d6 = _vac.dot(_vcp);
  6093. if (d6 >= 0 && d5 <= d6) {
  6094. // vertex region of C; barycentric coords (0, 0, 1)
  6095. return target.copy(c);
  6096. }
  6097. const vb = d5 * d2 - d1 * d6;
  6098. if (vb <= 0 && d2 >= 0 && d6 <= 0) {
  6099. w = d2 / (d2 - d6); // edge region of AC; barycentric coords (1-w, 0, w)
  6100. return target.copy(a).addScaledVector(_vac, w);
  6101. }
  6102. const va = d3 * d6 - d5 * d4;
  6103. if (va <= 0 && d4 - d3 >= 0 && d5 - d6 >= 0) {
  6104. _vbc.subVectors(c, b);
  6105. w = (d4 - d3) / (d4 - d3 + (d5 - d6)); // edge region of BC; barycentric coords (0, 1-w, w)
  6106. return target.copy(b).addScaledVector(_vbc, w); // edge region of BC
  6107. } // face region
  6108. const denom = 1 / (va + vb + vc); // u = va * denom
  6109. v = vb * denom;
  6110. w = vc * denom;
  6111. return target.copy(a).addScaledVector(_vab, v).addScaledVector(_vac, w);
  6112. }
  6113. equals(triangle) {
  6114. return triangle.a.equals(this.a) && triangle.b.equals(this.b) && triangle.c.equals(this.c);
  6115. }
  6116. }
  6117. let materialId = 0;
  6118. class Material extends EventDispatcher {
  6119. constructor() {
  6120. super();
  6121. this.isMaterial = true;
  6122. Object.defineProperty(this, 'id', {
  6123. value: materialId++
  6124. });
  6125. this.uuid = generateUUID();
  6126. this.name = '';
  6127. this.type = 'Material';
  6128. this.blending = NormalBlending;
  6129. this.side = FrontSide;
  6130. this.vertexColors = false;
  6131. this.opacity = 1;
  6132. this.transparent = false;
  6133. this.blendSrc = SrcAlphaFactor;
  6134. this.blendDst = OneMinusSrcAlphaFactor;
  6135. this.blendEquation = AddEquation;
  6136. this.blendSrcAlpha = null;
  6137. this.blendDstAlpha = null;
  6138. this.blendEquationAlpha = null;
  6139. this.depthFunc = LessEqualDepth;
  6140. this.depthTest = true;
  6141. this.depthWrite = true;
  6142. this.stencilWriteMask = 0xff;
  6143. this.stencilFunc = AlwaysStencilFunc;
  6144. this.stencilRef = 0;
  6145. this.stencilFuncMask = 0xff;
  6146. this.stencilFail = KeepStencilOp;
  6147. this.stencilZFail = KeepStencilOp;
  6148. this.stencilZPass = KeepStencilOp;
  6149. this.stencilWrite = false;
  6150. this.clippingPlanes = null;
  6151. this.clipIntersection = false;
  6152. this.clipShadows = false;
  6153. this.shadowSide = null;
  6154. this.colorWrite = true;
  6155. this.precision = null; // override the renderer's default precision for this material
  6156. this.polygonOffset = false;
  6157. this.polygonOffsetFactor = 0;
  6158. this.polygonOffsetUnits = 0;
  6159. this.dithering = false;
  6160. this.alphaToCoverage = false;
  6161. this.premultipliedAlpha = false;
  6162. this.visible = true;
  6163. this.toneMapped = true;
  6164. this.userData = {};
  6165. this.version = 0;
  6166. this._alphaTest = 0;
  6167. }
  6168. get alphaTest() {
  6169. return this._alphaTest;
  6170. }
  6171. set alphaTest(value) {
  6172. if (this._alphaTest > 0 !== value > 0) {
  6173. this.version++;
  6174. }
  6175. this._alphaTest = value;
  6176. }
  6177. onBuild() {}
  6178. onBeforeRender() {}
  6179. onBeforeCompile() {}
  6180. customProgramCacheKey() {
  6181. return this.onBeforeCompile.toString();
  6182. }
  6183. setValues(values) {
  6184. if (values === undefined) return;
  6185. for (const key in values) {
  6186. const newValue = values[key];
  6187. if (newValue === undefined) {
  6188. console.warn('THREE.Material: \'' + key + '\' parameter is undefined.');
  6189. continue;
  6190. } // for backward compatibility if shading is set in the constructor
  6191. if (key === 'shading') {
  6192. console.warn('THREE.' + this.type + ': .shading has been removed. Use the boolean .flatShading instead.');
  6193. this.flatShading = newValue === FlatShading ? true : false;
  6194. continue;
  6195. }
  6196. const currentValue = this[key];
  6197. if (currentValue === undefined) {
  6198. console.warn('THREE.' + this.type + ': \'' + key + '\' is not a property of this material.');
  6199. continue;
  6200. }
  6201. if (currentValue && currentValue.isColor) {
  6202. currentValue.set(newValue);
  6203. } else if (currentValue && currentValue.isVector3 && newValue && newValue.isVector3) {
  6204. currentValue.copy(newValue);
  6205. } else {
  6206. this[key] = newValue;
  6207. }
  6208. }
  6209. }
  6210. toJSON(meta) {
  6211. const isRootObject = meta === undefined || typeof meta === 'string';
  6212. if (isRootObject) {
  6213. meta = {
  6214. textures: {},
  6215. images: {}
  6216. };
  6217. }
  6218. const data = {
  6219. metadata: {
  6220. version: 4.5,
  6221. type: 'Material',
  6222. generator: 'Material.toJSON'
  6223. }
  6224. }; // standard Material serialization
  6225. data.uuid = this.uuid;
  6226. data.type = this.type;
  6227. if (this.name !== '') data.name = this.name;
  6228. if (this.color && this.color.isColor) data.color = this.color.getHex();
  6229. if (this.roughness !== undefined) data.roughness = this.roughness;
  6230. if (this.metalness !== undefined) data.metalness = this.metalness;
  6231. if (this.sheen !== undefined) data.sheen = this.sheen;
  6232. if (this.sheenColor && this.sheenColor.isColor) data.sheenColor = this.sheenColor.getHex();
  6233. if (this.sheenRoughness !== undefined) data.sheenRoughness = this.sheenRoughness;
  6234. if (this.emissive && this.emissive.isColor) data.emissive = this.emissive.getHex();
  6235. if (this.emissiveIntensity && this.emissiveIntensity !== 1) data.emissiveIntensity = this.emissiveIntensity;
  6236. if (this.specular && this.specular.isColor) data.specular = this.specular.getHex();
  6237. if (this.specularIntensity !== undefined) data.specularIntensity = this.specularIntensity;
  6238. if (this.specularColor && this.specularColor.isColor) data.specularColor = this.specularColor.getHex();
  6239. if (this.shininess !== undefined) data.shininess = this.shininess;
  6240. if (this.clearcoat !== undefined) data.clearcoat = this.clearcoat;
  6241. if (this.clearcoatRoughness !== undefined) data.clearcoatRoughness = this.clearcoatRoughness;
  6242. if (this.clearcoatMap && this.clearcoatMap.isTexture) {
  6243. data.clearcoatMap = this.clearcoatMap.toJSON(meta).uuid;
  6244. }
  6245. if (this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture) {
  6246. data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON(meta).uuid;
  6247. }
  6248. if (this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture) {
  6249. data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON(meta).uuid;
  6250. data.clearcoatNormalScale = this.clearcoatNormalScale.toArray();
  6251. }
  6252. if (this.iridescence !== undefined) data.iridescence = this.iridescence;
  6253. if (this.iridescenceIOR !== undefined) data.iridescenceIOR = this.iridescenceIOR;
  6254. if (this.iridescenceThicknessRange !== undefined) data.iridescenceThicknessRange = this.iridescenceThicknessRange;
  6255. if (this.iridescenceMap && this.iridescenceMap.isTexture) {
  6256. data.iridescenceMap = this.iridescenceMap.toJSON(meta).uuid;
  6257. }
  6258. if (this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture) {
  6259. data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON(meta).uuid;
  6260. }
  6261. if (this.map && this.map.isTexture) data.map = this.map.toJSON(meta).uuid;
  6262. if (this.matcap && this.matcap.isTexture) data.matcap = this.matcap.toJSON(meta).uuid;
  6263. if (this.alphaMap && this.alphaMap.isTexture) data.alphaMap = this.alphaMap.toJSON(meta).uuid;
  6264. if (this.lightMap && this.lightMap.isTexture) {
  6265. data.lightMap = this.lightMap.toJSON(meta).uuid;
  6266. data.lightMapIntensity = this.lightMapIntensity;
  6267. }
  6268. if (this.aoMap && this.aoMap.isTexture) {
  6269. data.aoMap = this.aoMap.toJSON(meta).uuid;
  6270. data.aoMapIntensity = this.aoMapIntensity;
  6271. }
  6272. if (this.bumpMap && this.bumpMap.isTexture) {
  6273. data.bumpMap = this.bumpMap.toJSON(meta).uuid;
  6274. data.bumpScale = this.bumpScale;
  6275. }
  6276. if (this.normalMap && this.normalMap.isTexture) {
  6277. data.normalMap = this.normalMap.toJSON(meta).uuid;
  6278. data.normalMapType = this.normalMapType;
  6279. data.normalScale = this.normalScale.toArray();
  6280. }
  6281. if (this.displacementMap && this.displacementMap.isTexture) {
  6282. data.displacementMap = this.displacementMap.toJSON(meta).uuid;
  6283. data.displacementScale = this.displacementScale;
  6284. data.displacementBias = this.displacementBias;
  6285. }
  6286. if (this.roughnessMap && this.roughnessMap.isTexture) data.roughnessMap = this.roughnessMap.toJSON(meta).uuid;
  6287. if (this.metalnessMap && this.metalnessMap.isTexture) data.metalnessMap = this.metalnessMap.toJSON(meta).uuid;
  6288. if (this.emissiveMap && this.emissiveMap.isTexture) data.emissiveMap = this.emissiveMap.toJSON(meta).uuid;
  6289. if (this.specularMap && this.specularMap.isTexture) data.specularMap = this.specularMap.toJSON(meta).uuid;
  6290. if (this.specularIntensityMap && this.specularIntensityMap.isTexture) data.specularIntensityMap = this.specularIntensityMap.toJSON(meta).uuid;
  6291. if (this.specularColorMap && this.specularColorMap.isTexture) data.specularColorMap = this.specularColorMap.toJSON(meta).uuid;
  6292. if (this.envMap && this.envMap.isTexture) {
  6293. data.envMap = this.envMap.toJSON(meta).uuid;
  6294. if (this.combine !== undefined) data.combine = this.combine;
  6295. }
  6296. if (this.envMapIntensity !== undefined) data.envMapIntensity = this.envMapIntensity;
  6297. if (this.reflectivity !== undefined) data.reflectivity = this.reflectivity;
  6298. if (this.refractionRatio !== undefined) data.refractionRatio = this.refractionRatio;
  6299. if (this.gradientMap && this.gradientMap.isTexture) {
  6300. data.gradientMap = this.gradientMap.toJSON(meta).uuid;
  6301. }
  6302. if (this.transmission !== undefined) data.transmission = this.transmission;
  6303. if (this.transmissionMap && this.transmissionMap.isTexture) data.transmissionMap = this.transmissionMap.toJSON(meta).uuid;
  6304. if (this.thickness !== undefined) data.thickness = this.thickness;
  6305. if (this.thicknessMap && this.thicknessMap.isTexture) data.thicknessMap = this.thicknessMap.toJSON(meta).uuid;
  6306. if (this.attenuationDistance !== undefined) data.attenuationDistance = this.attenuationDistance;
  6307. if (this.attenuationColor !== undefined) data.attenuationColor = this.attenuationColor.getHex();
  6308. if (this.size !== undefined) data.size = this.size;
  6309. if (this.shadowSide !== null) data.shadowSide = this.shadowSide;
  6310. if (this.sizeAttenuation !== undefined) data.sizeAttenuation = this.sizeAttenuation;
  6311. if (this.blending !== NormalBlending) data.blending = this.blending;
  6312. if (this.side !== FrontSide) data.side = this.side;
  6313. if (this.vertexColors) data.vertexColors = true;
  6314. if (this.opacity < 1) data.opacity = this.opacity;
  6315. if (this.transparent === true) data.transparent = this.transparent;
  6316. data.depthFunc = this.depthFunc;
  6317. data.depthTest = this.depthTest;
  6318. data.depthWrite = this.depthWrite;
  6319. data.colorWrite = this.colorWrite;
  6320. data.stencilWrite = this.stencilWrite;
  6321. data.stencilWriteMask = this.stencilWriteMask;
  6322. data.stencilFunc = this.stencilFunc;
  6323. data.stencilRef = this.stencilRef;
  6324. data.stencilFuncMask = this.stencilFuncMask;
  6325. data.stencilFail = this.stencilFail;
  6326. data.stencilZFail = this.stencilZFail;
  6327. data.stencilZPass = this.stencilZPass; // rotation (SpriteMaterial)
  6328. if (this.rotation !== undefined && this.rotation !== 0) data.rotation = this.rotation;
  6329. if (this.polygonOffset === true) data.polygonOffset = true;
  6330. if (this.polygonOffsetFactor !== 0) data.polygonOffsetFactor = this.polygonOffsetFactor;
  6331. if (this.polygonOffsetUnits !== 0) data.polygonOffsetUnits = this.polygonOffsetUnits;
  6332. if (this.linewidth !== undefined && this.linewidth !== 1) data.linewidth = this.linewidth;
  6333. if (this.dashSize !== undefined) data.dashSize = this.dashSize;
  6334. if (this.gapSize !== undefined) data.gapSize = this.gapSize;
  6335. if (this.scale !== undefined) data.scale = this.scale;
  6336. if (this.dithering === true) data.dithering = true;
  6337. if (this.alphaTest > 0) data.alphaTest = this.alphaTest;
  6338. if (this.alphaToCoverage === true) data.alphaToCoverage = this.alphaToCoverage;
  6339. if (this.premultipliedAlpha === true) data.premultipliedAlpha = this.premultipliedAlpha;
  6340. if (this.wireframe === true) data.wireframe = this.wireframe;
  6341. if (this.wireframeLinewidth > 1) data.wireframeLinewidth = this.wireframeLinewidth;
  6342. if (this.wireframeLinecap !== 'round') data.wireframeLinecap = this.wireframeLinecap;
  6343. if (this.wireframeLinejoin !== 'round') data.wireframeLinejoin = this.wireframeLinejoin;
  6344. if (this.flatShading === true) data.flatShading = this.flatShading;
  6345. if (this.visible === false) data.visible = false;
  6346. if (this.toneMapped === false) data.toneMapped = false;
  6347. if (this.fog === false) data.fog = false;
  6348. if (JSON.stringify(this.userData) !== '{}') data.userData = this.userData; // TODO: Copied from Object3D.toJSON
  6349. function extractFromCache(cache) {
  6350. const values = [];
  6351. for (const key in cache) {
  6352. const data = cache[key];
  6353. delete data.metadata;
  6354. values.push(data);
  6355. }
  6356. return values;
  6357. }
  6358. if (isRootObject) {
  6359. const textures = extractFromCache(meta.textures);
  6360. const images = extractFromCache(meta.images);
  6361. if (textures.length > 0) data.textures = textures;
  6362. if (images.length > 0) data.images = images;
  6363. }
  6364. return data;
  6365. }
  6366. clone() {
  6367. return new this.constructor().copy(this);
  6368. }
  6369. copy(source) {
  6370. this.name = source.name;
  6371. this.blending = source.blending;
  6372. this.side = source.side;
  6373. this.vertexColors = source.vertexColors;
  6374. this.opacity = source.opacity;
  6375. this.transparent = source.transparent;
  6376. this.blendSrc = source.blendSrc;
  6377. this.blendDst = source.blendDst;
  6378. this.blendEquation = source.blendEquation;
  6379. this.blendSrcAlpha = source.blendSrcAlpha;
  6380. this.blendDstAlpha = source.blendDstAlpha;
  6381. this.blendEquationAlpha = source.blendEquationAlpha;
  6382. this.depthFunc = source.depthFunc;
  6383. this.depthTest = source.depthTest;
  6384. this.depthWrite = source.depthWrite;
  6385. this.stencilWriteMask = source.stencilWriteMask;
  6386. this.stencilFunc = source.stencilFunc;
  6387. this.stencilRef = source.stencilRef;
  6388. this.stencilFuncMask = source.stencilFuncMask;
  6389. this.stencilFail = source.stencilFail;
  6390. this.stencilZFail = source.stencilZFail;
  6391. this.stencilZPass = source.stencilZPass;
  6392. this.stencilWrite = source.stencilWrite;
  6393. const srcPlanes = source.clippingPlanes;
  6394. let dstPlanes = null;
  6395. if (srcPlanes !== null) {
  6396. const n = srcPlanes.length;
  6397. dstPlanes = new Array(n);
  6398. for (let i = 0; i !== n; ++i) {
  6399. dstPlanes[i] = srcPlanes[i].clone();
  6400. }
  6401. }
  6402. this.clippingPlanes = dstPlanes;
  6403. this.clipIntersection = source.clipIntersection;
  6404. this.clipShadows = source.clipShadows;
  6405. this.shadowSide = source.shadowSide;
  6406. this.colorWrite = source.colorWrite;
  6407. this.precision = source.precision;
  6408. this.polygonOffset = source.polygonOffset;
  6409. this.polygonOffsetFactor = source.polygonOffsetFactor;
  6410. this.polygonOffsetUnits = source.polygonOffsetUnits;
  6411. this.dithering = source.dithering;
  6412. this.alphaTest = source.alphaTest;
  6413. this.alphaToCoverage = source.alphaToCoverage;
  6414. this.premultipliedAlpha = source.premultipliedAlpha;
  6415. this.visible = source.visible;
  6416. this.toneMapped = source.toneMapped;
  6417. this.userData = JSON.parse(JSON.stringify(source.userData));
  6418. return this;
  6419. }
  6420. dispose() {
  6421. this.dispatchEvent({
  6422. type: 'dispose'
  6423. });
  6424. }
  6425. set needsUpdate(value) {
  6426. if (value === true) this.version++;
  6427. }
  6428. }
  6429. class MeshBasicMaterial extends Material {
  6430. constructor(parameters) {
  6431. super();
  6432. this.isMeshBasicMaterial = true;
  6433. this.type = 'MeshBasicMaterial';
  6434. this.color = new Color(0xffffff); // emissive
  6435. this.map = null;
  6436. this.lightMap = null;
  6437. this.lightMapIntensity = 1.0;
  6438. this.aoMap = null;
  6439. this.aoMapIntensity = 1.0;
  6440. this.specularMap = null;
  6441. this.alphaMap = null;
  6442. this.envMap = null;
  6443. this.combine = MultiplyOperation;
  6444. this.reflectivity = 1;
  6445. this.refractionRatio = 0.98;
  6446. this.wireframe = false;
  6447. this.wireframeLinewidth = 1;
  6448. this.wireframeLinecap = 'round';
  6449. this.wireframeLinejoin = 'round';
  6450. this.fog = true;
  6451. this.setValues(parameters);
  6452. }
  6453. copy(source) {
  6454. super.copy(source);
  6455. this.color.copy(source.color);
  6456. this.map = source.map;
  6457. this.lightMap = source.lightMap;
  6458. this.lightMapIntensity = source.lightMapIntensity;
  6459. this.aoMap = source.aoMap;
  6460. this.aoMapIntensity = source.aoMapIntensity;
  6461. this.specularMap = source.specularMap;
  6462. this.alphaMap = source.alphaMap;
  6463. this.envMap = source.envMap;
  6464. this.combine = source.combine;
  6465. this.reflectivity = source.reflectivity;
  6466. this.refractionRatio = source.refractionRatio;
  6467. this.wireframe = source.wireframe;
  6468. this.wireframeLinewidth = source.wireframeLinewidth;
  6469. this.wireframeLinecap = source.wireframeLinecap;
  6470. this.wireframeLinejoin = source.wireframeLinejoin;
  6471. this.fog = source.fog;
  6472. return this;
  6473. }
  6474. }
  6475. const _vector$9 = /*@__PURE__*/new Vector3();
  6476. const _vector2$1 = /*@__PURE__*/new Vector2();
  6477. class BufferAttribute {
  6478. constructor(array, itemSize, normalized) {
  6479. if (Array.isArray(array)) {
  6480. throw new TypeError('THREE.BufferAttribute: array should be a Typed Array.');
  6481. }
  6482. this.isBufferAttribute = true;
  6483. this.name = '';
  6484. this.array = array;
  6485. this.itemSize = itemSize;
  6486. this.count = array !== undefined ? array.length / itemSize : 0;
  6487. this.normalized = normalized === true;
  6488. this.usage = StaticDrawUsage;
  6489. this.updateRange = {
  6490. offset: 0,
  6491. count: -1
  6492. };
  6493. this.version = 0;
  6494. }
  6495. onUploadCallback() {}
  6496. set needsUpdate(value) {
  6497. if (value === true) this.version++;
  6498. }
  6499. setUsage(value) {
  6500. this.usage = value;
  6501. return this;
  6502. }
  6503. copy(source) {
  6504. this.name = source.name;
  6505. this.array = new source.array.constructor(source.array);
  6506. this.itemSize = source.itemSize;
  6507. this.count = source.count;
  6508. this.normalized = source.normalized;
  6509. this.usage = source.usage;
  6510. return this;
  6511. }
  6512. copyAt(index1, attribute, index2) {
  6513. index1 *= this.itemSize;
  6514. index2 *= attribute.itemSize;
  6515. for (let i = 0, l = this.itemSize; i < l; i++) {
  6516. this.array[index1 + i] = attribute.array[index2 + i];
  6517. }
  6518. return this;
  6519. }
  6520. copyArray(array) {
  6521. this.array.set(array);
  6522. return this;
  6523. }
  6524. copyColorsArray(colors) {
  6525. const array = this.array;
  6526. let offset = 0;
  6527. for (let i = 0, l = colors.length; i < l; i++) {
  6528. let color = colors[i];
  6529. if (color === undefined) {
  6530. console.warn('THREE.BufferAttribute.copyColorsArray(): color is undefined', i);
  6531. color = new Color();
  6532. }
  6533. array[offset++] = color.r;
  6534. array[offset++] = color.g;
  6535. array[offset++] = color.b;
  6536. }
  6537. return this;
  6538. }
  6539. copyVector2sArray(vectors) {
  6540. const array = this.array;
  6541. let offset = 0;
  6542. for (let i = 0, l = vectors.length; i < l; i++) {
  6543. let vector = vectors[i];
  6544. if (vector === undefined) {
  6545. console.warn('THREE.BufferAttribute.copyVector2sArray(): vector is undefined', i);
  6546. vector = new Vector2();
  6547. }
  6548. array[offset++] = vector.x;
  6549. array[offset++] = vector.y;
  6550. }
  6551. return this;
  6552. }
  6553. copyVector3sArray(vectors) {
  6554. const array = this.array;
  6555. let offset = 0;
  6556. for (let i = 0, l = vectors.length; i < l; i++) {
  6557. let vector = vectors[i];
  6558. if (vector === undefined) {
  6559. console.warn('THREE.BufferAttribute.copyVector3sArray(): vector is undefined', i);
  6560. vector = new Vector3();
  6561. }
  6562. array[offset++] = vector.x;
  6563. array[offset++] = vector.y;
  6564. array[offset++] = vector.z;
  6565. }
  6566. return this;
  6567. }
  6568. copyVector4sArray(vectors) {
  6569. const array = this.array;
  6570. let offset = 0;
  6571. for (let i = 0, l = vectors.length; i < l; i++) {
  6572. let vector = vectors[i];
  6573. if (vector === undefined) {
  6574. console.warn('THREE.BufferAttribute.copyVector4sArray(): vector is undefined', i);
  6575. vector = new Vector4();
  6576. }
  6577. array[offset++] = vector.x;
  6578. array[offset++] = vector.y;
  6579. array[offset++] = vector.z;
  6580. array[offset++] = vector.w;
  6581. }
  6582. return this;
  6583. }
  6584. applyMatrix3(m) {
  6585. if (this.itemSize === 2) {
  6586. for (let i = 0, l = this.count; i < l; i++) {
  6587. _vector2$1.fromBufferAttribute(this, i);
  6588. _vector2$1.applyMatrix3(m);
  6589. this.setXY(i, _vector2$1.x, _vector2$1.y);
  6590. }
  6591. } else if (this.itemSize === 3) {
  6592. for (let i = 0, l = this.count; i < l; i++) {
  6593. _vector$9.fromBufferAttribute(this, i);
  6594. _vector$9.applyMatrix3(m);
  6595. this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
  6596. }
  6597. }
  6598. return this;
  6599. }
  6600. applyMatrix4(m) {
  6601. for (let i = 0, l = this.count; i < l; i++) {
  6602. _vector$9.fromBufferAttribute(this, i);
  6603. _vector$9.applyMatrix4(m);
  6604. this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
  6605. }
  6606. return this;
  6607. }
  6608. applyNormalMatrix(m) {
  6609. for (let i = 0, l = this.count; i < l; i++) {
  6610. _vector$9.fromBufferAttribute(this, i);
  6611. _vector$9.applyNormalMatrix(m);
  6612. this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
  6613. }
  6614. return this;
  6615. }
  6616. transformDirection(m) {
  6617. for (let i = 0, l = this.count; i < l; i++) {
  6618. _vector$9.fromBufferAttribute(this, i);
  6619. _vector$9.transformDirection(m);
  6620. this.setXYZ(i, _vector$9.x, _vector$9.y, _vector$9.z);
  6621. }
  6622. return this;
  6623. }
  6624. set(value, offset = 0) {
  6625. this.array.set(value, offset);
  6626. return this;
  6627. }
  6628. getX(index) {
  6629. return this.array[index * this.itemSize];
  6630. }
  6631. setX(index, x) {
  6632. this.array[index * this.itemSize] = x;
  6633. return this;
  6634. }
  6635. getY(index) {
  6636. return this.array[index * this.itemSize + 1];
  6637. }
  6638. setY(index, y) {
  6639. this.array[index * this.itemSize + 1] = y;
  6640. return this;
  6641. }
  6642. getZ(index) {
  6643. return this.array[index * this.itemSize + 2];
  6644. }
  6645. setZ(index, z) {
  6646. this.array[index * this.itemSize + 2] = z;
  6647. return this;
  6648. }
  6649. getW(index) {
  6650. return this.array[index * this.itemSize + 3];
  6651. }
  6652. setW(index, w) {
  6653. this.array[index * this.itemSize + 3] = w;
  6654. return this;
  6655. }
  6656. setXY(index, x, y) {
  6657. index *= this.itemSize;
  6658. this.array[index + 0] = x;
  6659. this.array[index + 1] = y;
  6660. return this;
  6661. }
  6662. setXYZ(index, x, y, z) {
  6663. index *= this.itemSize;
  6664. this.array[index + 0] = x;
  6665. this.array[index + 1] = y;
  6666. this.array[index + 2] = z;
  6667. return this;
  6668. }
  6669. setXYZW(index, x, y, z, w) {
  6670. index *= this.itemSize;
  6671. this.array[index + 0] = x;
  6672. this.array[index + 1] = y;
  6673. this.array[index + 2] = z;
  6674. this.array[index + 3] = w;
  6675. return this;
  6676. }
  6677. onUpload(callback) {
  6678. this.onUploadCallback = callback;
  6679. return this;
  6680. }
  6681. clone() {
  6682. return new this.constructor(this.array, this.itemSize).copy(this);
  6683. }
  6684. toJSON() {
  6685. const data = {
  6686. itemSize: this.itemSize,
  6687. type: this.array.constructor.name,
  6688. array: Array.from(this.array),
  6689. normalized: this.normalized
  6690. };
  6691. if (this.name !== '') data.name = this.name;
  6692. if (this.usage !== StaticDrawUsage) data.usage = this.usage;
  6693. if (this.updateRange.offset !== 0 || this.updateRange.count !== -1) data.updateRange = this.updateRange;
  6694. return data;
  6695. }
  6696. } //
  6697. class Int8BufferAttribute extends BufferAttribute {
  6698. constructor(array, itemSize, normalized) {
  6699. super(new Int8Array(array), itemSize, normalized);
  6700. }
  6701. }
  6702. class Uint8BufferAttribute extends BufferAttribute {
  6703. constructor(array, itemSize, normalized) {
  6704. super(new Uint8Array(array), itemSize, normalized);
  6705. }
  6706. }
  6707. class Uint8ClampedBufferAttribute extends BufferAttribute {
  6708. constructor(array, itemSize, normalized) {
  6709. super(new Uint8ClampedArray(array), itemSize, normalized);
  6710. }
  6711. }
  6712. class Int16BufferAttribute extends BufferAttribute {
  6713. constructor(array, itemSize, normalized) {
  6714. super(new Int16Array(array), itemSize, normalized);
  6715. }
  6716. }
  6717. class Uint16BufferAttribute extends BufferAttribute {
  6718. constructor(array, itemSize, normalized) {
  6719. super(new Uint16Array(array), itemSize, normalized);
  6720. }
  6721. }
  6722. class Int32BufferAttribute extends BufferAttribute {
  6723. constructor(array, itemSize, normalized) {
  6724. super(new Int32Array(array), itemSize, normalized);
  6725. }
  6726. }
  6727. class Uint32BufferAttribute extends BufferAttribute {
  6728. constructor(array, itemSize, normalized) {
  6729. super(new Uint32Array(array), itemSize, normalized);
  6730. }
  6731. }
  6732. class Float16BufferAttribute extends BufferAttribute {
  6733. constructor(array, itemSize, normalized) {
  6734. super(new Uint16Array(array), itemSize, normalized);
  6735. this.isFloat16BufferAttribute = true;
  6736. }
  6737. }
  6738. class Float32BufferAttribute extends BufferAttribute {
  6739. constructor(array, itemSize, normalized) {
  6740. super(new Float32Array(array), itemSize, normalized);
  6741. }
  6742. }
  6743. class Float64BufferAttribute extends BufferAttribute {
  6744. constructor(array, itemSize, normalized) {
  6745. super(new Float64Array(array), itemSize, normalized);
  6746. }
  6747. } //
  6748. let _id$1 = 0;
  6749. const _m1 = /*@__PURE__*/new Matrix4();
  6750. const _obj = /*@__PURE__*/new Object3D();
  6751. const _offset = /*@__PURE__*/new Vector3();
  6752. const _box$1 = /*@__PURE__*/new Box3();
  6753. const _boxMorphTargets = /*@__PURE__*/new Box3();
  6754. const _vector$8 = /*@__PURE__*/new Vector3();
  6755. class BufferGeometry extends EventDispatcher {
  6756. constructor() {
  6757. super();
  6758. this.isBufferGeometry = true;
  6759. Object.defineProperty(this, 'id', {
  6760. value: _id$1++
  6761. });
  6762. this.uuid = generateUUID();
  6763. this.name = '';
  6764. this.type = 'BufferGeometry';
  6765. this.index = null;
  6766. this.attributes = {};
  6767. this.morphAttributes = {};
  6768. this.morphTargetsRelative = false;
  6769. this.groups = [];
  6770. this.boundingBox = null;
  6771. this.boundingSphere = null;
  6772. this.drawRange = {
  6773. start: 0,
  6774. count: Infinity
  6775. };
  6776. this.userData = {};
  6777. }
  6778. getIndex() {
  6779. return this.index;
  6780. }
  6781. setIndex(index) {
  6782. if (Array.isArray(index)) {
  6783. this.index = new (arrayNeedsUint32(index) ? Uint32BufferAttribute : Uint16BufferAttribute)(index, 1);
  6784. } else {
  6785. this.index = index;
  6786. }
  6787. return this;
  6788. }
  6789. getAttribute(name) {
  6790. return this.attributes[name];
  6791. }
  6792. setAttribute(name, attribute) {
  6793. this.attributes[name] = attribute;
  6794. return this;
  6795. }
  6796. deleteAttribute(name) {
  6797. delete this.attributes[name];
  6798. return this;
  6799. }
  6800. hasAttribute(name) {
  6801. return this.attributes[name] !== undefined;
  6802. }
  6803. addGroup(start, count, materialIndex = 0) {
  6804. this.groups.push({
  6805. start: start,
  6806. count: count,
  6807. materialIndex: materialIndex
  6808. });
  6809. }
  6810. clearGroups() {
  6811. this.groups = [];
  6812. }
  6813. setDrawRange(start, count) {
  6814. this.drawRange.start = start;
  6815. this.drawRange.count = count;
  6816. }
  6817. applyMatrix4(matrix) {
  6818. const position = this.attributes.position;
  6819. if (position !== undefined) {
  6820. position.applyMatrix4(matrix);
  6821. position.needsUpdate = true;
  6822. }
  6823. const normal = this.attributes.normal;
  6824. if (normal !== undefined) {
  6825. const normalMatrix = new Matrix3().getNormalMatrix(matrix);
  6826. normal.applyNormalMatrix(normalMatrix);
  6827. normal.needsUpdate = true;
  6828. }
  6829. const tangent = this.attributes.tangent;
  6830. if (tangent !== undefined) {
  6831. tangent.transformDirection(matrix);
  6832. tangent.needsUpdate = true;
  6833. }
  6834. if (this.boundingBox !== null) {
  6835. this.computeBoundingBox();
  6836. }
  6837. if (this.boundingSphere !== null) {
  6838. this.computeBoundingSphere();
  6839. }
  6840. return this;
  6841. }
  6842. applyQuaternion(q) {
  6843. _m1.makeRotationFromQuaternion(q);
  6844. this.applyMatrix4(_m1);
  6845. return this;
  6846. }
  6847. rotateX(angle) {
  6848. // rotate geometry around world x-axis
  6849. _m1.makeRotationX(angle);
  6850. this.applyMatrix4(_m1);
  6851. return this;
  6852. }
  6853. rotateY(angle) {
  6854. // rotate geometry around world y-axis
  6855. _m1.makeRotationY(angle);
  6856. this.applyMatrix4(_m1);
  6857. return this;
  6858. }
  6859. rotateZ(angle) {
  6860. // rotate geometry around world z-axis
  6861. _m1.makeRotationZ(angle);
  6862. this.applyMatrix4(_m1);
  6863. return this;
  6864. }
  6865. translate(x, y, z) {
  6866. // translate geometry
  6867. _m1.makeTranslation(x, y, z);
  6868. this.applyMatrix4(_m1);
  6869. return this;
  6870. }
  6871. scale(x, y, z) {
  6872. // scale geometry
  6873. _m1.makeScale(x, y, z);
  6874. this.applyMatrix4(_m1);
  6875. return this;
  6876. }
  6877. lookAt(vector) {
  6878. _obj.lookAt(vector);
  6879. _obj.updateMatrix();
  6880. this.applyMatrix4(_obj.matrix);
  6881. return this;
  6882. }
  6883. center() {
  6884. this.computeBoundingBox();
  6885. this.boundingBox.getCenter(_offset).negate();
  6886. this.translate(_offset.x, _offset.y, _offset.z);
  6887. return this;
  6888. }
  6889. setFromPoints(points) {
  6890. const position = [];
  6891. for (let i = 0, l = points.length; i < l; i++) {
  6892. const point = points[i];
  6893. position.push(point.x, point.y, point.z || 0);
  6894. }
  6895. this.setAttribute('position', new Float32BufferAttribute(position, 3));
  6896. return this;
  6897. }
  6898. computeBoundingBox() {
  6899. if (this.boundingBox === null) {
  6900. this.boundingBox = new Box3();
  6901. }
  6902. const position = this.attributes.position;
  6903. const morphAttributesPosition = this.morphAttributes.position;
  6904. if (position && position.isGLBufferAttribute) {
  6905. console.error('THREE.BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box. Alternatively set "mesh.frustumCulled" to "false".', this);
  6906. this.boundingBox.set(new Vector3(-Infinity, -Infinity, -Infinity), new Vector3(+Infinity, +Infinity, +Infinity));
  6907. return;
  6908. }
  6909. if (position !== undefined) {
  6910. this.boundingBox.setFromBufferAttribute(position); // process morph attributes if present
  6911. if (morphAttributesPosition) {
  6912. for (let i = 0, il = morphAttributesPosition.length; i < il; i++) {
  6913. const morphAttribute = morphAttributesPosition[i];
  6914. _box$1.setFromBufferAttribute(morphAttribute);
  6915. if (this.morphTargetsRelative) {
  6916. _vector$8.addVectors(this.boundingBox.min, _box$1.min);
  6917. this.boundingBox.expandByPoint(_vector$8);
  6918. _vector$8.addVectors(this.boundingBox.max, _box$1.max);
  6919. this.boundingBox.expandByPoint(_vector$8);
  6920. } else {
  6921. this.boundingBox.expandByPoint(_box$1.min);
  6922. this.boundingBox.expandByPoint(_box$1.max);
  6923. }
  6924. }
  6925. }
  6926. } else {
  6927. this.boundingBox.makeEmpty();
  6928. }
  6929. if (isNaN(this.boundingBox.min.x) || isNaN(this.boundingBox.min.y) || isNaN(this.boundingBox.min.z)) {
  6930. console.error('THREE.BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this);
  6931. }
  6932. }
  6933. computeBoundingSphere() {
  6934. if (this.boundingSphere === null) {
  6935. this.boundingSphere = new Sphere();
  6936. }
  6937. const position = this.attributes.position;
  6938. const morphAttributesPosition = this.morphAttributes.position;
  6939. if (position && position.isGLBufferAttribute) {
  6940. console.error('THREE.BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere. Alternatively set "mesh.frustumCulled" to "false".', this);
  6941. this.boundingSphere.set(new Vector3(), Infinity);
  6942. return;
  6943. }
  6944. if (position) {
  6945. // first, find the center of the bounding sphere
  6946. const center = this.boundingSphere.center;
  6947. _box$1.setFromBufferAttribute(position); // process morph attributes if present
  6948. if (morphAttributesPosition) {
  6949. for (let i = 0, il = morphAttributesPosition.length; i < il; i++) {
  6950. const morphAttribute = morphAttributesPosition[i];
  6951. _boxMorphTargets.setFromBufferAttribute(morphAttribute);
  6952. if (this.morphTargetsRelative) {
  6953. _vector$8.addVectors(_box$1.min, _boxMorphTargets.min);
  6954. _box$1.expandByPoint(_vector$8);
  6955. _vector$8.addVectors(_box$1.max, _boxMorphTargets.max);
  6956. _box$1.expandByPoint(_vector$8);
  6957. } else {
  6958. _box$1.expandByPoint(_boxMorphTargets.min);
  6959. _box$1.expandByPoint(_boxMorphTargets.max);
  6960. }
  6961. }
  6962. }
  6963. _box$1.getCenter(center); // second, try to find a boundingSphere with a radius smaller than the
  6964. // boundingSphere of the boundingBox: sqrt(3) smaller in the best case
  6965. let maxRadiusSq = 0;
  6966. for (let i = 0, il = position.count; i < il; i++) {
  6967. _vector$8.fromBufferAttribute(position, i);
  6968. maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
  6969. } // process morph attributes if present
  6970. if (morphAttributesPosition) {
  6971. for (let i = 0, il = morphAttributesPosition.length; i < il; i++) {
  6972. const morphAttribute = morphAttributesPosition[i];
  6973. const morphTargetsRelative = this.morphTargetsRelative;
  6974. for (let j = 0, jl = morphAttribute.count; j < jl; j++) {
  6975. _vector$8.fromBufferAttribute(morphAttribute, j);
  6976. if (morphTargetsRelative) {
  6977. _offset.fromBufferAttribute(position, j);
  6978. _vector$8.add(_offset);
  6979. }
  6980. maxRadiusSq = Math.max(maxRadiusSq, center.distanceToSquared(_vector$8));
  6981. }
  6982. }
  6983. }
  6984. this.boundingSphere.radius = Math.sqrt(maxRadiusSq);
  6985. if (isNaN(this.boundingSphere.radius)) {
  6986. console.error('THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this);
  6987. }
  6988. }
  6989. }
  6990. computeTangents() {
  6991. const index = this.index;
  6992. const attributes = this.attributes; // based on http://www.terathon.com/code/tangent.html
  6993. // (per vertex tangents)
  6994. if (index === null || attributes.position === undefined || attributes.normal === undefined || attributes.uv === undefined) {
  6995. console.error('THREE.BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)');
  6996. return;
  6997. }
  6998. const indices = index.array;
  6999. const positions = attributes.position.array;
  7000. const normals = attributes.normal.array;
  7001. const uvs = attributes.uv.array;
  7002. const nVertices = positions.length / 3;
  7003. if (this.hasAttribute('tangent') === false) {
  7004. this.setAttribute('tangent', new BufferAttribute(new Float32Array(4 * nVertices), 4));
  7005. }
  7006. const tangents = this.getAttribute('tangent').array;
  7007. const tan1 = [],
  7008. tan2 = [];
  7009. for (let i = 0; i < nVertices; i++) {
  7010. tan1[i] = new Vector3();
  7011. tan2[i] = new Vector3();
  7012. }
  7013. const vA = new Vector3(),
  7014. vB = new Vector3(),
  7015. vC = new Vector3(),
  7016. uvA = new Vector2(),
  7017. uvB = new Vector2(),
  7018. uvC = new Vector2(),
  7019. sdir = new Vector3(),
  7020. tdir = new Vector3();
  7021. function handleTriangle(a, b, c) {
  7022. vA.fromArray(positions, a * 3);
  7023. vB.fromArray(positions, b * 3);
  7024. vC.fromArray(positions, c * 3);
  7025. uvA.fromArray(uvs, a * 2);
  7026. uvB.fromArray(uvs, b * 2);
  7027. uvC.fromArray(uvs, c * 2);
  7028. vB.sub(vA);
  7029. vC.sub(vA);
  7030. uvB.sub(uvA);
  7031. uvC.sub(uvA);
  7032. const r = 1.0 / (uvB.x * uvC.y - uvC.x * uvB.y); // silently ignore degenerate uv triangles having coincident or colinear vertices
  7033. if (!isFinite(r)) return;
  7034. sdir.copy(vB).multiplyScalar(uvC.y).addScaledVector(vC, -uvB.y).multiplyScalar(r);
  7035. tdir.copy(vC).multiplyScalar(uvB.x).addScaledVector(vB, -uvC.x).multiplyScalar(r);
  7036. tan1[a].add(sdir);
  7037. tan1[b].add(sdir);
  7038. tan1[c].add(sdir);
  7039. tan2[a].add(tdir);
  7040. tan2[b].add(tdir);
  7041. tan2[c].add(tdir);
  7042. }
  7043. let groups = this.groups;
  7044. if (groups.length === 0) {
  7045. groups = [{
  7046. start: 0,
  7047. count: indices.length
  7048. }];
  7049. }
  7050. for (let i = 0, il = groups.length; i < il; ++i) {
  7051. const group = groups[i];
  7052. const start = group.start;
  7053. const count = group.count;
  7054. for (let j = start, jl = start + count; j < jl; j += 3) {
  7055. handleTriangle(indices[j + 0], indices[j + 1], indices[j + 2]);
  7056. }
  7057. }
  7058. const tmp = new Vector3(),
  7059. tmp2 = new Vector3();
  7060. const n = new Vector3(),
  7061. n2 = new Vector3();
  7062. function handleVertex(v) {
  7063. n.fromArray(normals, v * 3);
  7064. n2.copy(n);
  7065. const t = tan1[v]; // Gram-Schmidt orthogonalize
  7066. tmp.copy(t);
  7067. tmp.sub(n.multiplyScalar(n.dot(t))).normalize(); // Calculate handedness
  7068. tmp2.crossVectors(n2, t);
  7069. const test = tmp2.dot(tan2[v]);
  7070. const w = test < 0.0 ? -1.0 : 1.0;
  7071. tangents[v * 4] = tmp.x;
  7072. tangents[v * 4 + 1] = tmp.y;
  7073. tangents[v * 4 + 2] = tmp.z;
  7074. tangents[v * 4 + 3] = w;
  7075. }
  7076. for (let i = 0, il = groups.length; i < il; ++i) {
  7077. const group = groups[i];
  7078. const start = group.start;
  7079. const count = group.count;
  7080. for (let j = start, jl = start + count; j < jl; j += 3) {
  7081. handleVertex(indices[j + 0]);
  7082. handleVertex(indices[j + 1]);
  7083. handleVertex(indices[j + 2]);
  7084. }
  7085. }
  7086. }
  7087. computeVertexNormals() {
  7088. const index = this.index;
  7089. const positionAttribute = this.getAttribute('position');
  7090. if (positionAttribute !== undefined) {
  7091. let normalAttribute = this.getAttribute('normal');
  7092. if (normalAttribute === undefined) {
  7093. normalAttribute = new BufferAttribute(new Float32Array(positionAttribute.count * 3), 3);
  7094. this.setAttribute('normal', normalAttribute);
  7095. } else {
  7096. // reset existing normals to zero
  7097. for (let i = 0, il = normalAttribute.count; i < il; i++) {
  7098. normalAttribute.setXYZ(i, 0, 0, 0);
  7099. }
  7100. }
  7101. const pA = new Vector3(),
  7102. pB = new Vector3(),
  7103. pC = new Vector3();
  7104. const nA = new Vector3(),
  7105. nB = new Vector3(),
  7106. nC = new Vector3();
  7107. const cb = new Vector3(),
  7108. ab = new Vector3(); // indexed elements
  7109. if (index) {
  7110. for (let i = 0, il = index.count; i < il; i += 3) {
  7111. const vA = index.getX(i + 0);
  7112. const vB = index.getX(i + 1);
  7113. const vC = index.getX(i + 2);
  7114. pA.fromBufferAttribute(positionAttribute, vA);
  7115. pB.fromBufferAttribute(positionAttribute, vB);
  7116. pC.fromBufferAttribute(positionAttribute, vC);
  7117. cb.subVectors(pC, pB);
  7118. ab.subVectors(pA, pB);
  7119. cb.cross(ab);
  7120. nA.fromBufferAttribute(normalAttribute, vA);
  7121. nB.fromBufferAttribute(normalAttribute, vB);
  7122. nC.fromBufferAttribute(normalAttribute, vC);
  7123. nA.add(cb);
  7124. nB.add(cb);
  7125. nC.add(cb);
  7126. normalAttribute.setXYZ(vA, nA.x, nA.y, nA.z);
  7127. normalAttribute.setXYZ(vB, nB.x, nB.y, nB.z);
  7128. normalAttribute.setXYZ(vC, nC.x, nC.y, nC.z);
  7129. }
  7130. } else {
  7131. // non-indexed elements (unconnected triangle soup)
  7132. for (let i = 0, il = positionAttribute.count; i < il; i += 3) {
  7133. pA.fromBufferAttribute(positionAttribute, i + 0);
  7134. pB.fromBufferAttribute(positionAttribute, i + 1);
  7135. pC.fromBufferAttribute(positionAttribute, i + 2);
  7136. cb.subVectors(pC, pB);
  7137. ab.subVectors(pA, pB);
  7138. cb.cross(ab);
  7139. normalAttribute.setXYZ(i + 0, cb.x, cb.y, cb.z);
  7140. normalAttribute.setXYZ(i + 1, cb.x, cb.y, cb.z);
  7141. normalAttribute.setXYZ(i + 2, cb.x, cb.y, cb.z);
  7142. }
  7143. }
  7144. this.normalizeNormals();
  7145. normalAttribute.needsUpdate = true;
  7146. }
  7147. }
  7148. merge(geometry, offset) {
  7149. if (!(geometry && geometry.isBufferGeometry)) {
  7150. console.error('THREE.BufferGeometry.merge(): geometry not an instance of THREE.BufferGeometry.', geometry);
  7151. return;
  7152. }
  7153. if (offset === undefined) {
  7154. offset = 0;
  7155. console.warn('THREE.BufferGeometry.merge(): Overwriting original geometry, starting at offset=0. ' + 'Use BufferGeometryUtils.mergeBufferGeometries() for lossless merge.');
  7156. }
  7157. const attributes = this.attributes;
  7158. for (const key in attributes) {
  7159. if (geometry.attributes[key] === undefined) continue;
  7160. const attribute1 = attributes[key];
  7161. const attributeArray1 = attribute1.array;
  7162. const attribute2 = geometry.attributes[key];
  7163. const attributeArray2 = attribute2.array;
  7164. const attributeOffset = attribute2.itemSize * offset;
  7165. const length = Math.min(attributeArray2.length, attributeArray1.length - attributeOffset);
  7166. for (let i = 0, j = attributeOffset; i < length; i++, j++) {
  7167. attributeArray1[j] = attributeArray2[i];
  7168. }
  7169. }
  7170. return this;
  7171. }
  7172. normalizeNormals() {
  7173. const normals = this.attributes.normal;
  7174. for (let i = 0, il = normals.count; i < il; i++) {
  7175. _vector$8.fromBufferAttribute(normals, i);
  7176. _vector$8.normalize();
  7177. normals.setXYZ(i, _vector$8.x, _vector$8.y, _vector$8.z);
  7178. }
  7179. }
  7180. toNonIndexed() {
  7181. function convertBufferAttribute(attribute, indices) {
  7182. const array = attribute.array;
  7183. const itemSize = attribute.itemSize;
  7184. const normalized = attribute.normalized;
  7185. const array2 = new array.constructor(indices.length * itemSize);
  7186. let index = 0,
  7187. index2 = 0;
  7188. for (let i = 0, l = indices.length; i < l; i++) {
  7189. if (attribute.isInterleavedBufferAttribute) {
  7190. index = indices[i] * attribute.data.stride + attribute.offset;
  7191. } else {
  7192. index = indices[i] * itemSize;
  7193. }
  7194. for (let j = 0; j < itemSize; j++) {
  7195. array2[index2++] = array[index++];
  7196. }
  7197. }
  7198. return new BufferAttribute(array2, itemSize, normalized);
  7199. } //
  7200. if (this.index === null) {
  7201. console.warn('THREE.BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.');
  7202. return this;
  7203. }
  7204. const geometry2 = new BufferGeometry();
  7205. const indices = this.index.array;
  7206. const attributes = this.attributes; // attributes
  7207. for (const name in attributes) {
  7208. const attribute = attributes[name];
  7209. const newAttribute = convertBufferAttribute(attribute, indices);
  7210. geometry2.setAttribute(name, newAttribute);
  7211. } // morph attributes
  7212. const morphAttributes = this.morphAttributes;
  7213. for (const name in morphAttributes) {
  7214. const morphArray = [];
  7215. const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes
  7216. for (let i = 0, il = morphAttribute.length; i < il; i++) {
  7217. const attribute = morphAttribute[i];
  7218. const newAttribute = convertBufferAttribute(attribute, indices);
  7219. morphArray.push(newAttribute);
  7220. }
  7221. geometry2.morphAttributes[name] = morphArray;
  7222. }
  7223. geometry2.morphTargetsRelative = this.morphTargetsRelative; // groups
  7224. const groups = this.groups;
  7225. for (let i = 0, l = groups.length; i < l; i++) {
  7226. const group = groups[i];
  7227. geometry2.addGroup(group.start, group.count, group.materialIndex);
  7228. }
  7229. return geometry2;
  7230. }
  7231. toJSON() {
  7232. const data = {
  7233. metadata: {
  7234. version: 4.5,
  7235. type: 'BufferGeometry',
  7236. generator: 'BufferGeometry.toJSON'
  7237. }
  7238. }; // standard BufferGeometry serialization
  7239. data.uuid = this.uuid;
  7240. data.type = this.type;
  7241. if (this.name !== '') data.name = this.name;
  7242. if (Object.keys(this.userData).length > 0) data.userData = this.userData;
  7243. if (this.parameters !== undefined) {
  7244. const parameters = this.parameters;
  7245. for (const key in parameters) {
  7246. if (parameters[key] !== undefined) data[key] = parameters[key];
  7247. }
  7248. return data;
  7249. } // for simplicity the code assumes attributes are not shared across geometries, see #15811
  7250. data.data = {
  7251. attributes: {}
  7252. };
  7253. const index = this.index;
  7254. if (index !== null) {
  7255. data.data.index = {
  7256. type: index.array.constructor.name,
  7257. array: Array.prototype.slice.call(index.array)
  7258. };
  7259. }
  7260. const attributes = this.attributes;
  7261. for (const key in attributes) {
  7262. const attribute = attributes[key];
  7263. data.data.attributes[key] = attribute.toJSON(data.data);
  7264. }
  7265. const morphAttributes = {};
  7266. let hasMorphAttributes = false;
  7267. for (const key in this.morphAttributes) {
  7268. const attributeArray = this.morphAttributes[key];
  7269. const array = [];
  7270. for (let i = 0, il = attributeArray.length; i < il; i++) {
  7271. const attribute = attributeArray[i];
  7272. array.push(attribute.toJSON(data.data));
  7273. }
  7274. if (array.length > 0) {
  7275. morphAttributes[key] = array;
  7276. hasMorphAttributes = true;
  7277. }
  7278. }
  7279. if (hasMorphAttributes) {
  7280. data.data.morphAttributes = morphAttributes;
  7281. data.data.morphTargetsRelative = this.morphTargetsRelative;
  7282. }
  7283. const groups = this.groups;
  7284. if (groups.length > 0) {
  7285. data.data.groups = JSON.parse(JSON.stringify(groups));
  7286. }
  7287. const boundingSphere = this.boundingSphere;
  7288. if (boundingSphere !== null) {
  7289. data.data.boundingSphere = {
  7290. center: boundingSphere.center.toArray(),
  7291. radius: boundingSphere.radius
  7292. };
  7293. }
  7294. return data;
  7295. }
  7296. clone() {
  7297. return new this.constructor().copy(this);
  7298. }
  7299. copy(source) {
  7300. // reset
  7301. this.index = null;
  7302. this.attributes = {};
  7303. this.morphAttributes = {};
  7304. this.groups = [];
  7305. this.boundingBox = null;
  7306. this.boundingSphere = null; // used for storing cloned, shared data
  7307. const data = {}; // name
  7308. this.name = source.name; // index
  7309. const index = source.index;
  7310. if (index !== null) {
  7311. this.setIndex(index.clone(data));
  7312. } // attributes
  7313. const attributes = source.attributes;
  7314. for (const name in attributes) {
  7315. const attribute = attributes[name];
  7316. this.setAttribute(name, attribute.clone(data));
  7317. } // morph attributes
  7318. const morphAttributes = source.morphAttributes;
  7319. for (const name in morphAttributes) {
  7320. const array = [];
  7321. const morphAttribute = morphAttributes[name]; // morphAttribute: array of Float32BufferAttributes
  7322. for (let i = 0, l = morphAttribute.length; i < l; i++) {
  7323. array.push(morphAttribute[i].clone(data));
  7324. }
  7325. this.morphAttributes[name] = array;
  7326. }
  7327. this.morphTargetsRelative = source.morphTargetsRelative; // groups
  7328. const groups = source.groups;
  7329. for (let i = 0, l = groups.length; i < l; i++) {
  7330. const group = groups[i];
  7331. this.addGroup(group.start, group.count, group.materialIndex);
  7332. } // bounding box
  7333. const boundingBox = source.boundingBox;
  7334. if (boundingBox !== null) {
  7335. this.boundingBox = boundingBox.clone();
  7336. } // bounding sphere
  7337. const boundingSphere = source.boundingSphere;
  7338. if (boundingSphere !== null) {
  7339. this.boundingSphere = boundingSphere.clone();
  7340. } // draw range
  7341. this.drawRange.start = source.drawRange.start;
  7342. this.drawRange.count = source.drawRange.count; // user data
  7343. this.userData = source.userData; // geometry generator parameters
  7344. if (source.parameters !== undefined) this.parameters = Object.assign({}, source.parameters);
  7345. return this;
  7346. }
  7347. dispose() {
  7348. this.dispatchEvent({
  7349. type: 'dispose'
  7350. });
  7351. }
  7352. }
  7353. const _inverseMatrix$2 = /*@__PURE__*/new Matrix4();
  7354. const _ray$2 = /*@__PURE__*/new Ray();
  7355. const _sphere$3 = /*@__PURE__*/new Sphere();
  7356. const _vA$1 = /*@__PURE__*/new Vector3();
  7357. const _vB$1 = /*@__PURE__*/new Vector3();
  7358. const _vC$1 = /*@__PURE__*/new Vector3();
  7359. const _tempA = /*@__PURE__*/new Vector3();
  7360. const _tempB = /*@__PURE__*/new Vector3();
  7361. const _tempC = /*@__PURE__*/new Vector3();
  7362. const _morphA = /*@__PURE__*/new Vector3();
  7363. const _morphB = /*@__PURE__*/new Vector3();
  7364. const _morphC = /*@__PURE__*/new Vector3();
  7365. const _uvA$1 = /*@__PURE__*/new Vector2();
  7366. const _uvB$1 = /*@__PURE__*/new Vector2();
  7367. const _uvC$1 = /*@__PURE__*/new Vector2();
  7368. const _intersectionPoint = /*@__PURE__*/new Vector3();
  7369. const _intersectionPointWorld = /*@__PURE__*/new Vector3();
  7370. class Mesh extends Object3D {
  7371. constructor(geometry = new BufferGeometry(), material = new MeshBasicMaterial()) {
  7372. super();
  7373. this.isMesh = true;
  7374. this.type = 'Mesh';
  7375. this.geometry = geometry;
  7376. this.material = material;
  7377. this.updateMorphTargets();
  7378. }
  7379. copy(source, recursive) {
  7380. super.copy(source, recursive);
  7381. if (source.morphTargetInfluences !== undefined) {
  7382. this.morphTargetInfluences = source.morphTargetInfluences.slice();
  7383. }
  7384. if (source.morphTargetDictionary !== undefined) {
  7385. this.morphTargetDictionary = Object.assign({}, source.morphTargetDictionary);
  7386. }
  7387. this.material = source.material;
  7388. this.geometry = source.geometry;
  7389. return this;
  7390. }
  7391. updateMorphTargets() {
  7392. const geometry = this.geometry;
  7393. const morphAttributes = geometry.morphAttributes;
  7394. const keys = Object.keys(morphAttributes);
  7395. if (keys.length > 0) {
  7396. const morphAttribute = morphAttributes[keys[0]];
  7397. if (morphAttribute !== undefined) {
  7398. this.morphTargetInfluences = [];
  7399. this.morphTargetDictionary = {};
  7400. for (let m = 0, ml = morphAttribute.length; m < ml; m++) {
  7401. const name = morphAttribute[m].name || String(m);
  7402. this.morphTargetInfluences.push(0);
  7403. this.morphTargetDictionary[name] = m;
  7404. }
  7405. }
  7406. }
  7407. }
  7408. raycast(raycaster, intersects) {
  7409. const geometry = this.geometry;
  7410. const material = this.material;
  7411. const matrixWorld = this.matrixWorld;
  7412. if (material === undefined) return; // Checking boundingSphere distance to ray
  7413. if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
  7414. _sphere$3.copy(geometry.boundingSphere);
  7415. _sphere$3.applyMatrix4(matrixWorld);
  7416. if (raycaster.ray.intersectsSphere(_sphere$3) === false) return; //
  7417. _inverseMatrix$2.copy(matrixWorld).invert();
  7418. _ray$2.copy(raycaster.ray).applyMatrix4(_inverseMatrix$2); // Check boundingBox before continuing
  7419. if (geometry.boundingBox !== null) {
  7420. if (_ray$2.intersectsBox(geometry.boundingBox) === false) return;
  7421. }
  7422. let intersection;
  7423. const index = geometry.index;
  7424. const position = geometry.attributes.position;
  7425. const morphPosition = geometry.morphAttributes.position;
  7426. const morphTargetsRelative = geometry.morphTargetsRelative;
  7427. const uv = geometry.attributes.uv;
  7428. const uv2 = geometry.attributes.uv2;
  7429. const groups = geometry.groups;
  7430. const drawRange = geometry.drawRange;
  7431. if (index !== null) {
  7432. // indexed buffer geometry
  7433. if (Array.isArray(material)) {
  7434. for (let i = 0, il = groups.length; i < il; i++) {
  7435. const group = groups[i];
  7436. const groupMaterial = material[group.materialIndex];
  7437. const start = Math.max(group.start, drawRange.start);
  7438. const end = Math.min(index.count, Math.min(group.start + group.count, drawRange.start + drawRange.count));
  7439. for (let j = start, jl = end; j < jl; j += 3) {
  7440. const a = index.getX(j);
  7441. const b = index.getX(j + 1);
  7442. const c = index.getX(j + 2);
  7443. intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
  7444. if (intersection) {
  7445. intersection.faceIndex = Math.floor(j / 3); // triangle number in indexed buffer semantics
  7446. intersection.face.materialIndex = group.materialIndex;
  7447. intersects.push(intersection);
  7448. }
  7449. }
  7450. }
  7451. } else {
  7452. const start = Math.max(0, drawRange.start);
  7453. const end = Math.min(index.count, drawRange.start + drawRange.count);
  7454. for (let i = start, il = end; i < il; i += 3) {
  7455. const a = index.getX(i);
  7456. const b = index.getX(i + 1);
  7457. const c = index.getX(i + 2);
  7458. intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
  7459. if (intersection) {
  7460. intersection.faceIndex = Math.floor(i / 3); // triangle number in indexed buffer semantics
  7461. intersects.push(intersection);
  7462. }
  7463. }
  7464. }
  7465. } else if (position !== undefined) {
  7466. // non-indexed buffer geometry
  7467. if (Array.isArray(material)) {
  7468. for (let i = 0, il = groups.length; i < il; i++) {
  7469. const group = groups[i];
  7470. const groupMaterial = material[group.materialIndex];
  7471. const start = Math.max(group.start, drawRange.start);
  7472. const end = Math.min(position.count, Math.min(group.start + group.count, drawRange.start + drawRange.count));
  7473. for (let j = start, jl = end; j < jl; j += 3) {
  7474. const a = j;
  7475. const b = j + 1;
  7476. const c = j + 2;
  7477. intersection = checkBufferGeometryIntersection(this, groupMaterial, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
  7478. if (intersection) {
  7479. intersection.faceIndex = Math.floor(j / 3); // triangle number in non-indexed buffer semantics
  7480. intersection.face.materialIndex = group.materialIndex;
  7481. intersects.push(intersection);
  7482. }
  7483. }
  7484. }
  7485. } else {
  7486. const start = Math.max(0, drawRange.start);
  7487. const end = Math.min(position.count, drawRange.start + drawRange.count);
  7488. for (let i = start, il = end; i < il; i += 3) {
  7489. const a = i;
  7490. const b = i + 1;
  7491. const c = i + 2;
  7492. intersection = checkBufferGeometryIntersection(this, material, raycaster, _ray$2, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c);
  7493. if (intersection) {
  7494. intersection.faceIndex = Math.floor(i / 3); // triangle number in non-indexed buffer semantics
  7495. intersects.push(intersection);
  7496. }
  7497. }
  7498. }
  7499. }
  7500. }
  7501. }
  7502. function checkIntersection(object, material, raycaster, ray, pA, pB, pC, point) {
  7503. let intersect;
  7504. if (material.side === BackSide) {
  7505. intersect = ray.intersectTriangle(pC, pB, pA, true, point);
  7506. } else {
  7507. intersect = ray.intersectTriangle(pA, pB, pC, material.side !== DoubleSide, point);
  7508. }
  7509. if (intersect === null) return null;
  7510. _intersectionPointWorld.copy(point);
  7511. _intersectionPointWorld.applyMatrix4(object.matrixWorld);
  7512. const distance = raycaster.ray.origin.distanceTo(_intersectionPointWorld);
  7513. if (distance < raycaster.near || distance > raycaster.far) return null;
  7514. return {
  7515. distance: distance,
  7516. point: _intersectionPointWorld.clone(),
  7517. object: object
  7518. };
  7519. }
  7520. function checkBufferGeometryIntersection(object, material, raycaster, ray, position, morphPosition, morphTargetsRelative, uv, uv2, a, b, c) {
  7521. _vA$1.fromBufferAttribute(position, a);
  7522. _vB$1.fromBufferAttribute(position, b);
  7523. _vC$1.fromBufferAttribute(position, c);
  7524. const morphInfluences = object.morphTargetInfluences;
  7525. if (morphPosition && morphInfluences) {
  7526. _morphA.set(0, 0, 0);
  7527. _morphB.set(0, 0, 0);
  7528. _morphC.set(0, 0, 0);
  7529. for (let i = 0, il = morphPosition.length; i < il; i++) {
  7530. const influence = morphInfluences[i];
  7531. const morphAttribute = morphPosition[i];
  7532. if (influence === 0) continue;
  7533. _tempA.fromBufferAttribute(morphAttribute, a);
  7534. _tempB.fromBufferAttribute(morphAttribute, b);
  7535. _tempC.fromBufferAttribute(morphAttribute, c);
  7536. if (morphTargetsRelative) {
  7537. _morphA.addScaledVector(_tempA, influence);
  7538. _morphB.addScaledVector(_tempB, influence);
  7539. _morphC.addScaledVector(_tempC, influence);
  7540. } else {
  7541. _morphA.addScaledVector(_tempA.sub(_vA$1), influence);
  7542. _morphB.addScaledVector(_tempB.sub(_vB$1), influence);
  7543. _morphC.addScaledVector(_tempC.sub(_vC$1), influence);
  7544. }
  7545. }
  7546. _vA$1.add(_morphA);
  7547. _vB$1.add(_morphB);
  7548. _vC$1.add(_morphC);
  7549. }
  7550. if (object.isSkinnedMesh) {
  7551. object.boneTransform(a, _vA$1);
  7552. object.boneTransform(b, _vB$1);
  7553. object.boneTransform(c, _vC$1);
  7554. }
  7555. const intersection = checkIntersection(object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint);
  7556. if (intersection) {
  7557. if (uv) {
  7558. _uvA$1.fromBufferAttribute(uv, a);
  7559. _uvB$1.fromBufferAttribute(uv, b);
  7560. _uvC$1.fromBufferAttribute(uv, c);
  7561. intersection.uv = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
  7562. }
  7563. if (uv2) {
  7564. _uvA$1.fromBufferAttribute(uv2, a);
  7565. _uvB$1.fromBufferAttribute(uv2, b);
  7566. _uvC$1.fromBufferAttribute(uv2, c);
  7567. intersection.uv2 = Triangle.getUV(_intersectionPoint, _vA$1, _vB$1, _vC$1, _uvA$1, _uvB$1, _uvC$1, new Vector2());
  7568. }
  7569. const face = {
  7570. a: a,
  7571. b: b,
  7572. c: c,
  7573. normal: new Vector3(),
  7574. materialIndex: 0
  7575. };
  7576. Triangle.getNormal(_vA$1, _vB$1, _vC$1, face.normal);
  7577. intersection.face = face;
  7578. }
  7579. return intersection;
  7580. }
  7581. class BoxGeometry extends BufferGeometry {
  7582. constructor(width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1) {
  7583. super();
  7584. this.type = 'BoxGeometry';
  7585. this.parameters = {
  7586. width: width,
  7587. height: height,
  7588. depth: depth,
  7589. widthSegments: widthSegments,
  7590. heightSegments: heightSegments,
  7591. depthSegments: depthSegments
  7592. };
  7593. const scope = this; // segments
  7594. widthSegments = Math.floor(widthSegments);
  7595. heightSegments = Math.floor(heightSegments);
  7596. depthSegments = Math.floor(depthSegments); // buffers
  7597. const indices = [];
  7598. const vertices = [];
  7599. const normals = [];
  7600. const uvs = []; // helper variables
  7601. let numberOfVertices = 0;
  7602. let groupStart = 0; // build each side of the box geometry
  7603. buildPlane('z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0); // px
  7604. buildPlane('z', 'y', 'x', 1, -1, depth, height, -width, depthSegments, heightSegments, 1); // nx
  7605. buildPlane('x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2); // py
  7606. buildPlane('x', 'z', 'y', 1, -1, width, depth, -height, widthSegments, depthSegments, 3); // ny
  7607. buildPlane('x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4); // pz
  7608. buildPlane('x', 'y', 'z', -1, -1, width, height, -depth, widthSegments, heightSegments, 5); // nz
  7609. // build geometry
  7610. this.setIndex(indices);
  7611. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  7612. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  7613. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  7614. function buildPlane(u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex) {
  7615. const segmentWidth = width / gridX;
  7616. const segmentHeight = height / gridY;
  7617. const widthHalf = width / 2;
  7618. const heightHalf = height / 2;
  7619. const depthHalf = depth / 2;
  7620. const gridX1 = gridX + 1;
  7621. const gridY1 = gridY + 1;
  7622. let vertexCounter = 0;
  7623. let groupCount = 0;
  7624. const vector = new Vector3(); // generate vertices, normals and uvs
  7625. for (let iy = 0; iy < gridY1; iy++) {
  7626. const y = iy * segmentHeight - heightHalf;
  7627. for (let ix = 0; ix < gridX1; ix++) {
  7628. const x = ix * segmentWidth - widthHalf; // set values to correct vector component
  7629. vector[u] = x * udir;
  7630. vector[v] = y * vdir;
  7631. vector[w] = depthHalf; // now apply vector to vertex buffer
  7632. vertices.push(vector.x, vector.y, vector.z); // set values to correct vector component
  7633. vector[u] = 0;
  7634. vector[v] = 0;
  7635. vector[w] = depth > 0 ? 1 : -1; // now apply vector to normal buffer
  7636. normals.push(vector.x, vector.y, vector.z); // uvs
  7637. uvs.push(ix / gridX);
  7638. uvs.push(1 - iy / gridY); // counters
  7639. vertexCounter += 1;
  7640. }
  7641. } // indices
  7642. // 1. you need three indices to draw a single face
  7643. // 2. a single segment consists of two faces
  7644. // 3. so we need to generate six (2*3) indices per segment
  7645. for (let iy = 0; iy < gridY; iy++) {
  7646. for (let ix = 0; ix < gridX; ix++) {
  7647. const a = numberOfVertices + ix + gridX1 * iy;
  7648. const b = numberOfVertices + ix + gridX1 * (iy + 1);
  7649. const c = numberOfVertices + (ix + 1) + gridX1 * (iy + 1);
  7650. const d = numberOfVertices + (ix + 1) + gridX1 * iy; // faces
  7651. indices.push(a, b, d);
  7652. indices.push(b, c, d); // increase counter
  7653. groupCount += 6;
  7654. }
  7655. } // add a group to the geometry. this will ensure multi material support
  7656. scope.addGroup(groupStart, groupCount, materialIndex); // calculate new start value for groups
  7657. groupStart += groupCount; // update total number of vertices
  7658. numberOfVertices += vertexCounter;
  7659. }
  7660. }
  7661. static fromJSON(data) {
  7662. return new BoxGeometry(data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments);
  7663. }
  7664. }
  7665. /**
  7666. * Uniform Utilities
  7667. */
  7668. function cloneUniforms(src) {
  7669. const dst = {};
  7670. for (const u in src) {
  7671. dst[u] = {};
  7672. for (const p in src[u]) {
  7673. const property = src[u][p];
  7674. if (property && (property.isColor || property.isMatrix3 || property.isMatrix4 || property.isVector2 || property.isVector3 || property.isVector4 || property.isTexture || property.isQuaternion)) {
  7675. dst[u][p] = property.clone();
  7676. } else if (Array.isArray(property)) {
  7677. dst[u][p] = property.slice();
  7678. } else {
  7679. dst[u][p] = property;
  7680. }
  7681. }
  7682. }
  7683. return dst;
  7684. }
  7685. function mergeUniforms(uniforms) {
  7686. const merged = {};
  7687. for (let u = 0; u < uniforms.length; u++) {
  7688. const tmp = cloneUniforms(uniforms[u]);
  7689. for (const p in tmp) {
  7690. merged[p] = tmp[p];
  7691. }
  7692. }
  7693. return merged;
  7694. }
  7695. function cloneUniformsGroups(src) {
  7696. const dst = [];
  7697. for (let u = 0; u < src.length; u++) {
  7698. dst.push(src[u].clone());
  7699. }
  7700. return dst;
  7701. } // Legacy
  7702. const UniformsUtils = {
  7703. clone: cloneUniforms,
  7704. merge: mergeUniforms
  7705. };
  7706. var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}";
  7707. var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}";
  7708. class ShaderMaterial extends Material {
  7709. constructor(parameters) {
  7710. super();
  7711. this.isShaderMaterial = true;
  7712. this.type = 'ShaderMaterial';
  7713. this.defines = {};
  7714. this.uniforms = {};
  7715. this.uniformsGroups = [];
  7716. this.vertexShader = default_vertex;
  7717. this.fragmentShader = default_fragment;
  7718. this.linewidth = 1;
  7719. this.wireframe = false;
  7720. this.wireframeLinewidth = 1;
  7721. this.fog = false; // set to use scene fog
  7722. this.lights = false; // set to use scene lights
  7723. this.clipping = false; // set to use user-defined clipping planes
  7724. this.extensions = {
  7725. derivatives: false,
  7726. // set to use derivatives
  7727. fragDepth: false,
  7728. // set to use fragment depth values
  7729. drawBuffers: false,
  7730. // set to use draw buffers
  7731. shaderTextureLOD: false // set to use shader texture LOD
  7732. }; // When rendered geometry doesn't include these attributes but the material does,
  7733. // use these default values in WebGL. This avoids errors when buffer data is missing.
  7734. this.defaultAttributeValues = {
  7735. 'color': [1, 1, 1],
  7736. 'uv': [0, 0],
  7737. 'uv2': [0, 0]
  7738. };
  7739. this.index0AttributeName = undefined;
  7740. this.uniformsNeedUpdate = false;
  7741. this.glslVersion = null;
  7742. if (parameters !== undefined) {
  7743. if (parameters.attributes !== undefined) {
  7744. console.error('THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.');
  7745. }
  7746. this.setValues(parameters);
  7747. }
  7748. }
  7749. copy(source) {
  7750. super.copy(source);
  7751. this.fragmentShader = source.fragmentShader;
  7752. this.vertexShader = source.vertexShader;
  7753. this.uniforms = cloneUniforms(source.uniforms);
  7754. this.uniformsGroups = cloneUniformsGroups(source.uniformsGroups);
  7755. this.defines = Object.assign({}, source.defines);
  7756. this.wireframe = source.wireframe;
  7757. this.wireframeLinewidth = source.wireframeLinewidth;
  7758. this.fog = source.fog;
  7759. this.lights = source.lights;
  7760. this.clipping = source.clipping;
  7761. this.extensions = Object.assign({}, source.extensions);
  7762. this.glslVersion = source.glslVersion;
  7763. return this;
  7764. }
  7765. toJSON(meta) {
  7766. const data = super.toJSON(meta);
  7767. data.glslVersion = this.glslVersion;
  7768. data.uniforms = {};
  7769. for (const name in this.uniforms) {
  7770. const uniform = this.uniforms[name];
  7771. const value = uniform.value;
  7772. if (value && value.isTexture) {
  7773. data.uniforms[name] = {
  7774. type: 't',
  7775. value: value.toJSON(meta).uuid
  7776. };
  7777. } else if (value && value.isColor) {
  7778. data.uniforms[name] = {
  7779. type: 'c',
  7780. value: value.getHex()
  7781. };
  7782. } else if (value && value.isVector2) {
  7783. data.uniforms[name] = {
  7784. type: 'v2',
  7785. value: value.toArray()
  7786. };
  7787. } else if (value && value.isVector3) {
  7788. data.uniforms[name] = {
  7789. type: 'v3',
  7790. value: value.toArray()
  7791. };
  7792. } else if (value && value.isVector4) {
  7793. data.uniforms[name] = {
  7794. type: 'v4',
  7795. value: value.toArray()
  7796. };
  7797. } else if (value && value.isMatrix3) {
  7798. data.uniforms[name] = {
  7799. type: 'm3',
  7800. value: value.toArray()
  7801. };
  7802. } else if (value && value.isMatrix4) {
  7803. data.uniforms[name] = {
  7804. type: 'm4',
  7805. value: value.toArray()
  7806. };
  7807. } else {
  7808. data.uniforms[name] = {
  7809. value: value
  7810. }; // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far
  7811. }
  7812. }
  7813. if (Object.keys(this.defines).length > 0) data.defines = this.defines;
  7814. data.vertexShader = this.vertexShader;
  7815. data.fragmentShader = this.fragmentShader;
  7816. const extensions = {};
  7817. for (const key in this.extensions) {
  7818. if (this.extensions[key] === true) extensions[key] = true;
  7819. }
  7820. if (Object.keys(extensions).length > 0) data.extensions = extensions;
  7821. return data;
  7822. }
  7823. }
  7824. class Camera extends Object3D {
  7825. constructor() {
  7826. super();
  7827. this.isCamera = true;
  7828. this.type = 'Camera';
  7829. this.matrixWorldInverse = new Matrix4();
  7830. this.projectionMatrix = new Matrix4();
  7831. this.projectionMatrixInverse = new Matrix4();
  7832. }
  7833. copy(source, recursive) {
  7834. super.copy(source, recursive);
  7835. this.matrixWorldInverse.copy(source.matrixWorldInverse);
  7836. this.projectionMatrix.copy(source.projectionMatrix);
  7837. this.projectionMatrixInverse.copy(source.projectionMatrixInverse);
  7838. return this;
  7839. }
  7840. getWorldDirection(target) {
  7841. this.updateWorldMatrix(true, false);
  7842. const e = this.matrixWorld.elements;
  7843. return target.set(-e[8], -e[9], -e[10]).normalize();
  7844. }
  7845. updateMatrixWorld(force) {
  7846. super.updateMatrixWorld(force);
  7847. this.matrixWorldInverse.copy(this.matrixWorld).invert();
  7848. }
  7849. updateWorldMatrix(updateParents, updateChildren) {
  7850. super.updateWorldMatrix(updateParents, updateChildren);
  7851. this.matrixWorldInverse.copy(this.matrixWorld).invert();
  7852. }
  7853. clone() {
  7854. return new this.constructor().copy(this);
  7855. }
  7856. }
  7857. class PerspectiveCamera extends Camera {
  7858. constructor(fov = 50, aspect = 1, near = 0.1, far = 2000) {
  7859. super();
  7860. this.isPerspectiveCamera = true;
  7861. this.type = 'PerspectiveCamera';
  7862. this.fov = fov;
  7863. this.zoom = 1;
  7864. this.near = near;
  7865. this.far = far;
  7866. this.focus = 10;
  7867. this.aspect = aspect;
  7868. this.view = null;
  7869. this.filmGauge = 35; // width of the film (default in millimeters)
  7870. this.filmOffset = 0; // horizontal film offset (same unit as gauge)
  7871. this.updateProjectionMatrix();
  7872. }
  7873. copy(source, recursive) {
  7874. super.copy(source, recursive);
  7875. this.fov = source.fov;
  7876. this.zoom = source.zoom;
  7877. this.near = source.near;
  7878. this.far = source.far;
  7879. this.focus = source.focus;
  7880. this.aspect = source.aspect;
  7881. this.view = source.view === null ? null : Object.assign({}, source.view);
  7882. this.filmGauge = source.filmGauge;
  7883. this.filmOffset = source.filmOffset;
  7884. return this;
  7885. }
  7886. /**
  7887. * Sets the FOV by focal length in respect to the current .filmGauge.
  7888. *
  7889. * The default film gauge is 35, so that the focal length can be specified for
  7890. * a 35mm (full frame) camera.
  7891. *
  7892. * Values for focal length and film gauge must have the same unit.
  7893. */
  7894. setFocalLength(focalLength) {
  7895. /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */
  7896. const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength;
  7897. this.fov = RAD2DEG * 2 * Math.atan(vExtentSlope);
  7898. this.updateProjectionMatrix();
  7899. }
  7900. /**
  7901. * Calculates the focal length from the current .fov and .filmGauge.
  7902. */
  7903. getFocalLength() {
  7904. const vExtentSlope = Math.tan(DEG2RAD * 0.5 * this.fov);
  7905. return 0.5 * this.getFilmHeight() / vExtentSlope;
  7906. }
  7907. getEffectiveFOV() {
  7908. return RAD2DEG * 2 * Math.atan(Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom);
  7909. }
  7910. getFilmWidth() {
  7911. // film not completely covered in portrait format (aspect < 1)
  7912. return this.filmGauge * Math.min(this.aspect, 1);
  7913. }
  7914. getFilmHeight() {
  7915. // film not completely covered in landscape format (aspect > 1)
  7916. return this.filmGauge / Math.max(this.aspect, 1);
  7917. }
  7918. /**
  7919. * Sets an offset in a larger frustum. This is useful for multi-window or
  7920. * multi-monitor/multi-machine setups.
  7921. *
  7922. * For example, if you have 3x2 monitors and each monitor is 1920x1080 and
  7923. * the monitors are in grid like this
  7924. *
  7925. * +---+---+---+
  7926. * | A | B | C |
  7927. * +---+---+---+
  7928. * | D | E | F |
  7929. * +---+---+---+
  7930. *
  7931. * then for each monitor you would call it like this
  7932. *
  7933. * const w = 1920;
  7934. * const h = 1080;
  7935. * const fullWidth = w * 3;
  7936. * const fullHeight = h * 2;
  7937. *
  7938. * --A--
  7939. * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h );
  7940. * --B--
  7941. * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h );
  7942. * --C--
  7943. * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h );
  7944. * --D--
  7945. * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h );
  7946. * --E--
  7947. * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h );
  7948. * --F--
  7949. * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );
  7950. *
  7951. * Note there is no reason monitors have to be the same size or in a grid.
  7952. */
  7953. setViewOffset(fullWidth, fullHeight, x, y, width, height) {
  7954. this.aspect = fullWidth / fullHeight;
  7955. if (this.view === null) {
  7956. this.view = {
  7957. enabled: true,
  7958. fullWidth: 1,
  7959. fullHeight: 1,
  7960. offsetX: 0,
  7961. offsetY: 0,
  7962. width: 1,
  7963. height: 1
  7964. };
  7965. }
  7966. this.view.enabled = true;
  7967. this.view.fullWidth = fullWidth;
  7968. this.view.fullHeight = fullHeight;
  7969. this.view.offsetX = x;
  7970. this.view.offsetY = y;
  7971. this.view.width = width;
  7972. this.view.height = height;
  7973. this.updateProjectionMatrix();
  7974. }
  7975. clearViewOffset() {
  7976. if (this.view !== null) {
  7977. this.view.enabled = false;
  7978. }
  7979. this.updateProjectionMatrix();
  7980. }
  7981. updateProjectionMatrix() {
  7982. const near = this.near;
  7983. let top = near * Math.tan(DEG2RAD * 0.5 * this.fov) / this.zoom;
  7984. let height = 2 * top;
  7985. let width = this.aspect * height;
  7986. let left = -0.5 * width;
  7987. const view = this.view;
  7988. if (this.view !== null && this.view.enabled) {
  7989. const fullWidth = view.fullWidth,
  7990. fullHeight = view.fullHeight;
  7991. left += view.offsetX * width / fullWidth;
  7992. top -= view.offsetY * height / fullHeight;
  7993. width *= view.width / fullWidth;
  7994. height *= view.height / fullHeight;
  7995. }
  7996. const skew = this.filmOffset;
  7997. if (skew !== 0) left += near * skew / this.getFilmWidth();
  7998. this.projectionMatrix.makePerspective(left, left + width, top, top - height, near, this.far);
  7999. this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
  8000. }
  8001. toJSON(meta) {
  8002. const data = super.toJSON(meta);
  8003. data.object.fov = this.fov;
  8004. data.object.zoom = this.zoom;
  8005. data.object.near = this.near;
  8006. data.object.far = this.far;
  8007. data.object.focus = this.focus;
  8008. data.object.aspect = this.aspect;
  8009. if (this.view !== null) data.object.view = Object.assign({}, this.view);
  8010. data.object.filmGauge = this.filmGauge;
  8011. data.object.filmOffset = this.filmOffset;
  8012. return data;
  8013. }
  8014. }
  8015. const fov = 90,
  8016. aspect = 1;
  8017. class CubeCamera extends Object3D {
  8018. constructor(near, far, renderTarget) {
  8019. super();
  8020. this.type = 'CubeCamera';
  8021. if (renderTarget.isWebGLCubeRenderTarget !== true) {
  8022. console.error('THREE.CubeCamera: The constructor now expects an instance of WebGLCubeRenderTarget as third parameter.');
  8023. return;
  8024. }
  8025. this.renderTarget = renderTarget;
  8026. const cameraPX = new PerspectiveCamera(fov, aspect, near, far);
  8027. cameraPX.layers = this.layers;
  8028. cameraPX.up.set(0, -1, 0);
  8029. cameraPX.lookAt(new Vector3(1, 0, 0));
  8030. this.add(cameraPX);
  8031. const cameraNX = new PerspectiveCamera(fov, aspect, near, far);
  8032. cameraNX.layers = this.layers;
  8033. cameraNX.up.set(0, -1, 0);
  8034. cameraNX.lookAt(new Vector3(-1, 0, 0));
  8035. this.add(cameraNX);
  8036. const cameraPY = new PerspectiveCamera(fov, aspect, near, far);
  8037. cameraPY.layers = this.layers;
  8038. cameraPY.up.set(0, 0, 1);
  8039. cameraPY.lookAt(new Vector3(0, 1, 0));
  8040. this.add(cameraPY);
  8041. const cameraNY = new PerspectiveCamera(fov, aspect, near, far);
  8042. cameraNY.layers = this.layers;
  8043. cameraNY.up.set(0, 0, -1);
  8044. cameraNY.lookAt(new Vector3(0, -1, 0));
  8045. this.add(cameraNY);
  8046. const cameraPZ = new PerspectiveCamera(fov, aspect, near, far);
  8047. cameraPZ.layers = this.layers;
  8048. cameraPZ.up.set(0, -1, 0);
  8049. cameraPZ.lookAt(new Vector3(0, 0, 1));
  8050. this.add(cameraPZ);
  8051. const cameraNZ = new PerspectiveCamera(fov, aspect, near, far);
  8052. cameraNZ.layers = this.layers;
  8053. cameraNZ.up.set(0, -1, 0);
  8054. cameraNZ.lookAt(new Vector3(0, 0, -1));
  8055. this.add(cameraNZ);
  8056. }
  8057. update(renderer, scene) {
  8058. if (this.parent === null) this.updateMatrixWorld();
  8059. const renderTarget = this.renderTarget;
  8060. const [cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ] = this.children;
  8061. const currentRenderTarget = renderer.getRenderTarget();
  8062. const currentToneMapping = renderer.toneMapping;
  8063. const currentXrEnabled = renderer.xr.enabled;
  8064. renderer.toneMapping = NoToneMapping;
  8065. renderer.xr.enabled = false;
  8066. const generateMipmaps = renderTarget.texture.generateMipmaps;
  8067. renderTarget.texture.generateMipmaps = false;
  8068. renderer.setRenderTarget(renderTarget, 0);
  8069. renderer.render(scene, cameraPX);
  8070. renderer.setRenderTarget(renderTarget, 1);
  8071. renderer.render(scene, cameraNX);
  8072. renderer.setRenderTarget(renderTarget, 2);
  8073. renderer.render(scene, cameraPY);
  8074. renderer.setRenderTarget(renderTarget, 3);
  8075. renderer.render(scene, cameraNY);
  8076. renderer.setRenderTarget(renderTarget, 4);
  8077. renderer.render(scene, cameraPZ);
  8078. renderTarget.texture.generateMipmaps = generateMipmaps;
  8079. renderer.setRenderTarget(renderTarget, 5);
  8080. renderer.render(scene, cameraNZ);
  8081. renderer.setRenderTarget(currentRenderTarget);
  8082. renderer.toneMapping = currentToneMapping;
  8083. renderer.xr.enabled = currentXrEnabled;
  8084. renderTarget.texture.needsPMREMUpdate = true;
  8085. }
  8086. }
  8087. class CubeTexture extends Texture {
  8088. constructor(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding) {
  8089. images = images !== undefined ? images : [];
  8090. mapping = mapping !== undefined ? mapping : CubeReflectionMapping;
  8091. super(images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
  8092. this.isCubeTexture = true;
  8093. this.flipY = false;
  8094. }
  8095. get images() {
  8096. return this.image;
  8097. }
  8098. set images(value) {
  8099. this.image = value;
  8100. }
  8101. }
  8102. class WebGLCubeRenderTarget extends WebGLRenderTarget {
  8103. constructor(size, options = {}) {
  8104. super(size, size, options);
  8105. this.isWebGLCubeRenderTarget = true;
  8106. const image = {
  8107. width: size,
  8108. height: size,
  8109. depth: 1
  8110. };
  8111. const images = [image, image, image, image, image, image];
  8112. this.texture = new CubeTexture(images, options.mapping, options.wrapS, options.wrapT, options.magFilter, options.minFilter, options.format, options.type, options.anisotropy, options.encoding); // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js)
  8113. // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words,
  8114. // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly.
  8115. // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped
  8116. // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture
  8117. // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures).
  8118. this.texture.isRenderTargetTexture = true;
  8119. this.texture.generateMipmaps = options.generateMipmaps !== undefined ? options.generateMipmaps : false;
  8120. this.texture.minFilter = options.minFilter !== undefined ? options.minFilter : LinearFilter;
  8121. }
  8122. fromEquirectangularTexture(renderer, texture) {
  8123. this.texture.type = texture.type;
  8124. this.texture.encoding = texture.encoding;
  8125. this.texture.generateMipmaps = texture.generateMipmaps;
  8126. this.texture.minFilter = texture.minFilter;
  8127. this.texture.magFilter = texture.magFilter;
  8128. const shader = {
  8129. uniforms: {
  8130. tEquirect: {
  8131. value: null
  8132. }
  8133. },
  8134. vertexShader:
  8135. /* glsl */
  8136. `
  8137. varying vec3 vWorldDirection;
  8138. vec3 transformDirection( in vec3 dir, in mat4 matrix ) {
  8139. return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );
  8140. }
  8141. void main() {
  8142. vWorldDirection = transformDirection( position, modelMatrix );
  8143. #include <begin_vertex>
  8144. #include <project_vertex>
  8145. }
  8146. `,
  8147. fragmentShader:
  8148. /* glsl */
  8149. `
  8150. uniform sampler2D tEquirect;
  8151. varying vec3 vWorldDirection;
  8152. #include <common>
  8153. void main() {
  8154. vec3 direction = normalize( vWorldDirection );
  8155. vec2 sampleUV = equirectUv( direction );
  8156. gl_FragColor = texture2D( tEquirect, sampleUV );
  8157. }
  8158. `
  8159. };
  8160. const geometry = new BoxGeometry(5, 5, 5);
  8161. const material = new ShaderMaterial({
  8162. name: 'CubemapFromEquirect',
  8163. uniforms: cloneUniforms(shader.uniforms),
  8164. vertexShader: shader.vertexShader,
  8165. fragmentShader: shader.fragmentShader,
  8166. side: BackSide,
  8167. blending: NoBlending
  8168. });
  8169. material.uniforms.tEquirect.value = texture;
  8170. const mesh = new Mesh(geometry, material);
  8171. const currentMinFilter = texture.minFilter; // Avoid blurred poles
  8172. if (texture.minFilter === LinearMipmapLinearFilter) texture.minFilter = LinearFilter;
  8173. const camera = new CubeCamera(1, 10, this);
  8174. camera.update(renderer, mesh);
  8175. texture.minFilter = currentMinFilter;
  8176. mesh.geometry.dispose();
  8177. mesh.material.dispose();
  8178. return this;
  8179. }
  8180. clear(renderer, color, depth, stencil) {
  8181. const currentRenderTarget = renderer.getRenderTarget();
  8182. for (let i = 0; i < 6; i++) {
  8183. renderer.setRenderTarget(this, i);
  8184. renderer.clear(color, depth, stencil);
  8185. }
  8186. renderer.setRenderTarget(currentRenderTarget);
  8187. }
  8188. }
  8189. const _vector1 = /*@__PURE__*/new Vector3();
  8190. const _vector2 = /*@__PURE__*/new Vector3();
  8191. const _normalMatrix = /*@__PURE__*/new Matrix3();
  8192. class Plane {
  8193. constructor(normal = new Vector3(1, 0, 0), constant = 0) {
  8194. this.isPlane = true; // normal is assumed to be normalized
  8195. this.normal = normal;
  8196. this.constant = constant;
  8197. }
  8198. set(normal, constant) {
  8199. this.normal.copy(normal);
  8200. this.constant = constant;
  8201. return this;
  8202. }
  8203. setComponents(x, y, z, w) {
  8204. this.normal.set(x, y, z);
  8205. this.constant = w;
  8206. return this;
  8207. }
  8208. setFromNormalAndCoplanarPoint(normal, point) {
  8209. this.normal.copy(normal);
  8210. this.constant = -point.dot(this.normal);
  8211. return this;
  8212. }
  8213. setFromCoplanarPoints(a, b, c) {
  8214. const normal = _vector1.subVectors(c, b).cross(_vector2.subVectors(a, b)).normalize(); // Q: should an error be thrown if normal is zero (e.g. degenerate plane)?
  8215. this.setFromNormalAndCoplanarPoint(normal, a);
  8216. return this;
  8217. }
  8218. copy(plane) {
  8219. this.normal.copy(plane.normal);
  8220. this.constant = plane.constant;
  8221. return this;
  8222. }
  8223. normalize() {
  8224. // Note: will lead to a divide by zero if the plane is invalid.
  8225. const inverseNormalLength = 1.0 / this.normal.length();
  8226. this.normal.multiplyScalar(inverseNormalLength);
  8227. this.constant *= inverseNormalLength;
  8228. return this;
  8229. }
  8230. negate() {
  8231. this.constant *= -1;
  8232. this.normal.negate();
  8233. return this;
  8234. }
  8235. distanceToPoint(point) {
  8236. return this.normal.dot(point) + this.constant;
  8237. }
  8238. distanceToSphere(sphere) {
  8239. return this.distanceToPoint(sphere.center) - sphere.radius;
  8240. }
  8241. projectPoint(point, target) {
  8242. return target.copy(this.normal).multiplyScalar(-this.distanceToPoint(point)).add(point);
  8243. }
  8244. intersectLine(line, target) {
  8245. const direction = line.delta(_vector1);
  8246. const denominator = this.normal.dot(direction);
  8247. if (denominator === 0) {
  8248. // line is coplanar, return origin
  8249. if (this.distanceToPoint(line.start) === 0) {
  8250. return target.copy(line.start);
  8251. } // Unsure if this is the correct method to handle this case.
  8252. return null;
  8253. }
  8254. const t = -(line.start.dot(this.normal) + this.constant) / denominator;
  8255. if (t < 0 || t > 1) {
  8256. return null;
  8257. }
  8258. return target.copy(direction).multiplyScalar(t).add(line.start);
  8259. }
  8260. intersectsLine(line) {
  8261. // Note: this tests if a line intersects the plane, not whether it (or its end-points) are coplanar with it.
  8262. const startSign = this.distanceToPoint(line.start);
  8263. const endSign = this.distanceToPoint(line.end);
  8264. return startSign < 0 && endSign > 0 || endSign < 0 && startSign > 0;
  8265. }
  8266. intersectsBox(box) {
  8267. return box.intersectsPlane(this);
  8268. }
  8269. intersectsSphere(sphere) {
  8270. return sphere.intersectsPlane(this);
  8271. }
  8272. coplanarPoint(target) {
  8273. return target.copy(this.normal).multiplyScalar(-this.constant);
  8274. }
  8275. applyMatrix4(matrix, optionalNormalMatrix) {
  8276. const normalMatrix = optionalNormalMatrix || _normalMatrix.getNormalMatrix(matrix);
  8277. const referencePoint = this.coplanarPoint(_vector1).applyMatrix4(matrix);
  8278. const normal = this.normal.applyMatrix3(normalMatrix).normalize();
  8279. this.constant = -referencePoint.dot(normal);
  8280. return this;
  8281. }
  8282. translate(offset) {
  8283. this.constant -= offset.dot(this.normal);
  8284. return this;
  8285. }
  8286. equals(plane) {
  8287. return plane.normal.equals(this.normal) && plane.constant === this.constant;
  8288. }
  8289. clone() {
  8290. return new this.constructor().copy(this);
  8291. }
  8292. }
  8293. const _sphere$2 = /*@__PURE__*/new Sphere();
  8294. const _vector$7 = /*@__PURE__*/new Vector3();
  8295. class Frustum {
  8296. constructor(p0 = new Plane(), p1 = new Plane(), p2 = new Plane(), p3 = new Plane(), p4 = new Plane(), p5 = new Plane()) {
  8297. this.planes = [p0, p1, p2, p3, p4, p5];
  8298. }
  8299. set(p0, p1, p2, p3, p4, p5) {
  8300. const planes = this.planes;
  8301. planes[0].copy(p0);
  8302. planes[1].copy(p1);
  8303. planes[2].copy(p2);
  8304. planes[3].copy(p3);
  8305. planes[4].copy(p4);
  8306. planes[5].copy(p5);
  8307. return this;
  8308. }
  8309. copy(frustum) {
  8310. const planes = this.planes;
  8311. for (let i = 0; i < 6; i++) {
  8312. planes[i].copy(frustum.planes[i]);
  8313. }
  8314. return this;
  8315. }
  8316. setFromProjectionMatrix(m) {
  8317. const planes = this.planes;
  8318. const me = m.elements;
  8319. const me0 = me[0],
  8320. me1 = me[1],
  8321. me2 = me[2],
  8322. me3 = me[3];
  8323. const me4 = me[4],
  8324. me5 = me[5],
  8325. me6 = me[6],
  8326. me7 = me[7];
  8327. const me8 = me[8],
  8328. me9 = me[9],
  8329. me10 = me[10],
  8330. me11 = me[11];
  8331. const me12 = me[12],
  8332. me13 = me[13],
  8333. me14 = me[14],
  8334. me15 = me[15];
  8335. planes[0].setComponents(me3 - me0, me7 - me4, me11 - me8, me15 - me12).normalize();
  8336. planes[1].setComponents(me3 + me0, me7 + me4, me11 + me8, me15 + me12).normalize();
  8337. planes[2].setComponents(me3 + me1, me7 + me5, me11 + me9, me15 + me13).normalize();
  8338. planes[3].setComponents(me3 - me1, me7 - me5, me11 - me9, me15 - me13).normalize();
  8339. planes[4].setComponents(me3 - me2, me7 - me6, me11 - me10, me15 - me14).normalize();
  8340. planes[5].setComponents(me3 + me2, me7 + me6, me11 + me10, me15 + me14).normalize();
  8341. return this;
  8342. }
  8343. intersectsObject(object) {
  8344. const geometry = object.geometry;
  8345. if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
  8346. _sphere$2.copy(geometry.boundingSphere).applyMatrix4(object.matrixWorld);
  8347. return this.intersectsSphere(_sphere$2);
  8348. }
  8349. intersectsSprite(sprite) {
  8350. _sphere$2.center.set(0, 0, 0);
  8351. _sphere$2.radius = 0.7071067811865476;
  8352. _sphere$2.applyMatrix4(sprite.matrixWorld);
  8353. return this.intersectsSphere(_sphere$2);
  8354. }
  8355. intersectsSphere(sphere) {
  8356. const planes = this.planes;
  8357. const center = sphere.center;
  8358. const negRadius = -sphere.radius;
  8359. for (let i = 0; i < 6; i++) {
  8360. const distance = planes[i].distanceToPoint(center);
  8361. if (distance < negRadius) {
  8362. return false;
  8363. }
  8364. }
  8365. return true;
  8366. }
  8367. intersectsBox(box) {
  8368. const planes = this.planes;
  8369. for (let i = 0; i < 6; i++) {
  8370. const plane = planes[i]; // corner at max distance
  8371. _vector$7.x = plane.normal.x > 0 ? box.max.x : box.min.x;
  8372. _vector$7.y = plane.normal.y > 0 ? box.max.y : box.min.y;
  8373. _vector$7.z = plane.normal.z > 0 ? box.max.z : box.min.z;
  8374. if (plane.distanceToPoint(_vector$7) < 0) {
  8375. return false;
  8376. }
  8377. }
  8378. return true;
  8379. }
  8380. containsPoint(point) {
  8381. const planes = this.planes;
  8382. for (let i = 0; i < 6; i++) {
  8383. if (planes[i].distanceToPoint(point) < 0) {
  8384. return false;
  8385. }
  8386. }
  8387. return true;
  8388. }
  8389. clone() {
  8390. return new this.constructor().copy(this);
  8391. }
  8392. }
  8393. function WebGLAnimation() {
  8394. let context = null;
  8395. let isAnimating = false;
  8396. let animationLoop = null;
  8397. let requestId = null;
  8398. function onAnimationFrame(time, frame) {
  8399. animationLoop(time, frame);
  8400. requestId = context.requestAnimationFrame(onAnimationFrame);
  8401. }
  8402. return {
  8403. start: function () {
  8404. if (isAnimating === true) return;
  8405. if (animationLoop === null) return;
  8406. requestId = context.requestAnimationFrame(onAnimationFrame);
  8407. isAnimating = true;
  8408. },
  8409. stop: function () {
  8410. context.cancelAnimationFrame(requestId);
  8411. isAnimating = false;
  8412. },
  8413. setAnimationLoop: function (callback) {
  8414. animationLoop = callback;
  8415. },
  8416. setContext: function (value) {
  8417. context = value;
  8418. }
  8419. };
  8420. }
  8421. function WebGLAttributes(gl, capabilities) {
  8422. const isWebGL2 = capabilities.isWebGL2;
  8423. const buffers = new WeakMap();
  8424. function createBuffer(attribute, bufferType) {
  8425. const array = attribute.array;
  8426. const usage = attribute.usage;
  8427. const buffer = gl.createBuffer();
  8428. gl.bindBuffer(bufferType, buffer);
  8429. gl.bufferData(bufferType, array, usage);
  8430. attribute.onUploadCallback();
  8431. let type;
  8432. if (array instanceof Float32Array) {
  8433. type = gl.FLOAT;
  8434. } else if (array instanceof Uint16Array) {
  8435. if (attribute.isFloat16BufferAttribute) {
  8436. if (isWebGL2) {
  8437. type = gl.HALF_FLOAT;
  8438. } else {
  8439. throw new Error('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.');
  8440. }
  8441. } else {
  8442. type = gl.UNSIGNED_SHORT;
  8443. }
  8444. } else if (array instanceof Int16Array) {
  8445. type = gl.SHORT;
  8446. } else if (array instanceof Uint32Array) {
  8447. type = gl.UNSIGNED_INT;
  8448. } else if (array instanceof Int32Array) {
  8449. type = gl.INT;
  8450. } else if (array instanceof Int8Array) {
  8451. type = gl.BYTE;
  8452. } else if (array instanceof Uint8Array) {
  8453. type = gl.UNSIGNED_BYTE;
  8454. } else if (array instanceof Uint8ClampedArray) {
  8455. type = gl.UNSIGNED_BYTE;
  8456. } else {
  8457. throw new Error('THREE.WebGLAttributes: Unsupported buffer data format: ' + array);
  8458. }
  8459. return {
  8460. buffer: buffer,
  8461. type: type,
  8462. bytesPerElement: array.BYTES_PER_ELEMENT,
  8463. version: attribute.version
  8464. };
  8465. }
  8466. function updateBuffer(buffer, attribute, bufferType) {
  8467. const array = attribute.array;
  8468. const updateRange = attribute.updateRange;
  8469. gl.bindBuffer(bufferType, buffer);
  8470. if (updateRange.count === -1) {
  8471. // Not using update ranges
  8472. gl.bufferSubData(bufferType, 0, array);
  8473. } else {
  8474. if (isWebGL2) {
  8475. gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count);
  8476. } else {
  8477. gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array.subarray(updateRange.offset, updateRange.offset + updateRange.count));
  8478. }
  8479. updateRange.count = -1; // reset range
  8480. }
  8481. } //
  8482. function get(attribute) {
  8483. if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
  8484. return buffers.get(attribute);
  8485. }
  8486. function remove(attribute) {
  8487. if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
  8488. const data = buffers.get(attribute);
  8489. if (data) {
  8490. gl.deleteBuffer(data.buffer);
  8491. buffers.delete(attribute);
  8492. }
  8493. }
  8494. function update(attribute, bufferType) {
  8495. if (attribute.isGLBufferAttribute) {
  8496. const cached = buffers.get(attribute);
  8497. if (!cached || cached.version < attribute.version) {
  8498. buffers.set(attribute, {
  8499. buffer: attribute.buffer,
  8500. type: attribute.type,
  8501. bytesPerElement: attribute.elementSize,
  8502. version: attribute.version
  8503. });
  8504. }
  8505. return;
  8506. }
  8507. if (attribute.isInterleavedBufferAttribute) attribute = attribute.data;
  8508. const data = buffers.get(attribute);
  8509. if (data === undefined) {
  8510. buffers.set(attribute, createBuffer(attribute, bufferType));
  8511. } else if (data.version < attribute.version) {
  8512. updateBuffer(data.buffer, attribute, bufferType);
  8513. data.version = attribute.version;
  8514. }
  8515. }
  8516. return {
  8517. get: get,
  8518. remove: remove,
  8519. update: update
  8520. };
  8521. }
  8522. class PlaneGeometry extends BufferGeometry {
  8523. constructor(width = 1, height = 1, widthSegments = 1, heightSegments = 1) {
  8524. super();
  8525. this.type = 'PlaneGeometry';
  8526. this.parameters = {
  8527. width: width,
  8528. height: height,
  8529. widthSegments: widthSegments,
  8530. heightSegments: heightSegments
  8531. };
  8532. const width_half = width / 2;
  8533. const height_half = height / 2;
  8534. const gridX = Math.floor(widthSegments);
  8535. const gridY = Math.floor(heightSegments);
  8536. const gridX1 = gridX + 1;
  8537. const gridY1 = gridY + 1;
  8538. const segment_width = width / gridX;
  8539. const segment_height = height / gridY; //
  8540. const indices = [];
  8541. const vertices = [];
  8542. const normals = [];
  8543. const uvs = [];
  8544. for (let iy = 0; iy < gridY1; iy++) {
  8545. const y = iy * segment_height - height_half;
  8546. for (let ix = 0; ix < gridX1; ix++) {
  8547. const x = ix * segment_width - width_half;
  8548. vertices.push(x, -y, 0);
  8549. normals.push(0, 0, 1);
  8550. uvs.push(ix / gridX);
  8551. uvs.push(1 - iy / gridY);
  8552. }
  8553. }
  8554. for (let iy = 0; iy < gridY; iy++) {
  8555. for (let ix = 0; ix < gridX; ix++) {
  8556. const a = ix + gridX1 * iy;
  8557. const b = ix + gridX1 * (iy + 1);
  8558. const c = ix + 1 + gridX1 * (iy + 1);
  8559. const d = ix + 1 + gridX1 * iy;
  8560. indices.push(a, b, d);
  8561. indices.push(b, c, d);
  8562. }
  8563. }
  8564. this.setIndex(indices);
  8565. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  8566. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  8567. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  8568. }
  8569. static fromJSON(data) {
  8570. return new PlaneGeometry(data.width, data.height, data.widthSegments, data.heightSegments);
  8571. }
  8572. }
  8573. var alphamap_fragment = "#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, vUv ).g;\n#endif";
  8574. var alphamap_pars_fragment = "#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
  8575. var alphatest_fragment = "#ifdef USE_ALPHATEST\n\tif ( diffuseColor.a < alphaTest ) discard;\n#endif";
  8576. var alphatest_pars_fragment = "#ifdef USE_ALPHATEST\n\tuniform float alphaTest;\n#endif";
  8577. var aomap_fragment = "#ifdef USE_AOMAP\n\tfloat ambientOcclusion = ( texture2D( aoMap, vUv2 ).r - 1.0 ) * aoMapIntensity + 1.0;\n\treflectedLight.indirectDiffuse *= ambientOcclusion;\n\t#if defined( USE_ENVMAP ) && defined( STANDARD )\n\t\tfloat dotNV = saturate( dot( geometry.normal, geometry.viewDir ) );\n\t\treflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness );\n\t#endif\n#endif";
  8578. var aomap_pars_fragment = "#ifdef USE_AOMAP\n\tuniform sampler2D aoMap;\n\tuniform float aoMapIntensity;\n#endif";
  8579. var begin_vertex = "vec3 transformed = vec3( position );";
  8580. var beginnormal_vertex = "vec3 objectNormal = vec3( normal );\n#ifdef USE_TANGENT\n\tvec3 objectTangent = vec3( tangent.xyz );\n#endif";
  8581. var bsdfs = "vec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float roughness ) {\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\tfloat D = D_GGX( alpha, dotNH );\n\treturn F * ( V * D );\n}\n#ifdef USE_IRIDESCENCE\n\tvec3 BRDF_GGX_Iridescence( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 f0, const in float f90, const in float iridescence, const in vec3 iridescenceFresnel, const in float roughness ) {\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = mix( F_Schlick( f0, f90, dotVH ), iridescenceFresnel, iridescence );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\nfloat G_BlinnPhong_Implicit( ) {\n\treturn 0.25;\n}\nfloat D_BlinnPhong( const in float shininess, const in float dotNH ) {\n\treturn RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess );\n}\nvec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( specularColor, 1.0, dotVH );\n\tfloat G = G_BlinnPhong_Implicit( );\n\tfloat D = D_BlinnPhong( shininess, dotNH );\n\treturn F * ( G * D );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif";
  8582. var iridescence_fragment = "#ifdef USE_IRIDESCENCE\n\tconst mat3 XYZ_TO_REC709 = mat3(\n\t\t 3.2404542, -0.9692660, 0.0556434,\n\t\t-1.5371385, 1.8760108, -0.2040259,\n\t\t-0.4985314, 0.0415560, 1.0572252\n\t);\n\tvec3 Fresnel0ToIor( vec3 fresnel0 ) {\n\t\tvec3 sqrtF0 = sqrt( fresnel0 );\n\t\treturn ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 );\n\t}\n\tvec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) );\n\t}\n\tfloat IorToFresnel0( float transmittedIor, float incidentIor ) {\n\t\treturn pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor ));\n\t}\n\tvec3 evalSensitivity( float OPD, vec3 shift ) {\n\t\tfloat phase = 2.0 * PI * OPD * 1.0e-9;\n\t\tvec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 );\n\t\tvec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 );\n\t\tvec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 );\n\t\tvec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var );\n\t\txyz.x += 9.7470e-14 * sqrt( 2.0 * PI * 4.5282e+09 ) * cos( 2.2399e+06 * phase + shift[ 0 ] ) * exp( - 4.5282e+09 * pow2( phase ) );\n\t\txyz /= 1.0685e-7;\n\t\tvec3 rgb = XYZ_TO_REC709 * xyz;\n\t\treturn rgb;\n\t}\n\tvec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) {\n\t\tvec3 I;\n\t\tfloat iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) );\n\t\tfloat sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) );\n\t\tfloat cosTheta2Sq = 1.0 - sinTheta2Sq;\n\t\tif ( cosTheta2Sq < 0.0 ) {\n\t\t\t return vec3( 1.0 );\n\t\t}\n\t\tfloat cosTheta2 = sqrt( cosTheta2Sq );\n\t\tfloat R0 = IorToFresnel0( iridescenceIOR, outsideIOR );\n\t\tfloat R12 = F_Schlick( R0, 1.0, cosTheta1 );\n\t\tfloat R21 = R12;\n\t\tfloat T121 = 1.0 - R12;\n\t\tfloat phi12 = 0.0;\n\t\tif ( iridescenceIOR < outsideIOR ) phi12 = PI;\n\t\tfloat phi21 = PI - phi12;\n\t\tvec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) );\t\tvec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR );\n\t\tvec3 R23 = F_Schlick( R1, 1.0, cosTheta2 );\n\t\tvec3 phi23 = vec3( 0.0 );\n\t\tif ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI;\n\t\tif ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI;\n\t\tif ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI;\n\t\tfloat OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2;\n\t\tvec3 phi = vec3( phi21 ) + phi23;\n\t\tvec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 );\n\t\tvec3 r123 = sqrt( R123 );\n\t\tvec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 );\n\t\tvec3 C0 = R12 + Rs;\n\t\tI = C0;\n\t\tvec3 Cm = Rs - T121;\n\t\tfor ( int m = 1; m <= 2; ++ m ) {\n\t\t\tCm *= r123;\n\t\t\tvec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi );\n\t\t\tI += Cm * Sm;\n\t\t}\n\t\treturn max( I, vec3( 0.0 ) );\n\t}\n#endif";
  8583. var bumpmap_pars_fragment = "#ifdef USE_BUMPMAP\n\tuniform sampler2D bumpMap;\n\tuniform float bumpScale;\n\tvec2 dHdxy_fwd() {\n\t\tvec2 dSTdx = dFdx( vUv );\n\t\tvec2 dSTdy = dFdy( vUv );\n\t\tfloat Hll = bumpScale * texture2D( bumpMap, vUv ).x;\n\t\tfloat dBx = bumpScale * texture2D( bumpMap, vUv + dSTdx ).x - Hll;\n\t\tfloat dBy = bumpScale * texture2D( bumpMap, vUv + dSTdy ).x - Hll;\n\t\treturn vec2( dBx, dBy );\n\t}\n\tvec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {\n\t\tvec3 vSigmaX = dFdx( surf_pos.xyz );\n\t\tvec3 vSigmaY = dFdy( surf_pos.xyz );\n\t\tvec3 vN = surf_norm;\n\t\tvec3 R1 = cross( vSigmaY, vN );\n\t\tvec3 R2 = cross( vN, vSigmaX );\n\t\tfloat fDet = dot( vSigmaX, R1 ) * faceDirection;\n\t\tvec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );\n\t\treturn normalize( abs( fDet ) * surf_norm - vGrad );\n\t}\n#endif";
  8584. var clipping_planes_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvec4 plane;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\tplane = clippingPlanes[ i ];\n\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t}\n\t#pragma unroll_loop_end\n\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\tbool clipped = true;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\tif ( clipped ) discard;\n\t#endif\n#endif";
  8585. var clipping_planes_pars_fragment = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif";
  8586. var clipping_planes_pars_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif";
  8587. var clipping_planes_vertex = "#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif";
  8588. var color_fragment = "#if defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#elif defined( USE_COLOR )\n\tdiffuseColor.rgb *= vColor;\n#endif";
  8589. var color_pars_fragment = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR )\n\tvarying vec3 vColor;\n#endif";
  8590. var color_pars_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvarying vec3 vColor;\n#endif";
  8591. var color_vertex = "#if defined( USE_COLOR_ALPHA )\n\tvColor = vec4( 1.0 );\n#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR )\n\tvColor = vec3( 1.0 );\n#endif\n#ifdef USE_COLOR\n\tvColor *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.xyz *= instanceColor.xyz;\n#endif";
  8592. var common = "#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\nstruct GeometricContext {\n\tvec3 position;\n\tvec3 normal;\n\tvec3 viewDir;\n#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal;\n#endif\n};\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nmat3 transposeMat3( const in mat3 m ) {\n\tmat3 tmp;\n\ttmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x );\n\ttmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y );\n\ttmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z );\n\treturn tmp;\n}\nfloat luminance( const in vec3 rgb ) {\n\tconst vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 );\n\treturn dot( weights, rgb );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}";
  8593. var cube_uv_reflection_fragment = "#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\tvec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define r0 1.0\n\t#define v0 0.339\n\t#define m0 - 2.0\n\t#define r1 0.8\n\t#define v1 0.276\n\t#define m1 - 1.0\n\t#define r4 0.4\n\t#define v4 0.046\n\t#define m4 2.0\n\t#define r5 0.305\n\t#define v5 0.016\n\t#define m5 3.0\n\t#define r6 0.21\n\t#define v6 0.0038\n\t#define m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= r1 ) {\n\t\t\tmip = ( r0 - roughness ) * ( m1 - m0 ) / ( r0 - r1 ) + m0;\n\t\t} else if ( roughness >= r4 ) {\n\t\t\tmip = ( r1 - roughness ) * ( m4 - m1 ) / ( r1 - r4 ) + m1;\n\t\t} else if ( roughness >= r5 ) {\n\t\t\tmip = ( r4 - roughness ) * ( m5 - m4 ) / ( r4 - r5 ) + m4;\n\t\t} else if ( roughness >= r6 ) {\n\t\t\tmip = ( r5 - roughness ) * ( m6 - m5 ) / ( r5 - r6 ) + m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif";
  8594. var defaultnormal_vertex = "vec3 transformedNormal = objectNormal;\n#ifdef USE_INSTANCING\n\tmat3 m = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( m[ 0 ], m[ 0 ] ), dot( m[ 1 ], m[ 1 ] ), dot( m[ 2 ], m[ 2 ] ) );\n\ttransformedNormal = m * transformedNormal;\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = ( modelViewMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif";
  8595. var displacementmap_pars_vertex = "#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif";
  8596. var displacementmap_vertex = "#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vUv ).x * displacementScale + displacementBias );\n#endif";
  8597. var emissivemap_fragment = "#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vUv );\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif";
  8598. var emissivemap_pars_fragment = "#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif";
  8599. var encodings_fragment = "gl_FragColor = linearToOutputTexel( gl_FragColor );";
  8600. var encodings_pars_fragment = "vec4 LinearToLinear( in vec4 value ) {\n\treturn value;\n}\nvec4 LinearTosRGB( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}";
  8601. var envmap_fragment = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 envColor = textureCubeUV( envMap, reflectVec, 0.0 );\n\t#else\n\t\tvec4 envColor = vec4( 0.0 );\n\t#endif\n\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t#endif\n#endif";
  8602. var envmap_common_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n\t\n#endif";
  8603. var envmap_pars_fragment = "#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif";
  8604. var envmap_pars_vertex = "#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) ||defined( PHONG )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif";
  8605. var envmap_vertex = "#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif";
  8606. var fog_vertex = "#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif";
  8607. var fog_pars_vertex = "#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif";
  8608. var fog_fragment = "#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif";
  8609. var fog_pars_fragment = "#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif";
  8610. var gradientmap_pars_fragment = "#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\treturn ( coord.x < 0.7 ) ? vec3( 0.7 ) : vec3( 1.0 );\n\t#endif\n}";
  8611. var lightmap_fragment = "#ifdef USE_LIGHTMAP\n\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\treflectedLight.indirectDiffuse += lightMapIrradiance;\n#endif";
  8612. var lightmap_pars_fragment = "#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif";
  8613. var lights_lambert_vertex = "vec3 diffuse = vec3( 1.0 );\nGeometricContext geometry;\ngeometry.position = mvPosition.xyz;\ngeometry.normal = normalize( transformedNormal );\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz );\nGeometricContext backGeometry;\nbackGeometry.position = geometry.position;\nbackGeometry.normal = -geometry.normal;\nbackGeometry.viewDir = geometry.viewDir;\nvLightFront = vec3( 0.0 );\nvIndirectFront = vec3( 0.0 );\n#ifdef DOUBLE_SIDED\n\tvLightBack = vec3( 0.0 );\n\tvIndirectBack = vec3( 0.0 );\n#endif\nIncidentLight directLight;\nfloat dotNL;\nvec3 directLightColor_Diffuse;\nvIndirectFront += getAmbientLightIrradiance( ambientLightColor );\nvIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal );\n#ifdef DOUBLE_SIDED\n\tvIndirectBack += getAmbientLightIrradiance( ambientLightColor );\n\tvIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal );\n#endif\n#if NUM_POINT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tgetPointLightInfo( pointLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tgetSpotLightInfo( spotLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_DIR_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tgetDirectionalLightInfo( directionalLights[ i ], geometry, directLight );\n\t\tdotNL = dot( geometry.normal, directLight.direction );\n\t\tdirectLightColor_Diffuse = directLight.color;\n\t\tvLightFront += saturate( dotNL ) * directLightColor_Diffuse;\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvLightBack += saturate( - dotNL ) * directLightColor_Diffuse;\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\tvIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\tvIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal );\n\t\t#endif\n\t}\n\t#pragma unroll_loop_end\n#endif";
  8614. var lights_pars_begin = "uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\nuniform vec3 lightProbe[ 9 ];\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\t#if defined ( PHYSICALLY_CORRECT_LIGHTS )\n\t\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\t\tif ( cutoffDistance > 0.0 ) {\n\t\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t\t}\n\t\treturn distanceFalloff;\n\t#else\n\t\tif ( cutoffDistance > 0.0 && decayExponent > 0.0 ) {\n\t\t\treturn pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent );\n\t\t}\n\t\treturn 1.0;\n\t#endif\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in GeometricContext geometry, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif";
  8615. var envmap_physical_pars_fragment = "#if defined( USE_ENVMAP )\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#if defined( ENVMAP_TYPE_CUBE_UV )\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, roughness * roughness) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n#endif";
  8616. var lights_toon_fragment = "ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;";
  8617. var lights_toon_pars_fragment = "varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometry.normal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in GeometricContext geometry, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon\n#define Material_LightProbeLOD( material )\t(0)";
  8618. var lights_phong_fragment = "BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;";
  8619. var lights_phong_pars_fragment = "varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in GeometricContext geometry, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong\n#define Material_LightProbeLOD( material )\t(0)";
  8620. var lights_physical_fragment = "PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nvec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\t#ifdef SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULARINTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vUv ).a;\n\t\t#endif\n\t\t#ifdef USE_SPECULARCOLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vUv ).rgb;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = mix( min( pow2( ( ior - 1.0 ) / ( ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 );\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vUv ).a;\n\t#endif\n#endif";
  8621. var lights_physical_pars_fragment = "struct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tfloat roughness;\n\tvec3 specularColor;\n\tfloat specularF90;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n};\nvec3 clearcoatSpecular = vec3( 0.0 );\nvec3 sheenSpecular = vec3( 0.0 );\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95;\n\tfloat b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72;\n\tfloat DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) );\n\treturn saturate( DG * RECIPROCAL_PI );\n}\nvec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tconst vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n\tconst vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n\tvec4 r = roughness * c0 + c1;\n\tfloat a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n\tvec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw;\n\treturn fab;\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tvec2 fab = DFGApprox( normal, viewDir, roughness );\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometry.normal;\n\t\tvec3 viewDir = geometry.viewDir;\n\t\tvec3 position = geometry.position;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometry.normal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometry.clearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecular += ccIrradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.clearcoatNormal, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * BRDF_Sheen( directLight.direction, geometry.viewDir, geometry.normal, material.sheenColor, material.sheenRoughness );\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX_Iridescence( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness );\n\t#else\n\t\treflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometry.viewDir, geometry.normal, material.specularColor, material.specularF90, material.roughness );\n\t#endif\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in GeometricContext geometry, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecular += clearcoatRadiance * EnvironmentBRDF( geometry.clearcoatNormal, geometry.viewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecular += irradiance * material.sheenColor * IBLSheenBRDF( geometry.normal, geometry.viewDir, material.sheenRoughness );\n\t#endif\n\tvec3 singleScattering = vec3( 0.0 );\n\tvec3 multiScattering = vec3( 0.0 );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering );\n\t#else\n\t\tcomputeMultiscattering( geometry.normal, geometry.viewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering );\n\t#endif\n\tvec3 totalScattering = singleScattering + multiScattering;\n\tvec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) );\n\treflectedLight.indirectSpecular += radiance * singleScattering;\n\treflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance;\n\treflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}";
  8622. var lights_fragment_begin = "\nGeometricContext geometry;\ngeometry.position = - vViewPosition;\ngeometry.normal = normal;\ngeometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\n#ifdef USE_CLEARCOAT\n\tgeometry.clearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometry.viewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, geometry, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\tirradiance += getLightProbeIrradiance( lightProbe, geometry.normal );\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif";
  8623. var lights_fragment_maps = "#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\tiblIrradiance += getIBLIrradiance( geometry.normal );\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\tradiance += getIBLRadiance( geometry.viewDir, geometry.normal, material.roughness );\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometry.viewDir, geometry.clearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif";
  8624. var lights_fragment_end = "#if defined( RE_IndirectDiffuse )\n\tRE_IndirectDiffuse( irradiance, geometry, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometry, material, reflectedLight );\n#endif";
  8625. var logdepthbuf_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tgl_FragDepthEXT = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif";
  8626. var logdepthbuf_pars_fragment = "#if defined( USE_LOGDEPTHBUF ) && defined( USE_LOGDEPTHBUF_EXT )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif";
  8627. var logdepthbuf_pars_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvarying float vFragDepth;\n\t\tvarying float vIsPerspective;\n\t#else\n\t\tuniform float logDepthBufFC;\n\t#endif\n#endif";
  8628. var logdepthbuf_vertex = "#ifdef USE_LOGDEPTHBUF\n\t#ifdef USE_LOGDEPTHBUF_EXT\n\t\tvFragDepth = 1.0 + gl_Position.w;\n\t\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n\t#else\n\t\tif ( isPerspectiveMatrix( projectionMatrix ) ) {\n\t\t\tgl_Position.z = log2( max( EPSILON, gl_Position.w + 1.0 ) ) * logDepthBufFC - 1.0;\n\t\t\tgl_Position.z *= gl_Position.w;\n\t\t}\n\t#endif\n#endif";
  8629. var map_fragment = "#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif";
  8630. var map_pars_fragment = "#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif";
  8631. var map_particle_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif";
  8632. var map_particle_pars_fragment = "#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\tuniform mat3 uvTransform;\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif";
  8633. var metalnessmap_fragment = "float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif";
  8634. var metalnessmap_pars_fragment = "#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif";
  8635. var morphcolor_vertex = "#if defined( USE_MORPHCOLORS ) && defined( MORPHTARGETS_TEXTURE )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif";
  8636. var morphnormal_vertex = "#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\tobjectNormal += morphNormal0 * morphTargetInfluences[ 0 ];\n\t\tobjectNormal += morphNormal1 * morphTargetInfluences[ 1 ];\n\t\tobjectNormal += morphNormal2 * morphTargetInfluences[ 2 ];\n\t\tobjectNormal += morphNormal3 * morphTargetInfluences[ 3 ];\n\t#endif\n#endif";
  8637. var morphtarget_pars_vertex = "#ifdef USE_MORPHTARGETS\n\tuniform float morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t\tuniform sampler2DArray morphTargetsTexture;\n\t\tuniform ivec2 morphTargetsTextureSize;\n\t\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t\t}\n\t#else\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\tuniform float morphTargetInfluences[ 8 ];\n\t\t#else\n\t\t\tuniform float morphTargetInfluences[ 4 ];\n\t\t#endif\n\t#endif\n#endif";
  8638. var morphtarget_vertex = "#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\t#ifdef MORPHTARGETS_TEXTURE\n\t\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t\t}\n\t#else\n\t\ttransformed += morphTarget0 * morphTargetInfluences[ 0 ];\n\t\ttransformed += morphTarget1 * morphTargetInfluences[ 1 ];\n\t\ttransformed += morphTarget2 * morphTargetInfluences[ 2 ];\n\t\ttransformed += morphTarget3 * morphTargetInfluences[ 3 ];\n\t\t#ifndef USE_MORPHNORMALS\n\t\t\ttransformed += morphTarget4 * morphTargetInfluences[ 4 ];\n\t\t\ttransformed += morphTarget5 * morphTargetInfluences[ 5 ];\n\t\t\ttransformed += morphTarget6 * morphTargetInfluences[ 6 ];\n\t\t\ttransformed += morphTarget7 * morphTargetInfluences[ 7 ];\n\t\t#endif\n\t#endif\n#endif";
  8639. var normal_fragment_begin = "float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = vec3( dFdx( vViewPosition.x ), dFdx( vViewPosition.y ), dFdx( vViewPosition.z ) );\n\tvec3 fdy = vec3( dFdy( vViewPosition.x ), dFdy( vViewPosition.y ), dFdy( vViewPosition.z ) );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\t#ifdef USE_TANGENT\n\t\tvec3 tangent = normalize( vTangent );\n\t\tvec3 bitangent = normalize( vBitangent );\n\t\t#ifdef DOUBLE_SIDED\n\t\t\ttangent = tangent * faceDirection;\n\t\t\tbitangent = bitangent * faceDirection;\n\t\t#endif\n\t\t#if defined( TANGENTSPACE_NORMALMAP ) || defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tmat3 vTBN = mat3( tangent, bitangent, normal );\n\t\t#endif\n\t#endif\n#endif\nvec3 geometryNormal = normal;";
  8640. var normal_fragment_maps = "#ifdef OBJECTSPACE_NORMALMAP\n\tnormal = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( TANGENTSPACE_NORMALMAP )\n\tvec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\t#ifdef USE_TANGENT\n\t\tnormal = normalize( vTBN * mapN );\n\t#else\n\t\tnormal = perturbNormal2Arb( - vViewPosition, normal, mapN, faceDirection );\n\t#endif\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif";
  8641. var normal_pars_fragment = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif";
  8642. var normal_pars_vertex = "#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif";
  8643. var normal_vertex = "#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif";
  8644. var normalmap_pars_fragment = "#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef OBJECTSPACE_NORMALMAP\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( TANGENTSPACE_NORMALMAP ) || defined ( USE_CLEARCOAT_NORMALMAP ) )\n\tvec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm, vec3 mapN, float faceDirection ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( vUv.st );\n\t\tvec2 st1 = dFdy( vUv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : faceDirection * inversesqrt( det );\n\t\treturn normalize( T * ( mapN.x * scale ) + B * ( mapN.y * scale ) + N * mapN.z );\n\t}\n#endif";
  8645. var clearcoat_normal_fragment_begin = "#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = geometryNormal;\n#endif";
  8646. var clearcoat_normal_fragment_maps = "#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\t#ifdef USE_TANGENT\n\t\tclearcoatNormal = normalize( vTBN * clearcoatMapN );\n\t#else\n\t\tclearcoatNormal = perturbNormal2Arb( - vViewPosition, clearcoatNormal, clearcoatMapN, faceDirection );\n\t#endif\n#endif";
  8647. var clearcoat_pars_fragment = "#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif";
  8648. var iridescence_pars_fragment = "#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif";
  8649. var output_fragment = "#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= transmissionAlpha + 0.1;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );";
  8650. var packing = "vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;\nconst vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );\nconst vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. );\nconst float ShiftRight8 = 1. / 256.;\nvec4 packDepthToRGBA( const in float v ) {\n\tvec4 r = vec4( fract( v * PackFactors ), v );\n\tr.yzw -= r.xyz * ShiftRight8;\treturn r * PackUpscale;\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors );\n}\nvec4 pack2HalfToRGBA( vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) {\n\treturn linearClipZ * ( near - far ) - near;\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) {\n\treturn ( near * far ) / ( ( far - near ) * invClipZ - far );\n}";
  8651. var premultiplied_alpha_fragment = "#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif";
  8652. var project_vertex = "vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;";
  8653. var dithering_fragment = "#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif";
  8654. var dithering_pars_fragment = "#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif";
  8655. var roughnessmap_fragment = "float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vUv );\n\troughnessFactor *= texelRoughness.g;\n#endif";
  8656. var roughnessmap_pars_fragment = "#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif";
  8657. var shadowmap_pars_fragment = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\tfloat texture2DCompare( sampler2D depths, vec2 uv, float compare ) {\n\t\treturn step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) );\n\t}\n\tvec2 texture2DDistribution( sampler2D shadow, vec2 uv ) {\n\t\treturn unpackRGBATo2Half( texture2D( shadow, uv ) );\n\t}\n\tfloat VSMShadow (sampler2D shadow, vec2 uv, float compare ){\n\t\tfloat occlusion = 1.0;\n\t\tvec2 distribution = texture2DDistribution( shadow, uv );\n\t\tfloat hard_shadow = step( compare , distribution.x );\n\t\tif (hard_shadow != 1.0 ) {\n\t\t\tfloat distance = compare - distribution.x ;\n\t\t\tfloat variance = max( 0.00000, distribution.y * distribution.y );\n\t\t\tfloat softness_probability = variance / (variance + distance * distance );\t\t\tsoftness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 );\t\t\tocclusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 );\n\t\t}\n\t\treturn occlusion;\n\t}\n\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\tfloat shadow = 1.0;\n\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\tshadowCoord.z += shadowBias;\n\t\tbvec4 inFrustumVec = bvec4 ( shadowCoord.x >= 0.0, shadowCoord.x <= 1.0, shadowCoord.y >= 0.0, shadowCoord.y <= 1.0 );\n\t\tbool inFrustum = all( inFrustumVec );\n\t\tbvec2 frustumTestVec = bvec2( inFrustum, shadowCoord.z <= 1.0 );\n\t\tbool frustumTest = all( frustumTestVec );\n\t\tif ( frustumTest ) {\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx0 = - texelSize.x * shadowRadius;\n\t\t\tfloat dy0 = - texelSize.y * shadowRadius;\n\t\t\tfloat dx1 = + texelSize.x * shadowRadius;\n\t\t\tfloat dy1 = + texelSize.y * shadowRadius;\n\t\t\tfloat dx2 = dx0 / 2.0;\n\t\t\tfloat dy2 = dy0 / 2.0;\n\t\t\tfloat dx3 = dx1 / 2.0;\n\t\t\tfloat dy3 = dy1 / 2.0;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z )\n\t\t\t) * ( 1.0 / 17.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_PCF_SOFT )\n\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\tfloat dx = texelSize.x;\n\t\t\tfloat dy = texelSize.y;\n\t\t\tvec2 uv = shadowCoord.xy;\n\t\t\tvec2 f = fract( uv * shadowMapSize + 0.5 );\n\t\t\tuv -= f * texelSize;\n\t\t\tshadow = (\n\t\t\t\ttexture2DCompare( shadowMap, uv, shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) +\n\t\t\t\ttexture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ),\n\t\t\t\t\t f.x ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t f.y ) +\n\t\t\t\tmix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), \n\t\t\t\t\t\t texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ),\n\t\t\t\t\t\t f.x ),\n\t\t\t\t\t f.y )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\t\tshadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#else\n\t\t\tshadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z );\n\t\t#endif\n\t\t}\n\t\treturn shadow;\n\t}\n\tvec2 cubeToUV( vec3 v, float texelSizeY ) {\n\t\tvec3 absV = abs( v );\n\t\tfloat scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) );\n\t\tabsV *= scaleToCube;\n\t\tv *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );\n\t\tvec2 planar = v.xy;\n\t\tfloat almostATexel = 1.5 * texelSizeY;\n\t\tfloat almostOne = 1.0 - almostATexel;\n\t\tif ( absV.z >= almostOne ) {\n\t\t\tif ( v.z > 0.0 )\n\t\t\t\tplanar.x = 4.0 - v.x;\n\t\t} else if ( absV.x >= almostOne ) {\n\t\t\tfloat signX = sign( v.x );\n\t\t\tplanar.x = v.z * signX + 2.0 * signX;\n\t\t} else if ( absV.y >= almostOne ) {\n\t\t\tfloat signY = sign( v.y );\n\t\t\tplanar.x = v.x + 2.0 * signY + 2.0;\n\t\t\tplanar.y = v.z * signY - 2.0;\n\t\t}\n\t\treturn vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 );\n\t}\n\tfloat getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tvec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) );\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tfloat dp = ( length( lightToPosition ) - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear );\t\tdp += shadowBias;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t#if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM )\n\t\t\tvec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y;\n\t\t\treturn (\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) +\n\t\t\t\ttexture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp )\n\t\t\t) * ( 1.0 / 9.0 );\n\t\t#else\n\t\t\treturn texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp );\n\t\t#endif\n\t}\n#endif";
  8658. var shadowmap_pars_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 spotShadowMatrix[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vSpotShadowCoord[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif";
  8659. var shadowmap_vertex = "#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0 || NUM_SPOT_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0\n\t\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\tvec4 shadowWorldPosition;\n\t#endif\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvSpotShadowCoord[ i ] = spotShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n#endif";
  8660. var shadowmask_pars_fragment = "float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}";
  8661. var skinbase_vertex = "#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif";
  8662. var skinning_pars_vertex = "#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tuniform int boneTextureSize;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tfloat j = i * 4.0;\n\t\tfloat x = mod( j, float( boneTextureSize ) );\n\t\tfloat y = floor( j / float( boneTextureSize ) );\n\t\tfloat dx = 1.0 / float( boneTextureSize );\n\t\tfloat dy = 1.0 / float( boneTextureSize );\n\t\ty = dy * ( y + 0.5 );\n\t\tvec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );\n\t\tvec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );\n\t\tvec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );\n\t\tvec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );\n\t\tmat4 bone = mat4( v1, v2, v3, v4 );\n\t\treturn bone;\n\t}\n#endif";
  8663. var skinning_vertex = "#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif";
  8664. var skinnormal_vertex = "#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif";
  8665. var specularmap_fragment = "float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif";
  8666. var specularmap_pars_fragment = "#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif";
  8667. var tonemapping_fragment = "#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif";
  8668. var tonemapping_pars_fragment = "#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn toneMappingExposure * color;\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 OptimizedCineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }";
  8669. var transmission_fragment = "#ifdef USE_TRANSMISSION\n\tfloat transmissionAlpha = 1.0;\n\tfloat transmissionFactor = transmission;\n\tfloat thicknessFactor = thickness;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\ttransmissionFactor *= texture2D( transmissionMap, vUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tthicknessFactor *= texture2D( thicknessMap, vUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmission = getIBLVolumeRefraction(\n\t\tn, v, roughnessFactor, material.diffuseColor, material.specularColor, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, ior, thicknessFactor,\n\t\tattenuationColor, attenuationDistance );\n\ttotalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );\n\ttransmissionAlpha = mix( transmissionAlpha, transmission.a, transmissionFactor );\n#endif";
  8670. var transmission_pars_fragment = "#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat framebufferLod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\t#ifdef texture2DLodEXT\n\t\t\treturn texture2DLodEXT( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#else\n\t\t\treturn texture2D( transmissionSamplerMap, fragCoord.xy, framebufferLod );\n\t\t#endif\n\t}\n\tvec3 applyVolumeAttenuation( const in vec3 radiance, const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( attenuationDistance == 0.0 ) {\n\t\t\treturn radiance;\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance * radiance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\trefractionCoords += 1.0;\n\t\trefractionCoords /= 2.0;\n\t\tvec4 transmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\tvec3 attenuatedColor = applyVolumeAttenuation( transmittedLight.rgb, length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor * diffuseColor, transmittedLight.a );\n\t}\n#endif";
  8671. var uv_pars_fragment = "#if ( defined( USE_UV ) && ! defined( UVS_VERTEX_ONLY ) )\n\tvarying vec2 vUv;\n#endif";
  8672. var uv_pars_vertex = "#ifdef USE_UV\n\t#ifdef UVS_VERTEX_ONLY\n\t\tvec2 vUv;\n\t#else\n\t\tvarying vec2 vUv;\n\t#endif\n\tuniform mat3 uvTransform;\n#endif";
  8673. var uv_vertex = "#ifdef USE_UV\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n#endif";
  8674. var uv2_pars_fragment = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvarying vec2 vUv2;\n#endif";
  8675. var uv2_pars_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tattribute vec2 uv2;\n\tvarying vec2 vUv2;\n\tuniform mat3 uv2Transform;\n#endif";
  8676. var uv2_vertex = "#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP )\n\tvUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy;\n#endif";
  8677. var worldpos_vertex = "#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION )\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif";
  8678. const vertex$g = "varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}";
  8679. const fragment$g = "uniform sampler2D t2D;\nvarying vec2 vUv;\nvoid main() {\n\tgl_FragColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tgl_FragColor = vec4( mix( pow( gl_FragColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), gl_FragColor.rgb * 0.0773993808, vec3( lessThanEqual( gl_FragColor.rgb, vec3( 0.04045 ) ) ) ), gl_FragColor.w );\n\t#endif\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
  8680. const vertex$f = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n\tgl_Position.z = gl_Position.w;\n}";
  8681. const fragment$f = "#include <envmap_common_pars_fragment>\nuniform float opacity;\nvarying vec3 vWorldDirection;\n#include <cube_uv_reflection_fragment>\nvoid main() {\n\tvec3 vReflect = vWorldDirection;\n\t#include <envmap_fragment>\n\tgl_FragColor = envColor;\n\tgl_FragColor.a *= opacity;\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
  8682. const vertex$e = "#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvHighPrecisionZW = gl_Position.zw;\n}";
  8683. const fragment$e = "#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <logdepthbuf_fragment>\n\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#endif\n}";
  8684. const vertex$d = "#define DISTANCE\nvarying vec3 vWorldPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <skinbase_vertex>\n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <clipping_planes_vertex>\n\tvWorldPosition = worldPosition.xyz;\n}";
  8685. const fragment$d = "#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include <common>\n#include <packing>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main () {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = packDepthToRGBA( dist );\n}";
  8686. const vertex$c = "varying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include <begin_vertex>\n\t#include <project_vertex>\n}";
  8687. const fragment$c = "uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include <common>\nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n}";
  8688. const vertex$b = "uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
  8689. const fragment$b = "uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include <common>\n#include <color_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <color_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
  8690. const vertex$a = "#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include <beginnormal_vertex>\n\t\t#include <morphnormal_vertex>\n\t\t#include <skinbase_vertex>\n\t\t#include <skinnormal_vertex>\n\t\t#include <defaultnormal_vertex>\n\t#endif\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <fog_vertex>\n}";
  8691. const fragment$a = "uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vUv2 );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include <aomap_fragment>\n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
  8692. const vertex$9 = "#define LAMBERT\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <envmap_pars_vertex>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <lights_lambert_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
  8693. const fragment$9 = "uniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\nvarying vec3 vLightFront;\nvarying vec3 vIndirectFront;\n#ifdef DOUBLE_SIDED\n\tvarying vec3 vLightBack;\n\tvarying vec3 vIndirectBack;\n#endif\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <fog_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <emissivemap_fragment>\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack;\n\t#else\n\t\treflectedLight.indirectDiffuse += vIndirectFront;\n\t#endif\n\t#include <lightmap_fragment>\n\treflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb );\n\t#ifdef DOUBLE_SIDED\n\t\treflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack;\n\t#else\n\t\treflectedLight.directDiffuse = vLightFront;\n\t#endif\n\treflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask();\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
  8694. const vertex$8 = "#define MATCAP\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <color_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n\tvViewPosition = - mvPosition.xyz;\n}";
  8695. const fragment$8 = "#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include <common>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
  8696. const vertex$7 = "#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}";
  8697. const fragment$7 = "#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( TANGENTSPACE_NORMALMAP )\n\tvarying vec3 vViewPosition;\n#endif\n#include <packing>\n#include <uv_pars_fragment>\n#include <normal_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\t#include <logdepthbuf_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\tgl_FragColor = vec4( packNormalToRGB( normal ), opacity );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}";
  8698. const vertex$6 = "#define PHONG\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <envmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <envmap_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
  8699. const fragment$6 = "#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_pars_fragment>\n#include <cube_uv_reflection_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_phong_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <specularmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <specularmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_phong_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include <envmap_fragment>\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
  8700. const vertex$5 = "#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}";
  8701. const fragment$5 = "#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULARINTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n\t#ifdef USE_SPECULARCOLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEENCOLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEENROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <bsdfs>\n#include <iridescence_fragment>\n#include <cube_uv_reflection_fragment>\n#include <envmap_common_pars_fragment>\n#include <envmap_physical_pars_fragment>\n#include <fog_pars_fragment>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_physical_pars_fragment>\n#include <transmission_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <clearcoat_pars_fragment>\n#include <iridescence_pars_fragment>\n#include <roughnessmap_pars_fragment>\n#include <metalnessmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <roughnessmap_fragment>\n\t#include <metalnessmap_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <clearcoat_normal_fragment_begin>\n\t#include <clearcoat_normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_physical_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include <transmission_fragment>\n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor );\n\t\toutgoingLight = outgoingLight * sheenEnergyComp + sheenSpecular;\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometry.clearcoatNormal, geometry.viewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + clearcoatSpecular * material.clearcoat;\n\t#endif\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
  8702. const vertex$4 = "#define TOON\nvarying vec3 vViewPosition;\n#include <common>\n#include <uv_pars_vertex>\n#include <uv2_pars_vertex>\n#include <displacementmap_pars_vertex>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <normal_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\t#include <uv2_vertex>\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <normal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <displacementmap_vertex>\n\t#include <project_vertex>\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\tvViewPosition = - mvPosition.xyz;\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
  8703. const fragment$4 = "#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <dithering_pars_fragment>\n#include <color_pars_fragment>\n#include <uv_pars_fragment>\n#include <uv2_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <aomap_pars_fragment>\n#include <lightmap_pars_fragment>\n#include <emissivemap_pars_fragment>\n#include <gradientmap_pars_fragment>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <normal_pars_fragment>\n#include <lights_toon_pars_fragment>\n#include <shadowmap_pars_fragment>\n#include <bumpmap_pars_fragment>\n#include <normalmap_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <color_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\t#include <normal_fragment_begin>\n\t#include <normal_fragment_maps>\n\t#include <emissivemap_fragment>\n\t#include <lights_toon_fragment>\n\t#include <lights_fragment_begin>\n\t#include <lights_fragment_maps>\n\t#include <lights_fragment_end>\n\t#include <aomap_fragment>\n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n\t#include <dithering_fragment>\n}";
  8704. const vertex$3 = "uniform float size;\nuniform float scale;\n#include <common>\n#include <color_pars_vertex>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <color_vertex>\n\t#include <morphcolor_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <project_vertex>\n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <worldpos_vertex>\n\t#include <fog_vertex>\n}";
  8705. const fragment$3 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_particle_fragment>\n\t#include <color_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n\t#include <premultiplied_alpha_fragment>\n}";
  8706. const vertex$2 = "#include <common>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <skinning_pars_vertex>\n#include <shadowmap_pars_vertex>\nvoid main() {\n\t#include <beginnormal_vertex>\n\t#include <morphnormal_vertex>\n\t#include <skinbase_vertex>\n\t#include <skinnormal_vertex>\n\t#include <defaultnormal_vertex>\n\t#include <begin_vertex>\n\t#include <morphtarget_vertex>\n\t#include <skinning_vertex>\n\t#include <project_vertex>\n\t#include <worldpos_vertex>\n\t#include <shadowmap_vertex>\n\t#include <fog_vertex>\n}";
  8707. const fragment$2 = "uniform vec3 color;\nuniform float opacity;\n#include <common>\n#include <packing>\n#include <fog_pars_fragment>\n#include <bsdfs>\n#include <lights_pars_begin>\n#include <shadowmap_pars_fragment>\n#include <shadowmask_pars_fragment>\nvoid main() {\n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
  8708. const vertex$1 = "uniform float rotation;\nuniform vec2 center;\n#include <common>\n#include <uv_pars_vertex>\n#include <fog_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvoid main() {\n\t#include <uv_vertex>\n\tvec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );\n\tvec2 scale;\n\tscale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );\n\tscale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include <logdepthbuf_vertex>\n\t#include <clipping_planes_vertex>\n\t#include <fog_vertex>\n}";
  8709. const fragment$1 = "uniform vec3 diffuse;\nuniform float opacity;\n#include <common>\n#include <uv_pars_fragment>\n#include <map_pars_fragment>\n#include <alphamap_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\nvoid main() {\n\t#include <clipping_planes_fragment>\n\tvec3 outgoingLight = vec3( 0.0 );\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include <logdepthbuf_fragment>\n\t#include <map_fragment>\n\t#include <alphamap_fragment>\n\t#include <alphatest_fragment>\n\toutgoingLight = diffuseColor.rgb;\n\t#include <output_fragment>\n\t#include <tonemapping_fragment>\n\t#include <encodings_fragment>\n\t#include <fog_fragment>\n}";
  8710. const ShaderChunk = {
  8711. alphamap_fragment: alphamap_fragment,
  8712. alphamap_pars_fragment: alphamap_pars_fragment,
  8713. alphatest_fragment: alphatest_fragment,
  8714. alphatest_pars_fragment: alphatest_pars_fragment,
  8715. aomap_fragment: aomap_fragment,
  8716. aomap_pars_fragment: aomap_pars_fragment,
  8717. begin_vertex: begin_vertex,
  8718. beginnormal_vertex: beginnormal_vertex,
  8719. bsdfs: bsdfs,
  8720. iridescence_fragment: iridescence_fragment,
  8721. bumpmap_pars_fragment: bumpmap_pars_fragment,
  8722. clipping_planes_fragment: clipping_planes_fragment,
  8723. clipping_planes_pars_fragment: clipping_planes_pars_fragment,
  8724. clipping_planes_pars_vertex: clipping_planes_pars_vertex,
  8725. clipping_planes_vertex: clipping_planes_vertex,
  8726. color_fragment: color_fragment,
  8727. color_pars_fragment: color_pars_fragment,
  8728. color_pars_vertex: color_pars_vertex,
  8729. color_vertex: color_vertex,
  8730. common: common,
  8731. cube_uv_reflection_fragment: cube_uv_reflection_fragment,
  8732. defaultnormal_vertex: defaultnormal_vertex,
  8733. displacementmap_pars_vertex: displacementmap_pars_vertex,
  8734. displacementmap_vertex: displacementmap_vertex,
  8735. emissivemap_fragment: emissivemap_fragment,
  8736. emissivemap_pars_fragment: emissivemap_pars_fragment,
  8737. encodings_fragment: encodings_fragment,
  8738. encodings_pars_fragment: encodings_pars_fragment,
  8739. envmap_fragment: envmap_fragment,
  8740. envmap_common_pars_fragment: envmap_common_pars_fragment,
  8741. envmap_pars_fragment: envmap_pars_fragment,
  8742. envmap_pars_vertex: envmap_pars_vertex,
  8743. envmap_physical_pars_fragment: envmap_physical_pars_fragment,
  8744. envmap_vertex: envmap_vertex,
  8745. fog_vertex: fog_vertex,
  8746. fog_pars_vertex: fog_pars_vertex,
  8747. fog_fragment: fog_fragment,
  8748. fog_pars_fragment: fog_pars_fragment,
  8749. gradientmap_pars_fragment: gradientmap_pars_fragment,
  8750. lightmap_fragment: lightmap_fragment,
  8751. lightmap_pars_fragment: lightmap_pars_fragment,
  8752. lights_lambert_vertex: lights_lambert_vertex,
  8753. lights_pars_begin: lights_pars_begin,
  8754. lights_toon_fragment: lights_toon_fragment,
  8755. lights_toon_pars_fragment: lights_toon_pars_fragment,
  8756. lights_phong_fragment: lights_phong_fragment,
  8757. lights_phong_pars_fragment: lights_phong_pars_fragment,
  8758. lights_physical_fragment: lights_physical_fragment,
  8759. lights_physical_pars_fragment: lights_physical_pars_fragment,
  8760. lights_fragment_begin: lights_fragment_begin,
  8761. lights_fragment_maps: lights_fragment_maps,
  8762. lights_fragment_end: lights_fragment_end,
  8763. logdepthbuf_fragment: logdepthbuf_fragment,
  8764. logdepthbuf_pars_fragment: logdepthbuf_pars_fragment,
  8765. logdepthbuf_pars_vertex: logdepthbuf_pars_vertex,
  8766. logdepthbuf_vertex: logdepthbuf_vertex,
  8767. map_fragment: map_fragment,
  8768. map_pars_fragment: map_pars_fragment,
  8769. map_particle_fragment: map_particle_fragment,
  8770. map_particle_pars_fragment: map_particle_pars_fragment,
  8771. metalnessmap_fragment: metalnessmap_fragment,
  8772. metalnessmap_pars_fragment: metalnessmap_pars_fragment,
  8773. morphcolor_vertex: morphcolor_vertex,
  8774. morphnormal_vertex: morphnormal_vertex,
  8775. morphtarget_pars_vertex: morphtarget_pars_vertex,
  8776. morphtarget_vertex: morphtarget_vertex,
  8777. normal_fragment_begin: normal_fragment_begin,
  8778. normal_fragment_maps: normal_fragment_maps,
  8779. normal_pars_fragment: normal_pars_fragment,
  8780. normal_pars_vertex: normal_pars_vertex,
  8781. normal_vertex: normal_vertex,
  8782. normalmap_pars_fragment: normalmap_pars_fragment,
  8783. clearcoat_normal_fragment_begin: clearcoat_normal_fragment_begin,
  8784. clearcoat_normal_fragment_maps: clearcoat_normal_fragment_maps,
  8785. clearcoat_pars_fragment: clearcoat_pars_fragment,
  8786. iridescence_pars_fragment: iridescence_pars_fragment,
  8787. output_fragment: output_fragment,
  8788. packing: packing,
  8789. premultiplied_alpha_fragment: premultiplied_alpha_fragment,
  8790. project_vertex: project_vertex,
  8791. dithering_fragment: dithering_fragment,
  8792. dithering_pars_fragment: dithering_pars_fragment,
  8793. roughnessmap_fragment: roughnessmap_fragment,
  8794. roughnessmap_pars_fragment: roughnessmap_pars_fragment,
  8795. shadowmap_pars_fragment: shadowmap_pars_fragment,
  8796. shadowmap_pars_vertex: shadowmap_pars_vertex,
  8797. shadowmap_vertex: shadowmap_vertex,
  8798. shadowmask_pars_fragment: shadowmask_pars_fragment,
  8799. skinbase_vertex: skinbase_vertex,
  8800. skinning_pars_vertex: skinning_pars_vertex,
  8801. skinning_vertex: skinning_vertex,
  8802. skinnormal_vertex: skinnormal_vertex,
  8803. specularmap_fragment: specularmap_fragment,
  8804. specularmap_pars_fragment: specularmap_pars_fragment,
  8805. tonemapping_fragment: tonemapping_fragment,
  8806. tonemapping_pars_fragment: tonemapping_pars_fragment,
  8807. transmission_fragment: transmission_fragment,
  8808. transmission_pars_fragment: transmission_pars_fragment,
  8809. uv_pars_fragment: uv_pars_fragment,
  8810. uv_pars_vertex: uv_pars_vertex,
  8811. uv_vertex: uv_vertex,
  8812. uv2_pars_fragment: uv2_pars_fragment,
  8813. uv2_pars_vertex: uv2_pars_vertex,
  8814. uv2_vertex: uv2_vertex,
  8815. worldpos_vertex: worldpos_vertex,
  8816. background_vert: vertex$g,
  8817. background_frag: fragment$g,
  8818. cube_vert: vertex$f,
  8819. cube_frag: fragment$f,
  8820. depth_vert: vertex$e,
  8821. depth_frag: fragment$e,
  8822. distanceRGBA_vert: vertex$d,
  8823. distanceRGBA_frag: fragment$d,
  8824. equirect_vert: vertex$c,
  8825. equirect_frag: fragment$c,
  8826. linedashed_vert: vertex$b,
  8827. linedashed_frag: fragment$b,
  8828. meshbasic_vert: vertex$a,
  8829. meshbasic_frag: fragment$a,
  8830. meshlambert_vert: vertex$9,
  8831. meshlambert_frag: fragment$9,
  8832. meshmatcap_vert: vertex$8,
  8833. meshmatcap_frag: fragment$8,
  8834. meshnormal_vert: vertex$7,
  8835. meshnormal_frag: fragment$7,
  8836. meshphong_vert: vertex$6,
  8837. meshphong_frag: fragment$6,
  8838. meshphysical_vert: vertex$5,
  8839. meshphysical_frag: fragment$5,
  8840. meshtoon_vert: vertex$4,
  8841. meshtoon_frag: fragment$4,
  8842. points_vert: vertex$3,
  8843. points_frag: fragment$3,
  8844. shadow_vert: vertex$2,
  8845. shadow_frag: fragment$2,
  8846. sprite_vert: vertex$1,
  8847. sprite_frag: fragment$1
  8848. };
  8849. /**
  8850. * Uniforms library for shared webgl shaders
  8851. */
  8852. const UniformsLib = {
  8853. common: {
  8854. diffuse: {
  8855. value: /*@__PURE__*/new Color(0xffffff)
  8856. },
  8857. opacity: {
  8858. value: 1.0
  8859. },
  8860. map: {
  8861. value: null
  8862. },
  8863. uvTransform: {
  8864. value: /*@__PURE__*/new Matrix3()
  8865. },
  8866. uv2Transform: {
  8867. value: /*@__PURE__*/new Matrix3()
  8868. },
  8869. alphaMap: {
  8870. value: null
  8871. },
  8872. alphaTest: {
  8873. value: 0
  8874. }
  8875. },
  8876. specularmap: {
  8877. specularMap: {
  8878. value: null
  8879. }
  8880. },
  8881. envmap: {
  8882. envMap: {
  8883. value: null
  8884. },
  8885. flipEnvMap: {
  8886. value: -1
  8887. },
  8888. reflectivity: {
  8889. value: 1.0
  8890. },
  8891. // basic, lambert, phong
  8892. ior: {
  8893. value: 1.5
  8894. },
  8895. // physical
  8896. refractionRatio: {
  8897. value: 0.98
  8898. } // basic, lambert, phong
  8899. },
  8900. aomap: {
  8901. aoMap: {
  8902. value: null
  8903. },
  8904. aoMapIntensity: {
  8905. value: 1
  8906. }
  8907. },
  8908. lightmap: {
  8909. lightMap: {
  8910. value: null
  8911. },
  8912. lightMapIntensity: {
  8913. value: 1
  8914. }
  8915. },
  8916. emissivemap: {
  8917. emissiveMap: {
  8918. value: null
  8919. }
  8920. },
  8921. bumpmap: {
  8922. bumpMap: {
  8923. value: null
  8924. },
  8925. bumpScale: {
  8926. value: 1
  8927. }
  8928. },
  8929. normalmap: {
  8930. normalMap: {
  8931. value: null
  8932. },
  8933. normalScale: {
  8934. value: /*@__PURE__*/new Vector2(1, 1)
  8935. }
  8936. },
  8937. displacementmap: {
  8938. displacementMap: {
  8939. value: null
  8940. },
  8941. displacementScale: {
  8942. value: 1
  8943. },
  8944. displacementBias: {
  8945. value: 0
  8946. }
  8947. },
  8948. roughnessmap: {
  8949. roughnessMap: {
  8950. value: null
  8951. }
  8952. },
  8953. metalnessmap: {
  8954. metalnessMap: {
  8955. value: null
  8956. }
  8957. },
  8958. gradientmap: {
  8959. gradientMap: {
  8960. value: null
  8961. }
  8962. },
  8963. fog: {
  8964. fogDensity: {
  8965. value: 0.00025
  8966. },
  8967. fogNear: {
  8968. value: 1
  8969. },
  8970. fogFar: {
  8971. value: 2000
  8972. },
  8973. fogColor: {
  8974. value: /*@__PURE__*/new Color(0xffffff)
  8975. }
  8976. },
  8977. lights: {
  8978. ambientLightColor: {
  8979. value: []
  8980. },
  8981. lightProbe: {
  8982. value: []
  8983. },
  8984. directionalLights: {
  8985. value: [],
  8986. properties: {
  8987. direction: {},
  8988. color: {}
  8989. }
  8990. },
  8991. directionalLightShadows: {
  8992. value: [],
  8993. properties: {
  8994. shadowBias: {},
  8995. shadowNormalBias: {},
  8996. shadowRadius: {},
  8997. shadowMapSize: {}
  8998. }
  8999. },
  9000. directionalShadowMap: {
  9001. value: []
  9002. },
  9003. directionalShadowMatrix: {
  9004. value: []
  9005. },
  9006. spotLights: {
  9007. value: [],
  9008. properties: {
  9009. color: {},
  9010. position: {},
  9011. direction: {},
  9012. distance: {},
  9013. coneCos: {},
  9014. penumbraCos: {},
  9015. decay: {}
  9016. }
  9017. },
  9018. spotLightShadows: {
  9019. value: [],
  9020. properties: {
  9021. shadowBias: {},
  9022. shadowNormalBias: {},
  9023. shadowRadius: {},
  9024. shadowMapSize: {}
  9025. }
  9026. },
  9027. spotShadowMap: {
  9028. value: []
  9029. },
  9030. spotShadowMatrix: {
  9031. value: []
  9032. },
  9033. pointLights: {
  9034. value: [],
  9035. properties: {
  9036. color: {},
  9037. position: {},
  9038. decay: {},
  9039. distance: {}
  9040. }
  9041. },
  9042. pointLightShadows: {
  9043. value: [],
  9044. properties: {
  9045. shadowBias: {},
  9046. shadowNormalBias: {},
  9047. shadowRadius: {},
  9048. shadowMapSize: {},
  9049. shadowCameraNear: {},
  9050. shadowCameraFar: {}
  9051. }
  9052. },
  9053. pointShadowMap: {
  9054. value: []
  9055. },
  9056. pointShadowMatrix: {
  9057. value: []
  9058. },
  9059. hemisphereLights: {
  9060. value: [],
  9061. properties: {
  9062. direction: {},
  9063. skyColor: {},
  9064. groundColor: {}
  9065. }
  9066. },
  9067. // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src
  9068. rectAreaLights: {
  9069. value: [],
  9070. properties: {
  9071. color: {},
  9072. position: {},
  9073. width: {},
  9074. height: {}
  9075. }
  9076. },
  9077. ltc_1: {
  9078. value: null
  9079. },
  9080. ltc_2: {
  9081. value: null
  9082. }
  9083. },
  9084. points: {
  9085. diffuse: {
  9086. value: /*@__PURE__*/new Color(0xffffff)
  9087. },
  9088. opacity: {
  9089. value: 1.0
  9090. },
  9091. size: {
  9092. value: 1.0
  9093. },
  9094. scale: {
  9095. value: 1.0
  9096. },
  9097. map: {
  9098. value: null
  9099. },
  9100. alphaMap: {
  9101. value: null
  9102. },
  9103. alphaTest: {
  9104. value: 0
  9105. },
  9106. uvTransform: {
  9107. value: /*@__PURE__*/new Matrix3()
  9108. }
  9109. },
  9110. sprite: {
  9111. diffuse: {
  9112. value: /*@__PURE__*/new Color(0xffffff)
  9113. },
  9114. opacity: {
  9115. value: 1.0
  9116. },
  9117. center: {
  9118. value: /*@__PURE__*/new Vector2(0.5, 0.5)
  9119. },
  9120. rotation: {
  9121. value: 0.0
  9122. },
  9123. map: {
  9124. value: null
  9125. },
  9126. alphaMap: {
  9127. value: null
  9128. },
  9129. alphaTest: {
  9130. value: 0
  9131. },
  9132. uvTransform: {
  9133. value: /*@__PURE__*/new Matrix3()
  9134. }
  9135. }
  9136. };
  9137. const ShaderLib = {
  9138. basic: {
  9139. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.fog]),
  9140. vertexShader: ShaderChunk.meshbasic_vert,
  9141. fragmentShader: ShaderChunk.meshbasic_frag
  9142. },
  9143. lambert: {
  9144. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.fog, UniformsLib.lights, {
  9145. emissive: {
  9146. value: /*@__PURE__*/new Color(0x000000)
  9147. }
  9148. }]),
  9149. vertexShader: ShaderChunk.meshlambert_vert,
  9150. fragmentShader: ShaderChunk.meshlambert_frag
  9151. },
  9152. phong: {
  9153. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.specularmap, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, UniformsLib.lights, {
  9154. emissive: {
  9155. value: /*@__PURE__*/new Color(0x000000)
  9156. },
  9157. specular: {
  9158. value: /*@__PURE__*/new Color(0x111111)
  9159. },
  9160. shininess: {
  9161. value: 30
  9162. }
  9163. }]),
  9164. vertexShader: ShaderChunk.meshphong_vert,
  9165. fragmentShader: ShaderChunk.meshphong_frag
  9166. },
  9167. standard: {
  9168. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.envmap, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.roughnessmap, UniformsLib.metalnessmap, UniformsLib.fog, UniformsLib.lights, {
  9169. emissive: {
  9170. value: /*@__PURE__*/new Color(0x000000)
  9171. },
  9172. roughness: {
  9173. value: 1.0
  9174. },
  9175. metalness: {
  9176. value: 0.0
  9177. },
  9178. envMapIntensity: {
  9179. value: 1
  9180. } // temporary
  9181. }]),
  9182. vertexShader: ShaderChunk.meshphysical_vert,
  9183. fragmentShader: ShaderChunk.meshphysical_frag
  9184. },
  9185. toon: {
  9186. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.aomap, UniformsLib.lightmap, UniformsLib.emissivemap, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.gradientmap, UniformsLib.fog, UniformsLib.lights, {
  9187. emissive: {
  9188. value: /*@__PURE__*/new Color(0x000000)
  9189. }
  9190. }]),
  9191. vertexShader: ShaderChunk.meshtoon_vert,
  9192. fragmentShader: ShaderChunk.meshtoon_frag
  9193. },
  9194. matcap: {
  9195. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, UniformsLib.fog, {
  9196. matcap: {
  9197. value: null
  9198. }
  9199. }]),
  9200. vertexShader: ShaderChunk.meshmatcap_vert,
  9201. fragmentShader: ShaderChunk.meshmatcap_frag
  9202. },
  9203. points: {
  9204. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.points, UniformsLib.fog]),
  9205. vertexShader: ShaderChunk.points_vert,
  9206. fragmentShader: ShaderChunk.points_frag
  9207. },
  9208. dashed: {
  9209. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.fog, {
  9210. scale: {
  9211. value: 1
  9212. },
  9213. dashSize: {
  9214. value: 1
  9215. },
  9216. totalSize: {
  9217. value: 2
  9218. }
  9219. }]),
  9220. vertexShader: ShaderChunk.linedashed_vert,
  9221. fragmentShader: ShaderChunk.linedashed_frag
  9222. },
  9223. depth: {
  9224. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.displacementmap]),
  9225. vertexShader: ShaderChunk.depth_vert,
  9226. fragmentShader: ShaderChunk.depth_frag
  9227. },
  9228. normal: {
  9229. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.bumpmap, UniformsLib.normalmap, UniformsLib.displacementmap, {
  9230. opacity: {
  9231. value: 1.0
  9232. }
  9233. }]),
  9234. vertexShader: ShaderChunk.meshnormal_vert,
  9235. fragmentShader: ShaderChunk.meshnormal_frag
  9236. },
  9237. sprite: {
  9238. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.sprite, UniformsLib.fog]),
  9239. vertexShader: ShaderChunk.sprite_vert,
  9240. fragmentShader: ShaderChunk.sprite_frag
  9241. },
  9242. background: {
  9243. uniforms: {
  9244. uvTransform: {
  9245. value: /*@__PURE__*/new Matrix3()
  9246. },
  9247. t2D: {
  9248. value: null
  9249. }
  9250. },
  9251. vertexShader: ShaderChunk.background_vert,
  9252. fragmentShader: ShaderChunk.background_frag
  9253. },
  9254. cube: {
  9255. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.envmap, {
  9256. opacity: {
  9257. value: 1.0
  9258. }
  9259. }]),
  9260. vertexShader: ShaderChunk.cube_vert,
  9261. fragmentShader: ShaderChunk.cube_frag
  9262. },
  9263. equirect: {
  9264. uniforms: {
  9265. tEquirect: {
  9266. value: null
  9267. }
  9268. },
  9269. vertexShader: ShaderChunk.equirect_vert,
  9270. fragmentShader: ShaderChunk.equirect_frag
  9271. },
  9272. distanceRGBA: {
  9273. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.common, UniformsLib.displacementmap, {
  9274. referencePosition: {
  9275. value: /*@__PURE__*/new Vector3()
  9276. },
  9277. nearDistance: {
  9278. value: 1
  9279. },
  9280. farDistance: {
  9281. value: 1000
  9282. }
  9283. }]),
  9284. vertexShader: ShaderChunk.distanceRGBA_vert,
  9285. fragmentShader: ShaderChunk.distanceRGBA_frag
  9286. },
  9287. shadow: {
  9288. uniforms: /*@__PURE__*/mergeUniforms([UniformsLib.lights, UniformsLib.fog, {
  9289. color: {
  9290. value: /*@__PURE__*/new Color(0x00000)
  9291. },
  9292. opacity: {
  9293. value: 1.0
  9294. }
  9295. }]),
  9296. vertexShader: ShaderChunk.shadow_vert,
  9297. fragmentShader: ShaderChunk.shadow_frag
  9298. }
  9299. };
  9300. ShaderLib.physical = {
  9301. uniforms: /*@__PURE__*/mergeUniforms([ShaderLib.standard.uniforms, {
  9302. clearcoat: {
  9303. value: 0
  9304. },
  9305. clearcoatMap: {
  9306. value: null
  9307. },
  9308. clearcoatRoughness: {
  9309. value: 0
  9310. },
  9311. clearcoatRoughnessMap: {
  9312. value: null
  9313. },
  9314. clearcoatNormalScale: {
  9315. value: /*@__PURE__*/new Vector2(1, 1)
  9316. },
  9317. clearcoatNormalMap: {
  9318. value: null
  9319. },
  9320. iridescence: {
  9321. value: 0
  9322. },
  9323. iridescenceMap: {
  9324. value: null
  9325. },
  9326. iridescenceIOR: {
  9327. value: 1.3
  9328. },
  9329. iridescenceThicknessMinimum: {
  9330. value: 100
  9331. },
  9332. iridescenceThicknessMaximum: {
  9333. value: 400
  9334. },
  9335. iridescenceThicknessMap: {
  9336. value: null
  9337. },
  9338. sheen: {
  9339. value: 0
  9340. },
  9341. sheenColor: {
  9342. value: /*@__PURE__*/new Color(0x000000)
  9343. },
  9344. sheenColorMap: {
  9345. value: null
  9346. },
  9347. sheenRoughness: {
  9348. value: 1
  9349. },
  9350. sheenRoughnessMap: {
  9351. value: null
  9352. },
  9353. transmission: {
  9354. value: 0
  9355. },
  9356. transmissionMap: {
  9357. value: null
  9358. },
  9359. transmissionSamplerSize: {
  9360. value: /*@__PURE__*/new Vector2()
  9361. },
  9362. transmissionSamplerMap: {
  9363. value: null
  9364. },
  9365. thickness: {
  9366. value: 0
  9367. },
  9368. thicknessMap: {
  9369. value: null
  9370. },
  9371. attenuationDistance: {
  9372. value: 0
  9373. },
  9374. attenuationColor: {
  9375. value: /*@__PURE__*/new Color(0x000000)
  9376. },
  9377. specularIntensity: {
  9378. value: 1
  9379. },
  9380. specularIntensityMap: {
  9381. value: null
  9382. },
  9383. specularColor: {
  9384. value: /*@__PURE__*/new Color(1, 1, 1)
  9385. },
  9386. specularColorMap: {
  9387. value: null
  9388. }
  9389. }]),
  9390. vertexShader: ShaderChunk.meshphysical_vert,
  9391. fragmentShader: ShaderChunk.meshphysical_frag
  9392. };
  9393. function WebGLBackground(renderer, cubemaps, state, objects, alpha, premultipliedAlpha) {
  9394. const clearColor = new Color(0x000000);
  9395. let clearAlpha = alpha === true ? 0 : 1;
  9396. let planeMesh;
  9397. let boxMesh;
  9398. let currentBackground = null;
  9399. let currentBackgroundVersion = 0;
  9400. let currentTonemapping = null;
  9401. function render(renderList, scene) {
  9402. let forceClear = false;
  9403. let background = scene.isScene === true ? scene.background : null;
  9404. if (background && background.isTexture) {
  9405. background = cubemaps.get(background);
  9406. } // Ignore background in AR
  9407. // TODO: Reconsider this.
  9408. const xr = renderer.xr;
  9409. const session = xr.getSession && xr.getSession();
  9410. if (session && session.environmentBlendMode === 'additive') {
  9411. background = null;
  9412. }
  9413. if (background === null) {
  9414. setClear(clearColor, clearAlpha);
  9415. } else if (background && background.isColor) {
  9416. setClear(background, 1);
  9417. forceClear = true;
  9418. }
  9419. if (renderer.autoClear || forceClear) {
  9420. renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil);
  9421. }
  9422. if (background && (background.isCubeTexture || background.mapping === CubeUVReflectionMapping)) {
  9423. if (boxMesh === undefined) {
  9424. boxMesh = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({
  9425. name: 'BackgroundCubeMaterial',
  9426. uniforms: cloneUniforms(ShaderLib.cube.uniforms),
  9427. vertexShader: ShaderLib.cube.vertexShader,
  9428. fragmentShader: ShaderLib.cube.fragmentShader,
  9429. side: BackSide,
  9430. depthTest: false,
  9431. depthWrite: false,
  9432. fog: false
  9433. }));
  9434. boxMesh.geometry.deleteAttribute('normal');
  9435. boxMesh.geometry.deleteAttribute('uv');
  9436. boxMesh.onBeforeRender = function (renderer, scene, camera) {
  9437. this.matrixWorld.copyPosition(camera.matrixWorld);
  9438. }; // enable code injection for non-built-in material
  9439. Object.defineProperty(boxMesh.material, 'envMap', {
  9440. get: function () {
  9441. return this.uniforms.envMap.value;
  9442. }
  9443. });
  9444. objects.update(boxMesh);
  9445. }
  9446. boxMesh.material.uniforms.envMap.value = background;
  9447. boxMesh.material.uniforms.flipEnvMap.value = background.isCubeTexture && background.isRenderTargetTexture === false ? -1 : 1;
  9448. if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) {
  9449. boxMesh.material.needsUpdate = true;
  9450. currentBackground = background;
  9451. currentBackgroundVersion = background.version;
  9452. currentTonemapping = renderer.toneMapping;
  9453. }
  9454. boxMesh.layers.enableAll(); // push to the pre-sorted opaque render list
  9455. renderList.unshift(boxMesh, boxMesh.geometry, boxMesh.material, 0, 0, null);
  9456. } else if (background && background.isTexture) {
  9457. if (planeMesh === undefined) {
  9458. planeMesh = new Mesh(new PlaneGeometry(2, 2), new ShaderMaterial({
  9459. name: 'BackgroundMaterial',
  9460. uniforms: cloneUniforms(ShaderLib.background.uniforms),
  9461. vertexShader: ShaderLib.background.vertexShader,
  9462. fragmentShader: ShaderLib.background.fragmentShader,
  9463. side: FrontSide,
  9464. depthTest: false,
  9465. depthWrite: false,
  9466. fog: false
  9467. }));
  9468. planeMesh.geometry.deleteAttribute('normal'); // enable code injection for non-built-in material
  9469. Object.defineProperty(planeMesh.material, 'map', {
  9470. get: function () {
  9471. return this.uniforms.t2D.value;
  9472. }
  9473. });
  9474. objects.update(planeMesh);
  9475. }
  9476. planeMesh.material.uniforms.t2D.value = background;
  9477. if (background.matrixAutoUpdate === true) {
  9478. background.updateMatrix();
  9479. }
  9480. planeMesh.material.uniforms.uvTransform.value.copy(background.matrix);
  9481. if (currentBackground !== background || currentBackgroundVersion !== background.version || currentTonemapping !== renderer.toneMapping) {
  9482. planeMesh.material.needsUpdate = true;
  9483. currentBackground = background;
  9484. currentBackgroundVersion = background.version;
  9485. currentTonemapping = renderer.toneMapping;
  9486. }
  9487. planeMesh.layers.enableAll(); // push to the pre-sorted opaque render list
  9488. renderList.unshift(planeMesh, planeMesh.geometry, planeMesh.material, 0, 0, null);
  9489. }
  9490. }
  9491. function setClear(color, alpha) {
  9492. state.buffers.color.setClear(color.r, color.g, color.b, alpha, premultipliedAlpha);
  9493. }
  9494. return {
  9495. getClearColor: function () {
  9496. return clearColor;
  9497. },
  9498. setClearColor: function (color, alpha = 1) {
  9499. clearColor.set(color);
  9500. clearAlpha = alpha;
  9501. setClear(clearColor, clearAlpha);
  9502. },
  9503. getClearAlpha: function () {
  9504. return clearAlpha;
  9505. },
  9506. setClearAlpha: function (alpha) {
  9507. clearAlpha = alpha;
  9508. setClear(clearColor, clearAlpha);
  9509. },
  9510. render: render
  9511. };
  9512. }
  9513. function WebGLBindingStates(gl, extensions, attributes, capabilities) {
  9514. const maxVertexAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
  9515. const extension = capabilities.isWebGL2 ? null : extensions.get('OES_vertex_array_object');
  9516. const vaoAvailable = capabilities.isWebGL2 || extension !== null;
  9517. const bindingStates = {};
  9518. const defaultState = createBindingState(null);
  9519. let currentState = defaultState;
  9520. let forceUpdate = false;
  9521. function setup(object, material, program, geometry, index) {
  9522. let updateBuffers = false;
  9523. if (vaoAvailable) {
  9524. const state = getBindingState(geometry, program, material);
  9525. if (currentState !== state) {
  9526. currentState = state;
  9527. bindVertexArrayObject(currentState.object);
  9528. }
  9529. updateBuffers = needsUpdate(object, geometry, program, index);
  9530. if (updateBuffers) saveCache(object, geometry, program, index);
  9531. } else {
  9532. const wireframe = material.wireframe === true;
  9533. if (currentState.geometry !== geometry.id || currentState.program !== program.id || currentState.wireframe !== wireframe) {
  9534. currentState.geometry = geometry.id;
  9535. currentState.program = program.id;
  9536. currentState.wireframe = wireframe;
  9537. updateBuffers = true;
  9538. }
  9539. }
  9540. if (index !== null) {
  9541. attributes.update(index, gl.ELEMENT_ARRAY_BUFFER);
  9542. }
  9543. if (updateBuffers || forceUpdate) {
  9544. forceUpdate = false;
  9545. setupVertexAttributes(object, material, program, geometry);
  9546. if (index !== null) {
  9547. gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, attributes.get(index).buffer);
  9548. }
  9549. }
  9550. }
  9551. function createVertexArrayObject() {
  9552. if (capabilities.isWebGL2) return gl.createVertexArray();
  9553. return extension.createVertexArrayOES();
  9554. }
  9555. function bindVertexArrayObject(vao) {
  9556. if (capabilities.isWebGL2) return gl.bindVertexArray(vao);
  9557. return extension.bindVertexArrayOES(vao);
  9558. }
  9559. function deleteVertexArrayObject(vao) {
  9560. if (capabilities.isWebGL2) return gl.deleteVertexArray(vao);
  9561. return extension.deleteVertexArrayOES(vao);
  9562. }
  9563. function getBindingState(geometry, program, material) {
  9564. const wireframe = material.wireframe === true;
  9565. let programMap = bindingStates[geometry.id];
  9566. if (programMap === undefined) {
  9567. programMap = {};
  9568. bindingStates[geometry.id] = programMap;
  9569. }
  9570. let stateMap = programMap[program.id];
  9571. if (stateMap === undefined) {
  9572. stateMap = {};
  9573. programMap[program.id] = stateMap;
  9574. }
  9575. let state = stateMap[wireframe];
  9576. if (state === undefined) {
  9577. state = createBindingState(createVertexArrayObject());
  9578. stateMap[wireframe] = state;
  9579. }
  9580. return state;
  9581. }
  9582. function createBindingState(vao) {
  9583. const newAttributes = [];
  9584. const enabledAttributes = [];
  9585. const attributeDivisors = [];
  9586. for (let i = 0; i < maxVertexAttributes; i++) {
  9587. newAttributes[i] = 0;
  9588. enabledAttributes[i] = 0;
  9589. attributeDivisors[i] = 0;
  9590. }
  9591. return {
  9592. // for backward compatibility on non-VAO support browser
  9593. geometry: null,
  9594. program: null,
  9595. wireframe: false,
  9596. newAttributes: newAttributes,
  9597. enabledAttributes: enabledAttributes,
  9598. attributeDivisors: attributeDivisors,
  9599. object: vao,
  9600. attributes: {},
  9601. index: null
  9602. };
  9603. }
  9604. function needsUpdate(object, geometry, program, index) {
  9605. const cachedAttributes = currentState.attributes;
  9606. const geometryAttributes = geometry.attributes;
  9607. let attributesNum = 0;
  9608. const programAttributes = program.getAttributes();
  9609. for (const name in programAttributes) {
  9610. const programAttribute = programAttributes[name];
  9611. if (programAttribute.location >= 0) {
  9612. const cachedAttribute = cachedAttributes[name];
  9613. let geometryAttribute = geometryAttributes[name];
  9614. if (geometryAttribute === undefined) {
  9615. if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix;
  9616. if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor;
  9617. }
  9618. if (cachedAttribute === undefined) return true;
  9619. if (cachedAttribute.attribute !== geometryAttribute) return true;
  9620. if (geometryAttribute && cachedAttribute.data !== geometryAttribute.data) return true;
  9621. attributesNum++;
  9622. }
  9623. }
  9624. if (currentState.attributesNum !== attributesNum) return true;
  9625. if (currentState.index !== index) return true;
  9626. return false;
  9627. }
  9628. function saveCache(object, geometry, program, index) {
  9629. const cache = {};
  9630. const attributes = geometry.attributes;
  9631. let attributesNum = 0;
  9632. const programAttributes = program.getAttributes();
  9633. for (const name in programAttributes) {
  9634. const programAttribute = programAttributes[name];
  9635. if (programAttribute.location >= 0) {
  9636. let attribute = attributes[name];
  9637. if (attribute === undefined) {
  9638. if (name === 'instanceMatrix' && object.instanceMatrix) attribute = object.instanceMatrix;
  9639. if (name === 'instanceColor' && object.instanceColor) attribute = object.instanceColor;
  9640. }
  9641. const data = {};
  9642. data.attribute = attribute;
  9643. if (attribute && attribute.data) {
  9644. data.data = attribute.data;
  9645. }
  9646. cache[name] = data;
  9647. attributesNum++;
  9648. }
  9649. }
  9650. currentState.attributes = cache;
  9651. currentState.attributesNum = attributesNum;
  9652. currentState.index = index;
  9653. }
  9654. function initAttributes() {
  9655. const newAttributes = currentState.newAttributes;
  9656. for (let i = 0, il = newAttributes.length; i < il; i++) {
  9657. newAttributes[i] = 0;
  9658. }
  9659. }
  9660. function enableAttribute(attribute) {
  9661. enableAttributeAndDivisor(attribute, 0);
  9662. }
  9663. function enableAttributeAndDivisor(attribute, meshPerAttribute) {
  9664. const newAttributes = currentState.newAttributes;
  9665. const enabledAttributes = currentState.enabledAttributes;
  9666. const attributeDivisors = currentState.attributeDivisors;
  9667. newAttributes[attribute] = 1;
  9668. if (enabledAttributes[attribute] === 0) {
  9669. gl.enableVertexAttribArray(attribute);
  9670. enabledAttributes[attribute] = 1;
  9671. }
  9672. if (attributeDivisors[attribute] !== meshPerAttribute) {
  9673. const extension = capabilities.isWebGL2 ? gl : extensions.get('ANGLE_instanced_arrays');
  9674. extension[capabilities.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE'](attribute, meshPerAttribute);
  9675. attributeDivisors[attribute] = meshPerAttribute;
  9676. }
  9677. }
  9678. function disableUnusedAttributes() {
  9679. const newAttributes = currentState.newAttributes;
  9680. const enabledAttributes = currentState.enabledAttributes;
  9681. for (let i = 0, il = enabledAttributes.length; i < il; i++) {
  9682. if (enabledAttributes[i] !== newAttributes[i]) {
  9683. gl.disableVertexAttribArray(i);
  9684. enabledAttributes[i] = 0;
  9685. }
  9686. }
  9687. }
  9688. function vertexAttribPointer(index, size, type, normalized, stride, offset) {
  9689. if (capabilities.isWebGL2 === true && (type === gl.INT || type === gl.UNSIGNED_INT)) {
  9690. gl.vertexAttribIPointer(index, size, type, stride, offset);
  9691. } else {
  9692. gl.vertexAttribPointer(index, size, type, normalized, stride, offset);
  9693. }
  9694. }
  9695. function setupVertexAttributes(object, material, program, geometry) {
  9696. if (capabilities.isWebGL2 === false && (object.isInstancedMesh || geometry.isInstancedBufferGeometry)) {
  9697. if (extensions.get('ANGLE_instanced_arrays') === null) return;
  9698. }
  9699. initAttributes();
  9700. const geometryAttributes = geometry.attributes;
  9701. const programAttributes = program.getAttributes();
  9702. const materialDefaultAttributeValues = material.defaultAttributeValues;
  9703. for (const name in programAttributes) {
  9704. const programAttribute = programAttributes[name];
  9705. if (programAttribute.location >= 0) {
  9706. let geometryAttribute = geometryAttributes[name];
  9707. if (geometryAttribute === undefined) {
  9708. if (name === 'instanceMatrix' && object.instanceMatrix) geometryAttribute = object.instanceMatrix;
  9709. if (name === 'instanceColor' && object.instanceColor) geometryAttribute = object.instanceColor;
  9710. }
  9711. if (geometryAttribute !== undefined) {
  9712. const normalized = geometryAttribute.normalized;
  9713. const size = geometryAttribute.itemSize;
  9714. const attribute = attributes.get(geometryAttribute); // TODO Attribute may not be available on context restore
  9715. if (attribute === undefined) continue;
  9716. const buffer = attribute.buffer;
  9717. const type = attribute.type;
  9718. const bytesPerElement = attribute.bytesPerElement;
  9719. if (geometryAttribute.isInterleavedBufferAttribute) {
  9720. const data = geometryAttribute.data;
  9721. const stride = data.stride;
  9722. const offset = geometryAttribute.offset;
  9723. if (data.isInstancedInterleavedBuffer) {
  9724. for (let i = 0; i < programAttribute.locationSize; i++) {
  9725. enableAttributeAndDivisor(programAttribute.location + i, data.meshPerAttribute);
  9726. }
  9727. if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) {
  9728. geometry._maxInstanceCount = data.meshPerAttribute * data.count;
  9729. }
  9730. } else {
  9731. for (let i = 0; i < programAttribute.locationSize; i++) {
  9732. enableAttribute(programAttribute.location + i);
  9733. }
  9734. }
  9735. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  9736. for (let i = 0; i < programAttribute.locationSize; i++) {
  9737. vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, stride * bytesPerElement, (offset + size / programAttribute.locationSize * i) * bytesPerElement);
  9738. }
  9739. } else {
  9740. if (geometryAttribute.isInstancedBufferAttribute) {
  9741. for (let i = 0; i < programAttribute.locationSize; i++) {
  9742. enableAttributeAndDivisor(programAttribute.location + i, geometryAttribute.meshPerAttribute);
  9743. }
  9744. if (object.isInstancedMesh !== true && geometry._maxInstanceCount === undefined) {
  9745. geometry._maxInstanceCount = geometryAttribute.meshPerAttribute * geometryAttribute.count;
  9746. }
  9747. } else {
  9748. for (let i = 0; i < programAttribute.locationSize; i++) {
  9749. enableAttribute(programAttribute.location + i);
  9750. }
  9751. }
  9752. gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  9753. for (let i = 0; i < programAttribute.locationSize; i++) {
  9754. vertexAttribPointer(programAttribute.location + i, size / programAttribute.locationSize, type, normalized, size * bytesPerElement, size / programAttribute.locationSize * i * bytesPerElement);
  9755. }
  9756. }
  9757. } else if (materialDefaultAttributeValues !== undefined) {
  9758. const value = materialDefaultAttributeValues[name];
  9759. if (value !== undefined) {
  9760. switch (value.length) {
  9761. case 2:
  9762. gl.vertexAttrib2fv(programAttribute.location, value);
  9763. break;
  9764. case 3:
  9765. gl.vertexAttrib3fv(programAttribute.location, value);
  9766. break;
  9767. case 4:
  9768. gl.vertexAttrib4fv(programAttribute.location, value);
  9769. break;
  9770. default:
  9771. gl.vertexAttrib1fv(programAttribute.location, value);
  9772. }
  9773. }
  9774. }
  9775. }
  9776. }
  9777. disableUnusedAttributes();
  9778. }
  9779. function dispose() {
  9780. reset();
  9781. for (const geometryId in bindingStates) {
  9782. const programMap = bindingStates[geometryId];
  9783. for (const programId in programMap) {
  9784. const stateMap = programMap[programId];
  9785. for (const wireframe in stateMap) {
  9786. deleteVertexArrayObject(stateMap[wireframe].object);
  9787. delete stateMap[wireframe];
  9788. }
  9789. delete programMap[programId];
  9790. }
  9791. delete bindingStates[geometryId];
  9792. }
  9793. }
  9794. function releaseStatesOfGeometry(geometry) {
  9795. if (bindingStates[geometry.id] === undefined) return;
  9796. const programMap = bindingStates[geometry.id];
  9797. for (const programId in programMap) {
  9798. const stateMap = programMap[programId];
  9799. for (const wireframe in stateMap) {
  9800. deleteVertexArrayObject(stateMap[wireframe].object);
  9801. delete stateMap[wireframe];
  9802. }
  9803. delete programMap[programId];
  9804. }
  9805. delete bindingStates[geometry.id];
  9806. }
  9807. function releaseStatesOfProgram(program) {
  9808. for (const geometryId in bindingStates) {
  9809. const programMap = bindingStates[geometryId];
  9810. if (programMap[program.id] === undefined) continue;
  9811. const stateMap = programMap[program.id];
  9812. for (const wireframe in stateMap) {
  9813. deleteVertexArrayObject(stateMap[wireframe].object);
  9814. delete stateMap[wireframe];
  9815. }
  9816. delete programMap[program.id];
  9817. }
  9818. }
  9819. function reset() {
  9820. resetDefaultState();
  9821. forceUpdate = true;
  9822. if (currentState === defaultState) return;
  9823. currentState = defaultState;
  9824. bindVertexArrayObject(currentState.object);
  9825. } // for backward-compatibility
  9826. function resetDefaultState() {
  9827. defaultState.geometry = null;
  9828. defaultState.program = null;
  9829. defaultState.wireframe = false;
  9830. }
  9831. return {
  9832. setup: setup,
  9833. reset: reset,
  9834. resetDefaultState: resetDefaultState,
  9835. dispose: dispose,
  9836. releaseStatesOfGeometry: releaseStatesOfGeometry,
  9837. releaseStatesOfProgram: releaseStatesOfProgram,
  9838. initAttributes: initAttributes,
  9839. enableAttribute: enableAttribute,
  9840. disableUnusedAttributes: disableUnusedAttributes
  9841. };
  9842. }
  9843. function WebGLBufferRenderer(gl, extensions, info, capabilities) {
  9844. const isWebGL2 = capabilities.isWebGL2;
  9845. let mode;
  9846. function setMode(value) {
  9847. mode = value;
  9848. }
  9849. function render(start, count) {
  9850. gl.drawArrays(mode, start, count);
  9851. info.update(count, mode, 1);
  9852. }
  9853. function renderInstances(start, count, primcount) {
  9854. if (primcount === 0) return;
  9855. let extension, methodName;
  9856. if (isWebGL2) {
  9857. extension = gl;
  9858. methodName = 'drawArraysInstanced';
  9859. } else {
  9860. extension = extensions.get('ANGLE_instanced_arrays');
  9861. methodName = 'drawArraysInstancedANGLE';
  9862. if (extension === null) {
  9863. console.error('THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.');
  9864. return;
  9865. }
  9866. }
  9867. extension[methodName](mode, start, count, primcount);
  9868. info.update(count, mode, primcount);
  9869. } //
  9870. this.setMode = setMode;
  9871. this.render = render;
  9872. this.renderInstances = renderInstances;
  9873. }
  9874. function WebGLCapabilities(gl, extensions, parameters) {
  9875. let maxAnisotropy;
  9876. function getMaxAnisotropy() {
  9877. if (maxAnisotropy !== undefined) return maxAnisotropy;
  9878. if (extensions.has('EXT_texture_filter_anisotropic') === true) {
  9879. const extension = extensions.get('EXT_texture_filter_anisotropic');
  9880. maxAnisotropy = gl.getParameter(extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT);
  9881. } else {
  9882. maxAnisotropy = 0;
  9883. }
  9884. return maxAnisotropy;
  9885. }
  9886. function getMaxPrecision(precision) {
  9887. if (precision === 'highp') {
  9888. if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.HIGH_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision > 0) {
  9889. return 'highp';
  9890. }
  9891. precision = 'mediump';
  9892. }
  9893. if (precision === 'mediump') {
  9894. if (gl.getShaderPrecisionFormat(gl.VERTEX_SHADER, gl.MEDIUM_FLOAT).precision > 0 && gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.MEDIUM_FLOAT).precision > 0) {
  9895. return 'mediump';
  9896. }
  9897. }
  9898. return 'lowp';
  9899. }
  9900. const isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && gl instanceof WebGL2RenderingContext || typeof WebGL2ComputeRenderingContext !== 'undefined' && gl instanceof WebGL2ComputeRenderingContext;
  9901. let precision = parameters.precision !== undefined ? parameters.precision : 'highp';
  9902. const maxPrecision = getMaxPrecision(precision);
  9903. if (maxPrecision !== precision) {
  9904. console.warn('THREE.WebGLRenderer:', precision, 'not supported, using', maxPrecision, 'instead.');
  9905. precision = maxPrecision;
  9906. }
  9907. const drawBuffers = isWebGL2 || extensions.has('WEBGL_draw_buffers');
  9908. const logarithmicDepthBuffer = parameters.logarithmicDepthBuffer === true;
  9909. const maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
  9910. const maxVertexTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
  9911. const maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
  9912. const maxCubemapSize = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
  9913. const maxAttributes = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
  9914. const maxVertexUniforms = gl.getParameter(gl.MAX_VERTEX_UNIFORM_VECTORS);
  9915. const maxVaryings = gl.getParameter(gl.MAX_VARYING_VECTORS);
  9916. const maxFragmentUniforms = gl.getParameter(gl.MAX_FRAGMENT_UNIFORM_VECTORS);
  9917. const vertexTextures = maxVertexTextures > 0;
  9918. const floatFragmentTextures = isWebGL2 || extensions.has('OES_texture_float');
  9919. const floatVertexTextures = vertexTextures && floatFragmentTextures;
  9920. const maxSamples = isWebGL2 ? gl.getParameter(gl.MAX_SAMPLES) : 0;
  9921. return {
  9922. isWebGL2: isWebGL2,
  9923. drawBuffers: drawBuffers,
  9924. getMaxAnisotropy: getMaxAnisotropy,
  9925. getMaxPrecision: getMaxPrecision,
  9926. precision: precision,
  9927. logarithmicDepthBuffer: logarithmicDepthBuffer,
  9928. maxTextures: maxTextures,
  9929. maxVertexTextures: maxVertexTextures,
  9930. maxTextureSize: maxTextureSize,
  9931. maxCubemapSize: maxCubemapSize,
  9932. maxAttributes: maxAttributes,
  9933. maxVertexUniforms: maxVertexUniforms,
  9934. maxVaryings: maxVaryings,
  9935. maxFragmentUniforms: maxFragmentUniforms,
  9936. vertexTextures: vertexTextures,
  9937. floatFragmentTextures: floatFragmentTextures,
  9938. floatVertexTextures: floatVertexTextures,
  9939. maxSamples: maxSamples
  9940. };
  9941. }
  9942. function WebGLClipping(properties) {
  9943. const scope = this;
  9944. let globalState = null,
  9945. numGlobalPlanes = 0,
  9946. localClippingEnabled = false,
  9947. renderingShadows = false;
  9948. const plane = new Plane(),
  9949. viewNormalMatrix = new Matrix3(),
  9950. uniform = {
  9951. value: null,
  9952. needsUpdate: false
  9953. };
  9954. this.uniform = uniform;
  9955. this.numPlanes = 0;
  9956. this.numIntersection = 0;
  9957. this.init = function (planes, enableLocalClipping, camera) {
  9958. const enabled = planes.length !== 0 || enableLocalClipping || // enable state of previous frame - the clipping code has to
  9959. // run another frame in order to reset the state:
  9960. numGlobalPlanes !== 0 || localClippingEnabled;
  9961. localClippingEnabled = enableLocalClipping;
  9962. globalState = projectPlanes(planes, camera, 0);
  9963. numGlobalPlanes = planes.length;
  9964. return enabled;
  9965. };
  9966. this.beginShadows = function () {
  9967. renderingShadows = true;
  9968. projectPlanes(null);
  9969. };
  9970. this.endShadows = function () {
  9971. renderingShadows = false;
  9972. resetGlobalState();
  9973. };
  9974. this.setState = function (material, camera, useCache) {
  9975. const planes = material.clippingPlanes,
  9976. clipIntersection = material.clipIntersection,
  9977. clipShadows = material.clipShadows;
  9978. const materialProperties = properties.get(material);
  9979. if (!localClippingEnabled || planes === null || planes.length === 0 || renderingShadows && !clipShadows) {
  9980. // there's no local clipping
  9981. if (renderingShadows) {
  9982. // there's no global clipping
  9983. projectPlanes(null);
  9984. } else {
  9985. resetGlobalState();
  9986. }
  9987. } else {
  9988. const nGlobal = renderingShadows ? 0 : numGlobalPlanes,
  9989. lGlobal = nGlobal * 4;
  9990. let dstArray = materialProperties.clippingState || null;
  9991. uniform.value = dstArray; // ensure unique state
  9992. dstArray = projectPlanes(planes, camera, lGlobal, useCache);
  9993. for (let i = 0; i !== lGlobal; ++i) {
  9994. dstArray[i] = globalState[i];
  9995. }
  9996. materialProperties.clippingState = dstArray;
  9997. this.numIntersection = clipIntersection ? this.numPlanes : 0;
  9998. this.numPlanes += nGlobal;
  9999. }
  10000. };
  10001. function resetGlobalState() {
  10002. if (uniform.value !== globalState) {
  10003. uniform.value = globalState;
  10004. uniform.needsUpdate = numGlobalPlanes > 0;
  10005. }
  10006. scope.numPlanes = numGlobalPlanes;
  10007. scope.numIntersection = 0;
  10008. }
  10009. function projectPlanes(planes, camera, dstOffset, skipTransform) {
  10010. const nPlanes = planes !== null ? planes.length : 0;
  10011. let dstArray = null;
  10012. if (nPlanes !== 0) {
  10013. dstArray = uniform.value;
  10014. if (skipTransform !== true || dstArray === null) {
  10015. const flatSize = dstOffset + nPlanes * 4,
  10016. viewMatrix = camera.matrixWorldInverse;
  10017. viewNormalMatrix.getNormalMatrix(viewMatrix);
  10018. if (dstArray === null || dstArray.length < flatSize) {
  10019. dstArray = new Float32Array(flatSize);
  10020. }
  10021. for (let i = 0, i4 = dstOffset; i !== nPlanes; ++i, i4 += 4) {
  10022. plane.copy(planes[i]).applyMatrix4(viewMatrix, viewNormalMatrix);
  10023. plane.normal.toArray(dstArray, i4);
  10024. dstArray[i4 + 3] = plane.constant;
  10025. }
  10026. }
  10027. uniform.value = dstArray;
  10028. uniform.needsUpdate = true;
  10029. }
  10030. scope.numPlanes = nPlanes;
  10031. scope.numIntersection = 0;
  10032. return dstArray;
  10033. }
  10034. }
  10035. function WebGLCubeMaps(renderer) {
  10036. let cubemaps = new WeakMap();
  10037. function mapTextureMapping(texture, mapping) {
  10038. if (mapping === EquirectangularReflectionMapping) {
  10039. texture.mapping = CubeReflectionMapping;
  10040. } else if (mapping === EquirectangularRefractionMapping) {
  10041. texture.mapping = CubeRefractionMapping;
  10042. }
  10043. return texture;
  10044. }
  10045. function get(texture) {
  10046. if (texture && texture.isTexture && texture.isRenderTargetTexture === false) {
  10047. const mapping = texture.mapping;
  10048. if (mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping) {
  10049. if (cubemaps.has(texture)) {
  10050. const cubemap = cubemaps.get(texture).texture;
  10051. return mapTextureMapping(cubemap, texture.mapping);
  10052. } else {
  10053. const image = texture.image;
  10054. if (image && image.height > 0) {
  10055. const renderTarget = new WebGLCubeRenderTarget(image.height / 2);
  10056. renderTarget.fromEquirectangularTexture(renderer, texture);
  10057. cubemaps.set(texture, renderTarget);
  10058. texture.addEventListener('dispose', onTextureDispose);
  10059. return mapTextureMapping(renderTarget.texture, texture.mapping);
  10060. } else {
  10061. // image not yet ready. try the conversion next frame
  10062. return null;
  10063. }
  10064. }
  10065. }
  10066. }
  10067. return texture;
  10068. }
  10069. function onTextureDispose(event) {
  10070. const texture = event.target;
  10071. texture.removeEventListener('dispose', onTextureDispose);
  10072. const cubemap = cubemaps.get(texture);
  10073. if (cubemap !== undefined) {
  10074. cubemaps.delete(texture);
  10075. cubemap.dispose();
  10076. }
  10077. }
  10078. function dispose() {
  10079. cubemaps = new WeakMap();
  10080. }
  10081. return {
  10082. get: get,
  10083. dispose: dispose
  10084. };
  10085. }
  10086. class OrthographicCamera extends Camera {
  10087. constructor(left = -1, right = 1, top = 1, bottom = -1, near = 0.1, far = 2000) {
  10088. super();
  10089. this.isOrthographicCamera = true;
  10090. this.type = 'OrthographicCamera';
  10091. this.zoom = 1;
  10092. this.view = null;
  10093. this.left = left;
  10094. this.right = right;
  10095. this.top = top;
  10096. this.bottom = bottom;
  10097. this.near = near;
  10098. this.far = far;
  10099. this.updateProjectionMatrix();
  10100. }
  10101. copy(source, recursive) {
  10102. super.copy(source, recursive);
  10103. this.left = source.left;
  10104. this.right = source.right;
  10105. this.top = source.top;
  10106. this.bottom = source.bottom;
  10107. this.near = source.near;
  10108. this.far = source.far;
  10109. this.zoom = source.zoom;
  10110. this.view = source.view === null ? null : Object.assign({}, source.view);
  10111. return this;
  10112. }
  10113. setViewOffset(fullWidth, fullHeight, x, y, width, height) {
  10114. if (this.view === null) {
  10115. this.view = {
  10116. enabled: true,
  10117. fullWidth: 1,
  10118. fullHeight: 1,
  10119. offsetX: 0,
  10120. offsetY: 0,
  10121. width: 1,
  10122. height: 1
  10123. };
  10124. }
  10125. this.view.enabled = true;
  10126. this.view.fullWidth = fullWidth;
  10127. this.view.fullHeight = fullHeight;
  10128. this.view.offsetX = x;
  10129. this.view.offsetY = y;
  10130. this.view.width = width;
  10131. this.view.height = height;
  10132. this.updateProjectionMatrix();
  10133. }
  10134. clearViewOffset() {
  10135. if (this.view !== null) {
  10136. this.view.enabled = false;
  10137. }
  10138. this.updateProjectionMatrix();
  10139. }
  10140. updateProjectionMatrix() {
  10141. const dx = (this.right - this.left) / (2 * this.zoom);
  10142. const dy = (this.top - this.bottom) / (2 * this.zoom);
  10143. const cx = (this.right + this.left) / 2;
  10144. const cy = (this.top + this.bottom) / 2;
  10145. let left = cx - dx;
  10146. let right = cx + dx;
  10147. let top = cy + dy;
  10148. let bottom = cy - dy;
  10149. if (this.view !== null && this.view.enabled) {
  10150. const scaleW = (this.right - this.left) / this.view.fullWidth / this.zoom;
  10151. const scaleH = (this.top - this.bottom) / this.view.fullHeight / this.zoom;
  10152. left += scaleW * this.view.offsetX;
  10153. right = left + scaleW * this.view.width;
  10154. top -= scaleH * this.view.offsetY;
  10155. bottom = top - scaleH * this.view.height;
  10156. }
  10157. this.projectionMatrix.makeOrthographic(left, right, top, bottom, this.near, this.far);
  10158. this.projectionMatrixInverse.copy(this.projectionMatrix).invert();
  10159. }
  10160. toJSON(meta) {
  10161. const data = super.toJSON(meta);
  10162. data.object.zoom = this.zoom;
  10163. data.object.left = this.left;
  10164. data.object.right = this.right;
  10165. data.object.top = this.top;
  10166. data.object.bottom = this.bottom;
  10167. data.object.near = this.near;
  10168. data.object.far = this.far;
  10169. if (this.view !== null) data.object.view = Object.assign({}, this.view);
  10170. return data;
  10171. }
  10172. }
  10173. const LOD_MIN = 4; // The standard deviations (radians) associated with the extra mips. These are
  10174. // chosen to approximate a Trowbridge-Reitz distribution function times the
  10175. // geometric shadowing function. These sigma values squared must match the
  10176. // variance #defines in cube_uv_reflection_fragment.glsl.js.
  10177. const EXTRA_LOD_SIGMA = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; // The maximum length of the blur for loop. Smaller sigmas will use fewer
  10178. // samples and exit early, but not recompile the shader.
  10179. const MAX_SAMPLES = 20;
  10180. const _flatCamera = /*@__PURE__*/new OrthographicCamera();
  10181. const _clearColor = /*@__PURE__*/new Color();
  10182. let _oldTarget = null; // Golden Ratio
  10183. const PHI = (1 + Math.sqrt(5)) / 2;
  10184. const INV_PHI = 1 / PHI; // Vertices of a dodecahedron (except the opposites, which represent the
  10185. // same axis), used as axis directions evenly spread on a sphere.
  10186. const _axisDirections = [/*@__PURE__*/new Vector3(1, 1, 1), /*@__PURE__*/new Vector3(-1, 1, 1), /*@__PURE__*/new Vector3(1, 1, -1), /*@__PURE__*/new Vector3(-1, 1, -1), /*@__PURE__*/new Vector3(0, PHI, INV_PHI), /*@__PURE__*/new Vector3(0, PHI, -INV_PHI), /*@__PURE__*/new Vector3(INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(-INV_PHI, 0, PHI), /*@__PURE__*/new Vector3(PHI, INV_PHI, 0), /*@__PURE__*/new Vector3(-PHI, INV_PHI, 0)];
  10187. /**
  10188. * This class generates a Prefiltered, Mipmapped Radiance Environment Map
  10189. * (PMREM) from a cubeMap environment texture. This allows different levels of
  10190. * blur to be quickly accessed based on material roughness. It is packed into a
  10191. * special CubeUV format that allows us to perform custom interpolation so that
  10192. * we can support nonlinear formats such as RGBE. Unlike a traditional mipmap
  10193. * chain, it only goes down to the LOD_MIN level (above), and then creates extra
  10194. * even more filtered 'mips' at the same LOD_MIN resolution, associated with
  10195. * higher roughness levels. In this way we maintain resolution to smoothly
  10196. * interpolate diffuse lighting while limiting sampling computation.
  10197. *
  10198. * Paper: Fast, Accurate Image-Based Lighting
  10199. * https://drive.google.com/file/d/15y8r_UpKlU9SvV4ILb0C3qCPecS8pvLz/view
  10200. */
  10201. class PMREMGenerator {
  10202. constructor(renderer) {
  10203. this._renderer = renderer;
  10204. this._pingPongRenderTarget = null;
  10205. this._lodMax = 0;
  10206. this._cubeSize = 0;
  10207. this._lodPlanes = [];
  10208. this._sizeLods = [];
  10209. this._sigmas = [];
  10210. this._blurMaterial = null;
  10211. this._cubemapMaterial = null;
  10212. this._equirectMaterial = null;
  10213. this._compileMaterial(this._blurMaterial);
  10214. }
  10215. /**
  10216. * Generates a PMREM from a supplied Scene, which can be faster than using an
  10217. * image if networking bandwidth is low. Optional sigma specifies a blur radius
  10218. * in radians to be applied to the scene before PMREM generation. Optional near
  10219. * and far planes ensure the scene is rendered in its entirety (the cubeCamera
  10220. * is placed at the origin).
  10221. */
  10222. fromScene(scene, sigma = 0, near = 0.1, far = 100) {
  10223. _oldTarget = this._renderer.getRenderTarget();
  10224. this._setSize(256);
  10225. const cubeUVRenderTarget = this._allocateTargets();
  10226. cubeUVRenderTarget.depthBuffer = true;
  10227. this._sceneToCubeUV(scene, near, far, cubeUVRenderTarget);
  10228. if (sigma > 0) {
  10229. this._blur(cubeUVRenderTarget, 0, 0, sigma);
  10230. }
  10231. this._applyPMREM(cubeUVRenderTarget);
  10232. this._cleanup(cubeUVRenderTarget);
  10233. return cubeUVRenderTarget;
  10234. }
  10235. /**
  10236. * Generates a PMREM from an equirectangular texture, which can be either LDR
  10237. * or HDR. The ideal input image size is 1k (1024 x 512),
  10238. * as this matches best with the 256 x 256 cubemap output.
  10239. */
  10240. fromEquirectangular(equirectangular, renderTarget = null) {
  10241. return this._fromTexture(equirectangular, renderTarget);
  10242. }
  10243. /**
  10244. * Generates a PMREM from an cubemap texture, which can be either LDR
  10245. * or HDR. The ideal input cube size is 256 x 256,
  10246. * as this matches best with the 256 x 256 cubemap output.
  10247. */
  10248. fromCubemap(cubemap, renderTarget = null) {
  10249. return this._fromTexture(cubemap, renderTarget);
  10250. }
  10251. /**
  10252. * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during
  10253. * your texture's network fetch for increased concurrency.
  10254. */
  10255. compileCubemapShader() {
  10256. if (this._cubemapMaterial === null) {
  10257. this._cubemapMaterial = _getCubemapMaterial();
  10258. this._compileMaterial(this._cubemapMaterial);
  10259. }
  10260. }
  10261. /**
  10262. * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during
  10263. * your texture's network fetch for increased concurrency.
  10264. */
  10265. compileEquirectangularShader() {
  10266. if (this._equirectMaterial === null) {
  10267. this._equirectMaterial = _getEquirectMaterial();
  10268. this._compileMaterial(this._equirectMaterial);
  10269. }
  10270. }
  10271. /**
  10272. * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class,
  10273. * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on
  10274. * one of them will cause any others to also become unusable.
  10275. */
  10276. dispose() {
  10277. this._dispose();
  10278. if (this._cubemapMaterial !== null) this._cubemapMaterial.dispose();
  10279. if (this._equirectMaterial !== null) this._equirectMaterial.dispose();
  10280. } // private interface
  10281. _setSize(cubeSize) {
  10282. this._lodMax = Math.floor(Math.log2(cubeSize));
  10283. this._cubeSize = Math.pow(2, this._lodMax);
  10284. }
  10285. _dispose() {
  10286. if (this._blurMaterial !== null) this._blurMaterial.dispose();
  10287. if (this._pingPongRenderTarget !== null) this._pingPongRenderTarget.dispose();
  10288. for (let i = 0; i < this._lodPlanes.length; i++) {
  10289. this._lodPlanes[i].dispose();
  10290. }
  10291. }
  10292. _cleanup(outputTarget) {
  10293. this._renderer.setRenderTarget(_oldTarget);
  10294. outputTarget.scissorTest = false;
  10295. _setViewport(outputTarget, 0, 0, outputTarget.width, outputTarget.height);
  10296. }
  10297. _fromTexture(texture, renderTarget) {
  10298. if (texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping) {
  10299. this._setSize(texture.image.length === 0 ? 16 : texture.image[0].width || texture.image[0].image.width);
  10300. } else {
  10301. // Equirectangular
  10302. this._setSize(texture.image.width / 4);
  10303. }
  10304. _oldTarget = this._renderer.getRenderTarget();
  10305. const cubeUVRenderTarget = renderTarget || this._allocateTargets();
  10306. this._textureToCubeUV(texture, cubeUVRenderTarget);
  10307. this._applyPMREM(cubeUVRenderTarget);
  10308. this._cleanup(cubeUVRenderTarget);
  10309. return cubeUVRenderTarget;
  10310. }
  10311. _allocateTargets() {
  10312. const width = 3 * Math.max(this._cubeSize, 16 * 7);
  10313. const height = 4 * this._cubeSize;
  10314. const params = {
  10315. magFilter: LinearFilter,
  10316. minFilter: LinearFilter,
  10317. generateMipmaps: false,
  10318. type: HalfFloatType,
  10319. format: RGBAFormat,
  10320. encoding: LinearEncoding,
  10321. depthBuffer: false
  10322. };
  10323. const cubeUVRenderTarget = _createRenderTarget(width, height, params);
  10324. if (this._pingPongRenderTarget === null || this._pingPongRenderTarget.width !== width) {
  10325. if (this._pingPongRenderTarget !== null) {
  10326. this._dispose();
  10327. }
  10328. this._pingPongRenderTarget = _createRenderTarget(width, height, params);
  10329. const {
  10330. _lodMax
  10331. } = this;
  10332. ({
  10333. sizeLods: this._sizeLods,
  10334. lodPlanes: this._lodPlanes,
  10335. sigmas: this._sigmas
  10336. } = _createPlanes(_lodMax));
  10337. this._blurMaterial = _getBlurShader(_lodMax, width, height);
  10338. }
  10339. return cubeUVRenderTarget;
  10340. }
  10341. _compileMaterial(material) {
  10342. const tmpMesh = new Mesh(this._lodPlanes[0], material);
  10343. this._renderer.compile(tmpMesh, _flatCamera);
  10344. }
  10345. _sceneToCubeUV(scene, near, far, cubeUVRenderTarget) {
  10346. const fov = 90;
  10347. const aspect = 1;
  10348. const cubeCamera = new PerspectiveCamera(fov, aspect, near, far);
  10349. const upSign = [1, -1, 1, 1, 1, 1];
  10350. const forwardSign = [1, 1, 1, -1, -1, -1];
  10351. const renderer = this._renderer;
  10352. const originalAutoClear = renderer.autoClear;
  10353. const toneMapping = renderer.toneMapping;
  10354. renderer.getClearColor(_clearColor);
  10355. renderer.toneMapping = NoToneMapping;
  10356. renderer.autoClear = false;
  10357. const backgroundMaterial = new MeshBasicMaterial({
  10358. name: 'PMREM.Background',
  10359. side: BackSide,
  10360. depthWrite: false,
  10361. depthTest: false
  10362. });
  10363. const backgroundBox = new Mesh(new BoxGeometry(), backgroundMaterial);
  10364. let useSolidColor = false;
  10365. const background = scene.background;
  10366. if (background) {
  10367. if (background.isColor) {
  10368. backgroundMaterial.color.copy(background);
  10369. scene.background = null;
  10370. useSolidColor = true;
  10371. }
  10372. } else {
  10373. backgroundMaterial.color.copy(_clearColor);
  10374. useSolidColor = true;
  10375. }
  10376. for (let i = 0; i < 6; i++) {
  10377. const col = i % 3;
  10378. if (col === 0) {
  10379. cubeCamera.up.set(0, upSign[i], 0);
  10380. cubeCamera.lookAt(forwardSign[i], 0, 0);
  10381. } else if (col === 1) {
  10382. cubeCamera.up.set(0, 0, upSign[i]);
  10383. cubeCamera.lookAt(0, forwardSign[i], 0);
  10384. } else {
  10385. cubeCamera.up.set(0, upSign[i], 0);
  10386. cubeCamera.lookAt(0, 0, forwardSign[i]);
  10387. }
  10388. const size = this._cubeSize;
  10389. _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size);
  10390. renderer.setRenderTarget(cubeUVRenderTarget);
  10391. if (useSolidColor) {
  10392. renderer.render(backgroundBox, cubeCamera);
  10393. }
  10394. renderer.render(scene, cubeCamera);
  10395. }
  10396. backgroundBox.geometry.dispose();
  10397. backgroundBox.material.dispose();
  10398. renderer.toneMapping = toneMapping;
  10399. renderer.autoClear = originalAutoClear;
  10400. scene.background = background;
  10401. }
  10402. _textureToCubeUV(texture, cubeUVRenderTarget) {
  10403. const renderer = this._renderer;
  10404. const isCubeTexture = texture.mapping === CubeReflectionMapping || texture.mapping === CubeRefractionMapping;
  10405. if (isCubeTexture) {
  10406. if (this._cubemapMaterial === null) {
  10407. this._cubemapMaterial = _getCubemapMaterial();
  10408. }
  10409. this._cubemapMaterial.uniforms.flipEnvMap.value = texture.isRenderTargetTexture === false ? -1 : 1;
  10410. } else {
  10411. if (this._equirectMaterial === null) {
  10412. this._equirectMaterial = _getEquirectMaterial();
  10413. }
  10414. }
  10415. const material = isCubeTexture ? this._cubemapMaterial : this._equirectMaterial;
  10416. const mesh = new Mesh(this._lodPlanes[0], material);
  10417. const uniforms = material.uniforms;
  10418. uniforms['envMap'].value = texture;
  10419. const size = this._cubeSize;
  10420. _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size);
  10421. renderer.setRenderTarget(cubeUVRenderTarget);
  10422. renderer.render(mesh, _flatCamera);
  10423. }
  10424. _applyPMREM(cubeUVRenderTarget) {
  10425. const renderer = this._renderer;
  10426. const autoClear = renderer.autoClear;
  10427. renderer.autoClear = false;
  10428. for (let i = 1; i < this._lodPlanes.length; i++) {
  10429. const sigma = Math.sqrt(this._sigmas[i] * this._sigmas[i] - this._sigmas[i - 1] * this._sigmas[i - 1]);
  10430. const poleAxis = _axisDirections[(i - 1) % _axisDirections.length];
  10431. this._blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis);
  10432. }
  10433. renderer.autoClear = autoClear;
  10434. }
  10435. /**
  10436. * This is a two-pass Gaussian blur for a cubemap. Normally this is done
  10437. * vertically and horizontally, but this breaks down on a cube. Here we apply
  10438. * the blur latitudinally (around the poles), and then longitudinally (towards
  10439. * the poles) to approximate the orthogonally-separable blur. It is least
  10440. * accurate at the poles, but still does a decent job.
  10441. */
  10442. _blur(cubeUVRenderTarget, lodIn, lodOut, sigma, poleAxis) {
  10443. const pingPongRenderTarget = this._pingPongRenderTarget;
  10444. this._halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis);
  10445. this._halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma, 'longitudinal', poleAxis);
  10446. }
  10447. _halfBlur(targetIn, targetOut, lodIn, lodOut, sigmaRadians, direction, poleAxis) {
  10448. const renderer = this._renderer;
  10449. const blurMaterial = this._blurMaterial;
  10450. if (direction !== 'latitudinal' && direction !== 'longitudinal') {
  10451. console.error('blur direction must be either latitudinal or longitudinal!');
  10452. } // Number of standard deviations at which to cut off the discrete approximation.
  10453. const STANDARD_DEVIATIONS = 3;
  10454. const blurMesh = new Mesh(this._lodPlanes[lodOut], blurMaterial);
  10455. const blurUniforms = blurMaterial.uniforms;
  10456. const pixels = this._sizeLods[lodIn] - 1;
  10457. const radiansPerPixel = isFinite(sigmaRadians) ? Math.PI / (2 * pixels) : 2 * Math.PI / (2 * MAX_SAMPLES - 1);
  10458. const sigmaPixels = sigmaRadians / radiansPerPixel;
  10459. const samples = isFinite(sigmaRadians) ? 1 + Math.floor(STANDARD_DEVIATIONS * sigmaPixels) : MAX_SAMPLES;
  10460. if (samples > MAX_SAMPLES) {
  10461. console.warn(`sigmaRadians, ${sigmaRadians}, is too large and will clip, as it requested ${samples} samples when the maximum is set to ${MAX_SAMPLES}`);
  10462. }
  10463. const weights = [];
  10464. let sum = 0;
  10465. for (let i = 0; i < MAX_SAMPLES; ++i) {
  10466. const x = i / sigmaPixels;
  10467. const weight = Math.exp(-x * x / 2);
  10468. weights.push(weight);
  10469. if (i === 0) {
  10470. sum += weight;
  10471. } else if (i < samples) {
  10472. sum += 2 * weight;
  10473. }
  10474. }
  10475. for (let i = 0; i < weights.length; i++) {
  10476. weights[i] = weights[i] / sum;
  10477. }
  10478. blurUniforms['envMap'].value = targetIn.texture;
  10479. blurUniforms['samples'].value = samples;
  10480. blurUniforms['weights'].value = weights;
  10481. blurUniforms['latitudinal'].value = direction === 'latitudinal';
  10482. if (poleAxis) {
  10483. blurUniforms['poleAxis'].value = poleAxis;
  10484. }
  10485. const {
  10486. _lodMax
  10487. } = this;
  10488. blurUniforms['dTheta'].value = radiansPerPixel;
  10489. blurUniforms['mipInt'].value = _lodMax - lodIn;
  10490. const outputSize = this._sizeLods[lodOut];
  10491. const x = 3 * outputSize * (lodOut > _lodMax - LOD_MIN ? lodOut - _lodMax + LOD_MIN : 0);
  10492. const y = 4 * (this._cubeSize - outputSize);
  10493. _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize);
  10494. renderer.setRenderTarget(targetOut);
  10495. renderer.render(blurMesh, _flatCamera);
  10496. }
  10497. }
  10498. function _createPlanes(lodMax) {
  10499. const lodPlanes = [];
  10500. const sizeLods = [];
  10501. const sigmas = [];
  10502. let lod = lodMax;
  10503. const totalLods = lodMax - LOD_MIN + 1 + EXTRA_LOD_SIGMA.length;
  10504. for (let i = 0; i < totalLods; i++) {
  10505. const sizeLod = Math.pow(2, lod);
  10506. sizeLods.push(sizeLod);
  10507. let sigma = 1.0 / sizeLod;
  10508. if (i > lodMax - LOD_MIN) {
  10509. sigma = EXTRA_LOD_SIGMA[i - lodMax + LOD_MIN - 1];
  10510. } else if (i === 0) {
  10511. sigma = 0;
  10512. }
  10513. sigmas.push(sigma);
  10514. const texelSize = 1.0 / (sizeLod - 2);
  10515. const min = -texelSize;
  10516. const max = 1 + texelSize;
  10517. const uv1 = [min, min, max, min, max, max, min, min, max, max, min, max];
  10518. const cubeFaces = 6;
  10519. const vertices = 6;
  10520. const positionSize = 3;
  10521. const uvSize = 2;
  10522. const faceIndexSize = 1;
  10523. const position = new Float32Array(positionSize * vertices * cubeFaces);
  10524. const uv = new Float32Array(uvSize * vertices * cubeFaces);
  10525. const faceIndex = new Float32Array(faceIndexSize * vertices * cubeFaces);
  10526. for (let face = 0; face < cubeFaces; face++) {
  10527. const x = face % 3 * 2 / 3 - 1;
  10528. const y = face > 2 ? 0 : -1;
  10529. const coordinates = [x, y, 0, x + 2 / 3, y, 0, x + 2 / 3, y + 1, 0, x, y, 0, x + 2 / 3, y + 1, 0, x, y + 1, 0];
  10530. position.set(coordinates, positionSize * vertices * face);
  10531. uv.set(uv1, uvSize * vertices * face);
  10532. const fill = [face, face, face, face, face, face];
  10533. faceIndex.set(fill, faceIndexSize * vertices * face);
  10534. }
  10535. const planes = new BufferGeometry();
  10536. planes.setAttribute('position', new BufferAttribute(position, positionSize));
  10537. planes.setAttribute('uv', new BufferAttribute(uv, uvSize));
  10538. planes.setAttribute('faceIndex', new BufferAttribute(faceIndex, faceIndexSize));
  10539. lodPlanes.push(planes);
  10540. if (lod > LOD_MIN) {
  10541. lod--;
  10542. }
  10543. }
  10544. return {
  10545. lodPlanes,
  10546. sizeLods,
  10547. sigmas
  10548. };
  10549. }
  10550. function _createRenderTarget(width, height, params) {
  10551. const cubeUVRenderTarget = new WebGLRenderTarget(width, height, params);
  10552. cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping;
  10553. cubeUVRenderTarget.texture.name = 'PMREM.cubeUv';
  10554. cubeUVRenderTarget.scissorTest = true;
  10555. return cubeUVRenderTarget;
  10556. }
  10557. function _setViewport(target, x, y, width, height) {
  10558. target.viewport.set(x, y, width, height);
  10559. target.scissor.set(x, y, width, height);
  10560. }
  10561. function _getBlurShader(lodMax, width, height) {
  10562. const weights = new Float32Array(MAX_SAMPLES);
  10563. const poleAxis = new Vector3(0, 1, 0);
  10564. const shaderMaterial = new ShaderMaterial({
  10565. name: 'SphericalGaussianBlur',
  10566. defines: {
  10567. 'n': MAX_SAMPLES,
  10568. 'CUBEUV_TEXEL_WIDTH': 1.0 / width,
  10569. 'CUBEUV_TEXEL_HEIGHT': 1.0 / height,
  10570. 'CUBEUV_MAX_MIP': `${lodMax}.0`
  10571. },
  10572. uniforms: {
  10573. 'envMap': {
  10574. value: null
  10575. },
  10576. 'samples': {
  10577. value: 1
  10578. },
  10579. 'weights': {
  10580. value: weights
  10581. },
  10582. 'latitudinal': {
  10583. value: false
  10584. },
  10585. 'dTheta': {
  10586. value: 0
  10587. },
  10588. 'mipInt': {
  10589. value: 0
  10590. },
  10591. 'poleAxis': {
  10592. value: poleAxis
  10593. }
  10594. },
  10595. vertexShader: _getCommonVertexShader(),
  10596. fragmentShader:
  10597. /* glsl */
  10598. `
  10599. precision mediump float;
  10600. precision mediump int;
  10601. varying vec3 vOutputDirection;
  10602. uniform sampler2D envMap;
  10603. uniform int samples;
  10604. uniform float weights[ n ];
  10605. uniform bool latitudinal;
  10606. uniform float dTheta;
  10607. uniform float mipInt;
  10608. uniform vec3 poleAxis;
  10609. #define ENVMAP_TYPE_CUBE_UV
  10610. #include <cube_uv_reflection_fragment>
  10611. vec3 getSample( float theta, vec3 axis ) {
  10612. float cosTheta = cos( theta );
  10613. // Rodrigues' axis-angle rotation
  10614. vec3 sampleDirection = vOutputDirection * cosTheta
  10615. + cross( axis, vOutputDirection ) * sin( theta )
  10616. + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );
  10617. return bilinearCubeUV( envMap, sampleDirection, mipInt );
  10618. }
  10619. void main() {
  10620. vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );
  10621. if ( all( equal( axis, vec3( 0.0 ) ) ) ) {
  10622. axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );
  10623. }
  10624. axis = normalize( axis );
  10625. gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
  10626. gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );
  10627. for ( int i = 1; i < n; i++ ) {
  10628. if ( i >= samples ) {
  10629. break;
  10630. }
  10631. float theta = dTheta * float( i );
  10632. gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );
  10633. gl_FragColor.rgb += weights[ i ] * getSample( theta, axis );
  10634. }
  10635. }
  10636. `,
  10637. blending: NoBlending,
  10638. depthTest: false,
  10639. depthWrite: false
  10640. });
  10641. return shaderMaterial;
  10642. }
  10643. function _getEquirectMaterial() {
  10644. return new ShaderMaterial({
  10645. name: 'EquirectangularToCubeUV',
  10646. uniforms: {
  10647. 'envMap': {
  10648. value: null
  10649. }
  10650. },
  10651. vertexShader: _getCommonVertexShader(),
  10652. fragmentShader:
  10653. /* glsl */
  10654. `
  10655. precision mediump float;
  10656. precision mediump int;
  10657. varying vec3 vOutputDirection;
  10658. uniform sampler2D envMap;
  10659. #include <common>
  10660. void main() {
  10661. vec3 outputDirection = normalize( vOutputDirection );
  10662. vec2 uv = equirectUv( outputDirection );
  10663. gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );
  10664. }
  10665. `,
  10666. blending: NoBlending,
  10667. depthTest: false,
  10668. depthWrite: false
  10669. });
  10670. }
  10671. function _getCubemapMaterial() {
  10672. return new ShaderMaterial({
  10673. name: 'CubemapToCubeUV',
  10674. uniforms: {
  10675. 'envMap': {
  10676. value: null
  10677. },
  10678. 'flipEnvMap': {
  10679. value: -1
  10680. }
  10681. },
  10682. vertexShader: _getCommonVertexShader(),
  10683. fragmentShader:
  10684. /* glsl */
  10685. `
  10686. precision mediump float;
  10687. precision mediump int;
  10688. uniform float flipEnvMap;
  10689. varying vec3 vOutputDirection;
  10690. uniform samplerCube envMap;
  10691. void main() {
  10692. gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );
  10693. }
  10694. `,
  10695. blending: NoBlending,
  10696. depthTest: false,
  10697. depthWrite: false
  10698. });
  10699. }
  10700. function _getCommonVertexShader() {
  10701. return (
  10702. /* glsl */
  10703. `
  10704. precision mediump float;
  10705. precision mediump int;
  10706. attribute float faceIndex;
  10707. varying vec3 vOutputDirection;
  10708. // RH coordinate system; PMREM face-indexing convention
  10709. vec3 getDirection( vec2 uv, float face ) {
  10710. uv = 2.0 * uv - 1.0;
  10711. vec3 direction = vec3( uv, 1.0 );
  10712. if ( face == 0.0 ) {
  10713. direction = direction.zyx; // ( 1, v, u ) pos x
  10714. } else if ( face == 1.0 ) {
  10715. direction = direction.xzy;
  10716. direction.xz *= -1.0; // ( -u, 1, -v ) pos y
  10717. } else if ( face == 2.0 ) {
  10718. direction.x *= -1.0; // ( -u, v, 1 ) pos z
  10719. } else if ( face == 3.0 ) {
  10720. direction = direction.zyx;
  10721. direction.xz *= -1.0; // ( -1, v, -u ) neg x
  10722. } else if ( face == 4.0 ) {
  10723. direction = direction.xzy;
  10724. direction.xy *= -1.0; // ( -u, -1, v ) neg y
  10725. } else if ( face == 5.0 ) {
  10726. direction.z *= -1.0; // ( u, v, -1 ) neg z
  10727. }
  10728. return direction;
  10729. }
  10730. void main() {
  10731. vOutputDirection = getDirection( uv, faceIndex );
  10732. gl_Position = vec4( position, 1.0 );
  10733. }
  10734. `
  10735. );
  10736. }
  10737. function WebGLCubeUVMaps(renderer) {
  10738. let cubeUVmaps = new WeakMap();
  10739. let pmremGenerator = null;
  10740. function get(texture) {
  10741. if (texture && texture.isTexture) {
  10742. const mapping = texture.mapping;
  10743. const isEquirectMap = mapping === EquirectangularReflectionMapping || mapping === EquirectangularRefractionMapping;
  10744. const isCubeMap = mapping === CubeReflectionMapping || mapping === CubeRefractionMapping; // equirect/cube map to cubeUV conversion
  10745. if (isEquirectMap || isCubeMap) {
  10746. if (texture.isRenderTargetTexture && texture.needsPMREMUpdate === true) {
  10747. texture.needsPMREMUpdate = false;
  10748. let renderTarget = cubeUVmaps.get(texture);
  10749. if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);
  10750. renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture, renderTarget) : pmremGenerator.fromCubemap(texture, renderTarget);
  10751. cubeUVmaps.set(texture, renderTarget);
  10752. return renderTarget.texture;
  10753. } else {
  10754. if (cubeUVmaps.has(texture)) {
  10755. return cubeUVmaps.get(texture).texture;
  10756. } else {
  10757. const image = texture.image;
  10758. if (isEquirectMap && image && image.height > 0 || isCubeMap && image && isCubeTextureComplete(image)) {
  10759. if (pmremGenerator === null) pmremGenerator = new PMREMGenerator(renderer);
  10760. const renderTarget = isEquirectMap ? pmremGenerator.fromEquirectangular(texture) : pmremGenerator.fromCubemap(texture);
  10761. cubeUVmaps.set(texture, renderTarget);
  10762. texture.addEventListener('dispose', onTextureDispose);
  10763. return renderTarget.texture;
  10764. } else {
  10765. // image not yet ready. try the conversion next frame
  10766. return null;
  10767. }
  10768. }
  10769. }
  10770. }
  10771. }
  10772. return texture;
  10773. }
  10774. function isCubeTextureComplete(image) {
  10775. let count = 0;
  10776. const length = 6;
  10777. for (let i = 0; i < length; i++) {
  10778. if (image[i] !== undefined) count++;
  10779. }
  10780. return count === length;
  10781. }
  10782. function onTextureDispose(event) {
  10783. const texture = event.target;
  10784. texture.removeEventListener('dispose', onTextureDispose);
  10785. const cubemapUV = cubeUVmaps.get(texture);
  10786. if (cubemapUV !== undefined) {
  10787. cubeUVmaps.delete(texture);
  10788. cubemapUV.dispose();
  10789. }
  10790. }
  10791. function dispose() {
  10792. cubeUVmaps = new WeakMap();
  10793. if (pmremGenerator !== null) {
  10794. pmremGenerator.dispose();
  10795. pmremGenerator = null;
  10796. }
  10797. }
  10798. return {
  10799. get: get,
  10800. dispose: dispose
  10801. };
  10802. }
  10803. function WebGLExtensions(gl) {
  10804. const extensions = {};
  10805. function getExtension(name) {
  10806. if (extensions[name] !== undefined) {
  10807. return extensions[name];
  10808. }
  10809. let extension;
  10810. switch (name) {
  10811. case 'WEBGL_depth_texture':
  10812. extension = gl.getExtension('WEBGL_depth_texture') || gl.getExtension('MOZ_WEBGL_depth_texture') || gl.getExtension('WEBKIT_WEBGL_depth_texture');
  10813. break;
  10814. case 'EXT_texture_filter_anisotropic':
  10815. extension = gl.getExtension('EXT_texture_filter_anisotropic') || gl.getExtension('MOZ_EXT_texture_filter_anisotropic') || gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic');
  10816. break;
  10817. case 'WEBGL_compressed_texture_s3tc':
  10818. extension = gl.getExtension('WEBGL_compressed_texture_s3tc') || gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc');
  10819. break;
  10820. case 'WEBGL_compressed_texture_pvrtc':
  10821. extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') || gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
  10822. break;
  10823. default:
  10824. extension = gl.getExtension(name);
  10825. }
  10826. extensions[name] = extension;
  10827. return extension;
  10828. }
  10829. return {
  10830. has: function (name) {
  10831. return getExtension(name) !== null;
  10832. },
  10833. init: function (capabilities) {
  10834. if (capabilities.isWebGL2) {
  10835. getExtension('EXT_color_buffer_float');
  10836. } else {
  10837. getExtension('WEBGL_depth_texture');
  10838. getExtension('OES_texture_float');
  10839. getExtension('OES_texture_half_float');
  10840. getExtension('OES_texture_half_float_linear');
  10841. getExtension('OES_standard_derivatives');
  10842. getExtension('OES_element_index_uint');
  10843. getExtension('OES_vertex_array_object');
  10844. getExtension('ANGLE_instanced_arrays');
  10845. }
  10846. getExtension('OES_texture_float_linear');
  10847. getExtension('EXT_color_buffer_half_float');
  10848. getExtension('WEBGL_multisampled_render_to_texture');
  10849. },
  10850. get: function (name) {
  10851. const extension = getExtension(name);
  10852. if (extension === null) {
  10853. console.warn('THREE.WebGLRenderer: ' + name + ' extension not supported.');
  10854. }
  10855. return extension;
  10856. }
  10857. };
  10858. }
  10859. function WebGLGeometries(gl, attributes, info, bindingStates) {
  10860. const geometries = {};
  10861. const wireframeAttributes = new WeakMap();
  10862. function onGeometryDispose(event) {
  10863. const geometry = event.target;
  10864. if (geometry.index !== null) {
  10865. attributes.remove(geometry.index);
  10866. }
  10867. for (const name in geometry.attributes) {
  10868. attributes.remove(geometry.attributes[name]);
  10869. }
  10870. geometry.removeEventListener('dispose', onGeometryDispose);
  10871. delete geometries[geometry.id];
  10872. const attribute = wireframeAttributes.get(geometry);
  10873. if (attribute) {
  10874. attributes.remove(attribute);
  10875. wireframeAttributes.delete(geometry);
  10876. }
  10877. bindingStates.releaseStatesOfGeometry(geometry);
  10878. if (geometry.isInstancedBufferGeometry === true) {
  10879. delete geometry._maxInstanceCount;
  10880. } //
  10881. info.memory.geometries--;
  10882. }
  10883. function get(object, geometry) {
  10884. if (geometries[geometry.id] === true) return geometry;
  10885. geometry.addEventListener('dispose', onGeometryDispose);
  10886. geometries[geometry.id] = true;
  10887. info.memory.geometries++;
  10888. return geometry;
  10889. }
  10890. function update(geometry) {
  10891. const geometryAttributes = geometry.attributes; // Updating index buffer in VAO now. See WebGLBindingStates.
  10892. for (const name in geometryAttributes) {
  10893. attributes.update(geometryAttributes[name], gl.ARRAY_BUFFER);
  10894. } // morph targets
  10895. const morphAttributes = geometry.morphAttributes;
  10896. for (const name in morphAttributes) {
  10897. const array = morphAttributes[name];
  10898. for (let i = 0, l = array.length; i < l; i++) {
  10899. attributes.update(array[i], gl.ARRAY_BUFFER);
  10900. }
  10901. }
  10902. }
  10903. function updateWireframeAttribute(geometry) {
  10904. const indices = [];
  10905. const geometryIndex = geometry.index;
  10906. const geometryPosition = geometry.attributes.position;
  10907. let version = 0;
  10908. if (geometryIndex !== null) {
  10909. const array = geometryIndex.array;
  10910. version = geometryIndex.version;
  10911. for (let i = 0, l = array.length; i < l; i += 3) {
  10912. const a = array[i + 0];
  10913. const b = array[i + 1];
  10914. const c = array[i + 2];
  10915. indices.push(a, b, b, c, c, a);
  10916. }
  10917. } else {
  10918. const array = geometryPosition.array;
  10919. version = geometryPosition.version;
  10920. for (let i = 0, l = array.length / 3 - 1; i < l; i += 3) {
  10921. const a = i + 0;
  10922. const b = i + 1;
  10923. const c = i + 2;
  10924. indices.push(a, b, b, c, c, a);
  10925. }
  10926. }
  10927. const attribute = new (arrayNeedsUint32(indices) ? Uint32BufferAttribute : Uint16BufferAttribute)(indices, 1);
  10928. attribute.version = version; // Updating index buffer in VAO now. See WebGLBindingStates
  10929. //
  10930. const previousAttribute = wireframeAttributes.get(geometry);
  10931. if (previousAttribute) attributes.remove(previousAttribute); //
  10932. wireframeAttributes.set(geometry, attribute);
  10933. }
  10934. function getWireframeAttribute(geometry) {
  10935. const currentAttribute = wireframeAttributes.get(geometry);
  10936. if (currentAttribute) {
  10937. const geometryIndex = geometry.index;
  10938. if (geometryIndex !== null) {
  10939. // if the attribute is obsolete, create a new one
  10940. if (currentAttribute.version < geometryIndex.version) {
  10941. updateWireframeAttribute(geometry);
  10942. }
  10943. }
  10944. } else {
  10945. updateWireframeAttribute(geometry);
  10946. }
  10947. return wireframeAttributes.get(geometry);
  10948. }
  10949. return {
  10950. get: get,
  10951. update: update,
  10952. getWireframeAttribute: getWireframeAttribute
  10953. };
  10954. }
  10955. function WebGLIndexedBufferRenderer(gl, extensions, info, capabilities) {
  10956. const isWebGL2 = capabilities.isWebGL2;
  10957. let mode;
  10958. function setMode(value) {
  10959. mode = value;
  10960. }
  10961. let type, bytesPerElement;
  10962. function setIndex(value) {
  10963. type = value.type;
  10964. bytesPerElement = value.bytesPerElement;
  10965. }
  10966. function render(start, count) {
  10967. gl.drawElements(mode, count, type, start * bytesPerElement);
  10968. info.update(count, mode, 1);
  10969. }
  10970. function renderInstances(start, count, primcount) {
  10971. if (primcount === 0) return;
  10972. let extension, methodName;
  10973. if (isWebGL2) {
  10974. extension = gl;
  10975. methodName = 'drawElementsInstanced';
  10976. } else {
  10977. extension = extensions.get('ANGLE_instanced_arrays');
  10978. methodName = 'drawElementsInstancedANGLE';
  10979. if (extension === null) {
  10980. console.error('THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.');
  10981. return;
  10982. }
  10983. }
  10984. extension[methodName](mode, count, type, start * bytesPerElement, primcount);
  10985. info.update(count, mode, primcount);
  10986. } //
  10987. this.setMode = setMode;
  10988. this.setIndex = setIndex;
  10989. this.render = render;
  10990. this.renderInstances = renderInstances;
  10991. }
  10992. function WebGLInfo(gl) {
  10993. const memory = {
  10994. geometries: 0,
  10995. textures: 0
  10996. };
  10997. const render = {
  10998. frame: 0,
  10999. calls: 0,
  11000. triangles: 0,
  11001. points: 0,
  11002. lines: 0
  11003. };
  11004. function update(count, mode, instanceCount) {
  11005. render.calls++;
  11006. switch (mode) {
  11007. case gl.TRIANGLES:
  11008. render.triangles += instanceCount * (count / 3);
  11009. break;
  11010. case gl.LINES:
  11011. render.lines += instanceCount * (count / 2);
  11012. break;
  11013. case gl.LINE_STRIP:
  11014. render.lines += instanceCount * (count - 1);
  11015. break;
  11016. case gl.LINE_LOOP:
  11017. render.lines += instanceCount * count;
  11018. break;
  11019. case gl.POINTS:
  11020. render.points += instanceCount * count;
  11021. break;
  11022. default:
  11023. console.error('THREE.WebGLInfo: Unknown draw mode:', mode);
  11024. break;
  11025. }
  11026. }
  11027. function reset() {
  11028. render.frame++;
  11029. render.calls = 0;
  11030. render.triangles = 0;
  11031. render.points = 0;
  11032. render.lines = 0;
  11033. }
  11034. return {
  11035. memory: memory,
  11036. render: render,
  11037. programs: null,
  11038. autoReset: true,
  11039. reset: reset,
  11040. update: update
  11041. };
  11042. }
  11043. function numericalSort(a, b) {
  11044. return a[0] - b[0];
  11045. }
  11046. function absNumericalSort(a, b) {
  11047. return Math.abs(b[1]) - Math.abs(a[1]);
  11048. }
  11049. function denormalize(morph, attribute) {
  11050. let denominator = 1;
  11051. const array = attribute.isInterleavedBufferAttribute ? attribute.data.array : attribute.array;
  11052. if (array instanceof Int8Array) denominator = 127;else if (array instanceof Uint8Array) denominator = 255;else if (array instanceof Uint16Array) denominator = 65535;else if (array instanceof Int16Array) denominator = 32767;else if (array instanceof Int32Array) denominator = 2147483647;else console.error('THREE.WebGLMorphtargets: Unsupported morph attribute data type: ', array);
  11053. morph.divideScalar(denominator);
  11054. }
  11055. function WebGLMorphtargets(gl, capabilities, textures) {
  11056. const influencesList = {};
  11057. const morphInfluences = new Float32Array(8);
  11058. const morphTextures = new WeakMap();
  11059. const morph = new Vector4();
  11060. const workInfluences = [];
  11061. for (let i = 0; i < 8; i++) {
  11062. workInfluences[i] = [i, 0];
  11063. }
  11064. function update(object, geometry, material, program) {
  11065. const objectInfluences = object.morphTargetInfluences;
  11066. if (capabilities.isWebGL2 === true) {
  11067. // instead of using attributes, the WebGL 2 code path encodes morph targets
  11068. // into an array of data textures. Each layer represents a single morph target.
  11069. const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
  11070. const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
  11071. let entry = morphTextures.get(geometry);
  11072. if (entry === undefined || entry.count !== morphTargetsCount) {
  11073. if (entry !== undefined) entry.texture.dispose();
  11074. const hasMorphPosition = geometry.morphAttributes.position !== undefined;
  11075. const hasMorphNormals = geometry.morphAttributes.normal !== undefined;
  11076. const hasMorphColors = geometry.morphAttributes.color !== undefined;
  11077. const morphTargets = geometry.morphAttributes.position || [];
  11078. const morphNormals = geometry.morphAttributes.normal || [];
  11079. const morphColors = geometry.morphAttributes.color || [];
  11080. let vertexDataCount = 0;
  11081. if (hasMorphPosition === true) vertexDataCount = 1;
  11082. if (hasMorphNormals === true) vertexDataCount = 2;
  11083. if (hasMorphColors === true) vertexDataCount = 3;
  11084. let width = geometry.attributes.position.count * vertexDataCount;
  11085. let height = 1;
  11086. if (width > capabilities.maxTextureSize) {
  11087. height = Math.ceil(width / capabilities.maxTextureSize);
  11088. width = capabilities.maxTextureSize;
  11089. }
  11090. const buffer = new Float32Array(width * height * 4 * morphTargetsCount);
  11091. const texture = new DataArrayTexture(buffer, width, height, morphTargetsCount);
  11092. texture.type = FloatType;
  11093. texture.needsUpdate = true; // fill buffer
  11094. const vertexDataStride = vertexDataCount * 4;
  11095. for (let i = 0; i < morphTargetsCount; i++) {
  11096. const morphTarget = morphTargets[i];
  11097. const morphNormal = morphNormals[i];
  11098. const morphColor = morphColors[i];
  11099. const offset = width * height * 4 * i;
  11100. for (let j = 0; j < morphTarget.count; j++) {
  11101. const stride = j * vertexDataStride;
  11102. if (hasMorphPosition === true) {
  11103. morph.fromBufferAttribute(morphTarget, j);
  11104. if (morphTarget.normalized === true) denormalize(morph, morphTarget);
  11105. buffer[offset + stride + 0] = morph.x;
  11106. buffer[offset + stride + 1] = morph.y;
  11107. buffer[offset + stride + 2] = morph.z;
  11108. buffer[offset + stride + 3] = 0;
  11109. }
  11110. if (hasMorphNormals === true) {
  11111. morph.fromBufferAttribute(morphNormal, j);
  11112. if (morphNormal.normalized === true) denormalize(morph, morphNormal);
  11113. buffer[offset + stride + 4] = morph.x;
  11114. buffer[offset + stride + 5] = morph.y;
  11115. buffer[offset + stride + 6] = morph.z;
  11116. buffer[offset + stride + 7] = 0;
  11117. }
  11118. if (hasMorphColors === true) {
  11119. morph.fromBufferAttribute(morphColor, j);
  11120. if (morphColor.normalized === true) denormalize(morph, morphColor);
  11121. buffer[offset + stride + 8] = morph.x;
  11122. buffer[offset + stride + 9] = morph.y;
  11123. buffer[offset + stride + 10] = morph.z;
  11124. buffer[offset + stride + 11] = morphColor.itemSize === 4 ? morph.w : 1;
  11125. }
  11126. }
  11127. }
  11128. entry = {
  11129. count: morphTargetsCount,
  11130. texture: texture,
  11131. size: new Vector2(width, height)
  11132. };
  11133. morphTextures.set(geometry, entry);
  11134. function disposeTexture() {
  11135. texture.dispose();
  11136. morphTextures.delete(geometry);
  11137. geometry.removeEventListener('dispose', disposeTexture);
  11138. }
  11139. geometry.addEventListener('dispose', disposeTexture);
  11140. } //
  11141. let morphInfluencesSum = 0;
  11142. for (let i = 0; i < objectInfluences.length; i++) {
  11143. morphInfluencesSum += objectInfluences[i];
  11144. }
  11145. const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
  11146. program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence);
  11147. program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences);
  11148. program.getUniforms().setValue(gl, 'morphTargetsTexture', entry.texture, textures);
  11149. program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry.size);
  11150. } else {
  11151. // When object doesn't have morph target influences defined, we treat it as a 0-length array
  11152. // This is important to make sure we set up morphTargetBaseInfluence / morphTargetInfluences
  11153. const length = objectInfluences === undefined ? 0 : objectInfluences.length;
  11154. let influences = influencesList[geometry.id];
  11155. if (influences === undefined || influences.length !== length) {
  11156. // initialise list
  11157. influences = [];
  11158. for (let i = 0; i < length; i++) {
  11159. influences[i] = [i, 0];
  11160. }
  11161. influencesList[geometry.id] = influences;
  11162. } // Collect influences
  11163. for (let i = 0; i < length; i++) {
  11164. const influence = influences[i];
  11165. influence[0] = i;
  11166. influence[1] = objectInfluences[i];
  11167. }
  11168. influences.sort(absNumericalSort);
  11169. for (let i = 0; i < 8; i++) {
  11170. if (i < length && influences[i][1]) {
  11171. workInfluences[i][0] = influences[i][0];
  11172. workInfluences[i][1] = influences[i][1];
  11173. } else {
  11174. workInfluences[i][0] = Number.MAX_SAFE_INTEGER;
  11175. workInfluences[i][1] = 0;
  11176. }
  11177. }
  11178. workInfluences.sort(numericalSort);
  11179. const morphTargets = geometry.morphAttributes.position;
  11180. const morphNormals = geometry.morphAttributes.normal;
  11181. let morphInfluencesSum = 0;
  11182. for (let i = 0; i < 8; i++) {
  11183. const influence = workInfluences[i];
  11184. const index = influence[0];
  11185. const value = influence[1];
  11186. if (index !== Number.MAX_SAFE_INTEGER && value) {
  11187. if (morphTargets && geometry.getAttribute('morphTarget' + i) !== morphTargets[index]) {
  11188. geometry.setAttribute('morphTarget' + i, morphTargets[index]);
  11189. }
  11190. if (morphNormals && geometry.getAttribute('morphNormal' + i) !== morphNormals[index]) {
  11191. geometry.setAttribute('morphNormal' + i, morphNormals[index]);
  11192. }
  11193. morphInfluences[i] = value;
  11194. morphInfluencesSum += value;
  11195. } else {
  11196. if (morphTargets && geometry.hasAttribute('morphTarget' + i) === true) {
  11197. geometry.deleteAttribute('morphTarget' + i);
  11198. }
  11199. if (morphNormals && geometry.hasAttribute('morphNormal' + i) === true) {
  11200. geometry.deleteAttribute('morphNormal' + i);
  11201. }
  11202. morphInfluences[i] = 0;
  11203. }
  11204. } // GLSL shader uses formula baseinfluence * base + sum(target * influence)
  11205. // This allows us to switch between absolute morphs and relative morphs without changing shader code
  11206. // When baseinfluence = 1 - sum(influence), the above is equivalent to sum((target - base) * influence)
  11207. const morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum;
  11208. program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence);
  11209. program.getUniforms().setValue(gl, 'morphTargetInfluences', morphInfluences);
  11210. }
  11211. }
  11212. return {
  11213. update: update
  11214. };
  11215. }
  11216. function WebGLObjects(gl, geometries, attributes, info) {
  11217. let updateMap = new WeakMap();
  11218. function update(object) {
  11219. const frame = info.render.frame;
  11220. const geometry = object.geometry;
  11221. const buffergeometry = geometries.get(object, geometry); // Update once per frame
  11222. if (updateMap.get(buffergeometry) !== frame) {
  11223. geometries.update(buffergeometry);
  11224. updateMap.set(buffergeometry, frame);
  11225. }
  11226. if (object.isInstancedMesh) {
  11227. if (object.hasEventListener('dispose', onInstancedMeshDispose) === false) {
  11228. object.addEventListener('dispose', onInstancedMeshDispose);
  11229. }
  11230. attributes.update(object.instanceMatrix, gl.ARRAY_BUFFER);
  11231. if (object.instanceColor !== null) {
  11232. attributes.update(object.instanceColor, gl.ARRAY_BUFFER);
  11233. }
  11234. }
  11235. return buffergeometry;
  11236. }
  11237. function dispose() {
  11238. updateMap = new WeakMap();
  11239. }
  11240. function onInstancedMeshDispose(event) {
  11241. const instancedMesh = event.target;
  11242. instancedMesh.removeEventListener('dispose', onInstancedMeshDispose);
  11243. attributes.remove(instancedMesh.instanceMatrix);
  11244. if (instancedMesh.instanceColor !== null) attributes.remove(instancedMesh.instanceColor);
  11245. }
  11246. return {
  11247. update: update,
  11248. dispose: dispose
  11249. };
  11250. }
  11251. /**
  11252. * Uniforms of a program.
  11253. * Those form a tree structure with a special top-level container for the root,
  11254. * which you get by calling 'new WebGLUniforms( gl, program )'.
  11255. *
  11256. *
  11257. * Properties of inner nodes including the top-level container:
  11258. *
  11259. * .seq - array of nested uniforms
  11260. * .map - nested uniforms by name
  11261. *
  11262. *
  11263. * Methods of all nodes except the top-level container:
  11264. *
  11265. * .setValue( gl, value, [textures] )
  11266. *
  11267. * uploads a uniform value(s)
  11268. * the 'textures' parameter is needed for sampler uniforms
  11269. *
  11270. *
  11271. * Static methods of the top-level container (textures factorizations):
  11272. *
  11273. * .upload( gl, seq, values, textures )
  11274. *
  11275. * sets uniforms in 'seq' to 'values[id].value'
  11276. *
  11277. * .seqWithValue( seq, values ) : filteredSeq
  11278. *
  11279. * filters 'seq' entries with corresponding entry in values
  11280. *
  11281. *
  11282. * Methods of the top-level container (textures factorizations):
  11283. *
  11284. * .setValue( gl, name, value, textures )
  11285. *
  11286. * sets uniform with name 'name' to 'value'
  11287. *
  11288. * .setOptional( gl, obj, prop )
  11289. *
  11290. * like .set for an optional property of the object
  11291. *
  11292. */
  11293. const emptyTexture = /*@__PURE__*/new Texture();
  11294. const emptyArrayTexture = /*@__PURE__*/new DataArrayTexture();
  11295. const empty3dTexture = /*@__PURE__*/new Data3DTexture();
  11296. const emptyCubeTexture = /*@__PURE__*/new CubeTexture(); // --- Utilities ---
  11297. // Array Caches (provide typed arrays for temporary by size)
  11298. const arrayCacheF32 = [];
  11299. const arrayCacheI32 = []; // Float32Array caches used for uploading Matrix uniforms
  11300. const mat4array = new Float32Array(16);
  11301. const mat3array = new Float32Array(9);
  11302. const mat2array = new Float32Array(4); // Flattening for arrays of vectors and matrices
  11303. function flatten(array, nBlocks, blockSize) {
  11304. const firstElem = array[0];
  11305. if (firstElem <= 0 || firstElem > 0) return array; // unoptimized: ! isNaN( firstElem )
  11306. // see http://jacksondunstan.com/articles/983
  11307. const n = nBlocks * blockSize;
  11308. let r = arrayCacheF32[n];
  11309. if (r === undefined) {
  11310. r = new Float32Array(n);
  11311. arrayCacheF32[n] = r;
  11312. }
  11313. if (nBlocks !== 0) {
  11314. firstElem.toArray(r, 0);
  11315. for (let i = 1, offset = 0; i !== nBlocks; ++i) {
  11316. offset += blockSize;
  11317. array[i].toArray(r, offset);
  11318. }
  11319. }
  11320. return r;
  11321. }
  11322. function arraysEqual(a, b) {
  11323. if (a.length !== b.length) return false;
  11324. for (let i = 0, l = a.length; i < l; i++) {
  11325. if (a[i] !== b[i]) return false;
  11326. }
  11327. return true;
  11328. }
  11329. function copyArray(a, b) {
  11330. for (let i = 0, l = b.length; i < l; i++) {
  11331. a[i] = b[i];
  11332. }
  11333. } // Texture unit allocation
  11334. function allocTexUnits(textures, n) {
  11335. let r = arrayCacheI32[n];
  11336. if (r === undefined) {
  11337. r = new Int32Array(n);
  11338. arrayCacheI32[n] = r;
  11339. }
  11340. for (let i = 0; i !== n; ++i) {
  11341. r[i] = textures.allocateTextureUnit();
  11342. }
  11343. return r;
  11344. } // --- Setters ---
  11345. // Note: Defining these methods externally, because they come in a bunch
  11346. // and this way their names minify.
  11347. // Single scalar
  11348. function setValueV1f(gl, v) {
  11349. const cache = this.cache;
  11350. if (cache[0] === v) return;
  11351. gl.uniform1f(this.addr, v);
  11352. cache[0] = v;
  11353. } // Single float vector (from flat array or THREE.VectorN)
  11354. function setValueV2f(gl, v) {
  11355. const cache = this.cache;
  11356. if (v.x !== undefined) {
  11357. if (cache[0] !== v.x || cache[1] !== v.y) {
  11358. gl.uniform2f(this.addr, v.x, v.y);
  11359. cache[0] = v.x;
  11360. cache[1] = v.y;
  11361. }
  11362. } else {
  11363. if (arraysEqual(cache, v)) return;
  11364. gl.uniform2fv(this.addr, v);
  11365. copyArray(cache, v);
  11366. }
  11367. }
  11368. function setValueV3f(gl, v) {
  11369. const cache = this.cache;
  11370. if (v.x !== undefined) {
  11371. if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z) {
  11372. gl.uniform3f(this.addr, v.x, v.y, v.z);
  11373. cache[0] = v.x;
  11374. cache[1] = v.y;
  11375. cache[2] = v.z;
  11376. }
  11377. } else if (v.r !== undefined) {
  11378. if (cache[0] !== v.r || cache[1] !== v.g || cache[2] !== v.b) {
  11379. gl.uniform3f(this.addr, v.r, v.g, v.b);
  11380. cache[0] = v.r;
  11381. cache[1] = v.g;
  11382. cache[2] = v.b;
  11383. }
  11384. } else {
  11385. if (arraysEqual(cache, v)) return;
  11386. gl.uniform3fv(this.addr, v);
  11387. copyArray(cache, v);
  11388. }
  11389. }
  11390. function setValueV4f(gl, v) {
  11391. const cache = this.cache;
  11392. if (v.x !== undefined) {
  11393. if (cache[0] !== v.x || cache[1] !== v.y || cache[2] !== v.z || cache[3] !== v.w) {
  11394. gl.uniform4f(this.addr, v.x, v.y, v.z, v.w);
  11395. cache[0] = v.x;
  11396. cache[1] = v.y;
  11397. cache[2] = v.z;
  11398. cache[3] = v.w;
  11399. }
  11400. } else {
  11401. if (arraysEqual(cache, v)) return;
  11402. gl.uniform4fv(this.addr, v);
  11403. copyArray(cache, v);
  11404. }
  11405. } // Single matrix (from flat array or THREE.MatrixN)
  11406. function setValueM2(gl, v) {
  11407. const cache = this.cache;
  11408. const elements = v.elements;
  11409. if (elements === undefined) {
  11410. if (arraysEqual(cache, v)) return;
  11411. gl.uniformMatrix2fv(this.addr, false, v);
  11412. copyArray(cache, v);
  11413. } else {
  11414. if (arraysEqual(cache, elements)) return;
  11415. mat2array.set(elements);
  11416. gl.uniformMatrix2fv(this.addr, false, mat2array);
  11417. copyArray(cache, elements);
  11418. }
  11419. }
  11420. function setValueM3(gl, v) {
  11421. const cache = this.cache;
  11422. const elements = v.elements;
  11423. if (elements === undefined) {
  11424. if (arraysEqual(cache, v)) return;
  11425. gl.uniformMatrix3fv(this.addr, false, v);
  11426. copyArray(cache, v);
  11427. } else {
  11428. if (arraysEqual(cache, elements)) return;
  11429. mat3array.set(elements);
  11430. gl.uniformMatrix3fv(this.addr, false, mat3array);
  11431. copyArray(cache, elements);
  11432. }
  11433. }
  11434. function setValueM4(gl, v) {
  11435. const cache = this.cache;
  11436. const elements = v.elements;
  11437. if (elements === undefined) {
  11438. if (arraysEqual(cache, v)) return;
  11439. gl.uniformMatrix4fv(this.addr, false, v);
  11440. copyArray(cache, v);
  11441. } else {
  11442. if (arraysEqual(cache, elements)) return;
  11443. mat4array.set(elements);
  11444. gl.uniformMatrix4fv(this.addr, false, mat4array);
  11445. copyArray(cache, elements);
  11446. }
  11447. } // Single integer / boolean
  11448. function setValueV1i(gl, v) {
  11449. const cache = this.cache;
  11450. if (cache[0] === v) return;
  11451. gl.uniform1i(this.addr, v);
  11452. cache[0] = v;
  11453. } // Single integer / boolean vector (from flat array)
  11454. function setValueV2i(gl, v) {
  11455. const cache = this.cache;
  11456. if (arraysEqual(cache, v)) return;
  11457. gl.uniform2iv(this.addr, v);
  11458. copyArray(cache, v);
  11459. }
  11460. function setValueV3i(gl, v) {
  11461. const cache = this.cache;
  11462. if (arraysEqual(cache, v)) return;
  11463. gl.uniform3iv(this.addr, v);
  11464. copyArray(cache, v);
  11465. }
  11466. function setValueV4i(gl, v) {
  11467. const cache = this.cache;
  11468. if (arraysEqual(cache, v)) return;
  11469. gl.uniform4iv(this.addr, v);
  11470. copyArray(cache, v);
  11471. } // Single unsigned integer
  11472. function setValueV1ui(gl, v) {
  11473. const cache = this.cache;
  11474. if (cache[0] === v) return;
  11475. gl.uniform1ui(this.addr, v);
  11476. cache[0] = v;
  11477. } // Single unsigned integer vector (from flat array)
  11478. function setValueV2ui(gl, v) {
  11479. const cache = this.cache;
  11480. if (arraysEqual(cache, v)) return;
  11481. gl.uniform2uiv(this.addr, v);
  11482. copyArray(cache, v);
  11483. }
  11484. function setValueV3ui(gl, v) {
  11485. const cache = this.cache;
  11486. if (arraysEqual(cache, v)) return;
  11487. gl.uniform3uiv(this.addr, v);
  11488. copyArray(cache, v);
  11489. }
  11490. function setValueV4ui(gl, v) {
  11491. const cache = this.cache;
  11492. if (arraysEqual(cache, v)) return;
  11493. gl.uniform4uiv(this.addr, v);
  11494. copyArray(cache, v);
  11495. } // Single texture (2D / Cube)
  11496. function setValueT1(gl, v, textures) {
  11497. const cache = this.cache;
  11498. const unit = textures.allocateTextureUnit();
  11499. if (cache[0] !== unit) {
  11500. gl.uniform1i(this.addr, unit);
  11501. cache[0] = unit;
  11502. }
  11503. textures.setTexture2D(v || emptyTexture, unit);
  11504. }
  11505. function setValueT3D1(gl, v, textures) {
  11506. const cache = this.cache;
  11507. const unit = textures.allocateTextureUnit();
  11508. if (cache[0] !== unit) {
  11509. gl.uniform1i(this.addr, unit);
  11510. cache[0] = unit;
  11511. }
  11512. textures.setTexture3D(v || empty3dTexture, unit);
  11513. }
  11514. function setValueT6(gl, v, textures) {
  11515. const cache = this.cache;
  11516. const unit = textures.allocateTextureUnit();
  11517. if (cache[0] !== unit) {
  11518. gl.uniform1i(this.addr, unit);
  11519. cache[0] = unit;
  11520. }
  11521. textures.setTextureCube(v || emptyCubeTexture, unit);
  11522. }
  11523. function setValueT2DArray1(gl, v, textures) {
  11524. const cache = this.cache;
  11525. const unit = textures.allocateTextureUnit();
  11526. if (cache[0] !== unit) {
  11527. gl.uniform1i(this.addr, unit);
  11528. cache[0] = unit;
  11529. }
  11530. textures.setTexture2DArray(v || emptyArrayTexture, unit);
  11531. } // Helper to pick the right setter for the singular case
  11532. function getSingularSetter(type) {
  11533. switch (type) {
  11534. case 0x1406:
  11535. return setValueV1f;
  11536. // FLOAT
  11537. case 0x8b50:
  11538. return setValueV2f;
  11539. // _VEC2
  11540. case 0x8b51:
  11541. return setValueV3f;
  11542. // _VEC3
  11543. case 0x8b52:
  11544. return setValueV4f;
  11545. // _VEC4
  11546. case 0x8b5a:
  11547. return setValueM2;
  11548. // _MAT2
  11549. case 0x8b5b:
  11550. return setValueM3;
  11551. // _MAT3
  11552. case 0x8b5c:
  11553. return setValueM4;
  11554. // _MAT4
  11555. case 0x1404:
  11556. case 0x8b56:
  11557. return setValueV1i;
  11558. // INT, BOOL
  11559. case 0x8b53:
  11560. case 0x8b57:
  11561. return setValueV2i;
  11562. // _VEC2
  11563. case 0x8b54:
  11564. case 0x8b58:
  11565. return setValueV3i;
  11566. // _VEC3
  11567. case 0x8b55:
  11568. case 0x8b59:
  11569. return setValueV4i;
  11570. // _VEC4
  11571. case 0x1405:
  11572. return setValueV1ui;
  11573. // UINT
  11574. case 0x8dc6:
  11575. return setValueV2ui;
  11576. // _VEC2
  11577. case 0x8dc7:
  11578. return setValueV3ui;
  11579. // _VEC3
  11580. case 0x8dc8:
  11581. return setValueV4ui;
  11582. // _VEC4
  11583. case 0x8b5e: // SAMPLER_2D
  11584. case 0x8d66: // SAMPLER_EXTERNAL_OES
  11585. case 0x8dca: // INT_SAMPLER_2D
  11586. case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
  11587. case 0x8b62:
  11588. // SAMPLER_2D_SHADOW
  11589. return setValueT1;
  11590. case 0x8b5f: // SAMPLER_3D
  11591. case 0x8dcb: // INT_SAMPLER_3D
  11592. case 0x8dd3:
  11593. // UNSIGNED_INT_SAMPLER_3D
  11594. return setValueT3D1;
  11595. case 0x8b60: // SAMPLER_CUBE
  11596. case 0x8dcc: // INT_SAMPLER_CUBE
  11597. case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
  11598. case 0x8dc5:
  11599. // SAMPLER_CUBE_SHADOW
  11600. return setValueT6;
  11601. case 0x8dc1: // SAMPLER_2D_ARRAY
  11602. case 0x8dcf: // INT_SAMPLER_2D_ARRAY
  11603. case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY
  11604. case 0x8dc4:
  11605. // SAMPLER_2D_ARRAY_SHADOW
  11606. return setValueT2DArray1;
  11607. }
  11608. } // Array of scalars
  11609. function setValueV1fArray(gl, v) {
  11610. gl.uniform1fv(this.addr, v);
  11611. } // Array of vectors (from flat array or array of THREE.VectorN)
  11612. function setValueV2fArray(gl, v) {
  11613. const data = flatten(v, this.size, 2);
  11614. gl.uniform2fv(this.addr, data);
  11615. }
  11616. function setValueV3fArray(gl, v) {
  11617. const data = flatten(v, this.size, 3);
  11618. gl.uniform3fv(this.addr, data);
  11619. }
  11620. function setValueV4fArray(gl, v) {
  11621. const data = flatten(v, this.size, 4);
  11622. gl.uniform4fv(this.addr, data);
  11623. } // Array of matrices (from flat array or array of THREE.MatrixN)
  11624. function setValueM2Array(gl, v) {
  11625. const data = flatten(v, this.size, 4);
  11626. gl.uniformMatrix2fv(this.addr, false, data);
  11627. }
  11628. function setValueM3Array(gl, v) {
  11629. const data = flatten(v, this.size, 9);
  11630. gl.uniformMatrix3fv(this.addr, false, data);
  11631. }
  11632. function setValueM4Array(gl, v) {
  11633. const data = flatten(v, this.size, 16);
  11634. gl.uniformMatrix4fv(this.addr, false, data);
  11635. } // Array of integer / boolean
  11636. function setValueV1iArray(gl, v) {
  11637. gl.uniform1iv(this.addr, v);
  11638. } // Array of integer / boolean vectors (from flat array)
  11639. function setValueV2iArray(gl, v) {
  11640. gl.uniform2iv(this.addr, v);
  11641. }
  11642. function setValueV3iArray(gl, v) {
  11643. gl.uniform3iv(this.addr, v);
  11644. }
  11645. function setValueV4iArray(gl, v) {
  11646. gl.uniform4iv(this.addr, v);
  11647. } // Array of unsigned integer
  11648. function setValueV1uiArray(gl, v) {
  11649. gl.uniform1uiv(this.addr, v);
  11650. } // Array of unsigned integer vectors (from flat array)
  11651. function setValueV2uiArray(gl, v) {
  11652. gl.uniform2uiv(this.addr, v);
  11653. }
  11654. function setValueV3uiArray(gl, v) {
  11655. gl.uniform3uiv(this.addr, v);
  11656. }
  11657. function setValueV4uiArray(gl, v) {
  11658. gl.uniform4uiv(this.addr, v);
  11659. } // Array of textures (2D / 3D / Cube / 2DArray)
  11660. function setValueT1Array(gl, v, textures) {
  11661. const n = v.length;
  11662. const units = allocTexUnits(textures, n);
  11663. gl.uniform1iv(this.addr, units);
  11664. for (let i = 0; i !== n; ++i) {
  11665. textures.setTexture2D(v[i] || emptyTexture, units[i]);
  11666. }
  11667. }
  11668. function setValueT3DArray(gl, v, textures) {
  11669. const n = v.length;
  11670. const units = allocTexUnits(textures, n);
  11671. gl.uniform1iv(this.addr, units);
  11672. for (let i = 0; i !== n; ++i) {
  11673. textures.setTexture3D(v[i] || empty3dTexture, units[i]);
  11674. }
  11675. }
  11676. function setValueT6Array(gl, v, textures) {
  11677. const n = v.length;
  11678. const units = allocTexUnits(textures, n);
  11679. gl.uniform1iv(this.addr, units);
  11680. for (let i = 0; i !== n; ++i) {
  11681. textures.setTextureCube(v[i] || emptyCubeTexture, units[i]);
  11682. }
  11683. }
  11684. function setValueT2DArrayArray(gl, v, textures) {
  11685. const n = v.length;
  11686. const units = allocTexUnits(textures, n);
  11687. gl.uniform1iv(this.addr, units);
  11688. for (let i = 0; i !== n; ++i) {
  11689. textures.setTexture2DArray(v[i] || emptyArrayTexture, units[i]);
  11690. }
  11691. } // Helper to pick the right setter for a pure (bottom-level) array
  11692. function getPureArraySetter(type) {
  11693. switch (type) {
  11694. case 0x1406:
  11695. return setValueV1fArray;
  11696. // FLOAT
  11697. case 0x8b50:
  11698. return setValueV2fArray;
  11699. // _VEC2
  11700. case 0x8b51:
  11701. return setValueV3fArray;
  11702. // _VEC3
  11703. case 0x8b52:
  11704. return setValueV4fArray;
  11705. // _VEC4
  11706. case 0x8b5a:
  11707. return setValueM2Array;
  11708. // _MAT2
  11709. case 0x8b5b:
  11710. return setValueM3Array;
  11711. // _MAT3
  11712. case 0x8b5c:
  11713. return setValueM4Array;
  11714. // _MAT4
  11715. case 0x1404:
  11716. case 0x8b56:
  11717. return setValueV1iArray;
  11718. // INT, BOOL
  11719. case 0x8b53:
  11720. case 0x8b57:
  11721. return setValueV2iArray;
  11722. // _VEC2
  11723. case 0x8b54:
  11724. case 0x8b58:
  11725. return setValueV3iArray;
  11726. // _VEC3
  11727. case 0x8b55:
  11728. case 0x8b59:
  11729. return setValueV4iArray;
  11730. // _VEC4
  11731. case 0x1405:
  11732. return setValueV1uiArray;
  11733. // UINT
  11734. case 0x8dc6:
  11735. return setValueV2uiArray;
  11736. // _VEC2
  11737. case 0x8dc7:
  11738. return setValueV3uiArray;
  11739. // _VEC3
  11740. case 0x8dc8:
  11741. return setValueV4uiArray;
  11742. // _VEC4
  11743. case 0x8b5e: // SAMPLER_2D
  11744. case 0x8d66: // SAMPLER_EXTERNAL_OES
  11745. case 0x8dca: // INT_SAMPLER_2D
  11746. case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D
  11747. case 0x8b62:
  11748. // SAMPLER_2D_SHADOW
  11749. return setValueT1Array;
  11750. case 0x8b5f: // SAMPLER_3D
  11751. case 0x8dcb: // INT_SAMPLER_3D
  11752. case 0x8dd3:
  11753. // UNSIGNED_INT_SAMPLER_3D
  11754. return setValueT3DArray;
  11755. case 0x8b60: // SAMPLER_CUBE
  11756. case 0x8dcc: // INT_SAMPLER_CUBE
  11757. case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE
  11758. case 0x8dc5:
  11759. // SAMPLER_CUBE_SHADOW
  11760. return setValueT6Array;
  11761. case 0x8dc1: // SAMPLER_2D_ARRAY
  11762. case 0x8dcf: // INT_SAMPLER_2D_ARRAY
  11763. case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY
  11764. case 0x8dc4:
  11765. // SAMPLER_2D_ARRAY_SHADOW
  11766. return setValueT2DArrayArray;
  11767. }
  11768. } // --- Uniform Classes ---
  11769. class SingleUniform {
  11770. constructor(id, activeInfo, addr) {
  11771. this.id = id;
  11772. this.addr = addr;
  11773. this.cache = [];
  11774. this.setValue = getSingularSetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG
  11775. }
  11776. }
  11777. class PureArrayUniform {
  11778. constructor(id, activeInfo, addr) {
  11779. this.id = id;
  11780. this.addr = addr;
  11781. this.cache = [];
  11782. this.size = activeInfo.size;
  11783. this.setValue = getPureArraySetter(activeInfo.type); // this.path = activeInfo.name; // DEBUG
  11784. }
  11785. }
  11786. class StructuredUniform {
  11787. constructor(id) {
  11788. this.id = id;
  11789. this.seq = [];
  11790. this.map = {};
  11791. }
  11792. setValue(gl, value, textures) {
  11793. const seq = this.seq;
  11794. for (let i = 0, n = seq.length; i !== n; ++i) {
  11795. const u = seq[i];
  11796. u.setValue(gl, value[u.id], textures);
  11797. }
  11798. }
  11799. } // --- Top-level ---
  11800. // Parser - builds up the property tree from the path strings
  11801. const RePathPart = /(\w+)(\])?(\[|\.)?/g; // extracts
  11802. // - the identifier (member name or array index)
  11803. // - followed by an optional right bracket (found when array index)
  11804. // - followed by an optional left bracket or dot (type of subscript)
  11805. //
  11806. // Note: These portions can be read in a non-overlapping fashion and
  11807. // allow straightforward parsing of the hierarchy that WebGL encodes
  11808. // in the uniform names.
  11809. function addUniform(container, uniformObject) {
  11810. container.seq.push(uniformObject);
  11811. container.map[uniformObject.id] = uniformObject;
  11812. }
  11813. function parseUniform(activeInfo, addr, container) {
  11814. const path = activeInfo.name,
  11815. pathLength = path.length; // reset RegExp object, because of the early exit of a previous run
  11816. RePathPart.lastIndex = 0;
  11817. while (true) {
  11818. const match = RePathPart.exec(path),
  11819. matchEnd = RePathPart.lastIndex;
  11820. let id = match[1];
  11821. const idIsIndex = match[2] === ']',
  11822. subscript = match[3];
  11823. if (idIsIndex) id = id | 0; // convert to integer
  11824. if (subscript === undefined || subscript === '[' && matchEnd + 2 === pathLength) {
  11825. // bare name or "pure" bottom-level array "[0]" suffix
  11826. addUniform(container, subscript === undefined ? new SingleUniform(id, activeInfo, addr) : new PureArrayUniform(id, activeInfo, addr));
  11827. break;
  11828. } else {
  11829. // step into inner node / create it in case it doesn't exist
  11830. const map = container.map;
  11831. let next = map[id];
  11832. if (next === undefined) {
  11833. next = new StructuredUniform(id);
  11834. addUniform(container, next);
  11835. }
  11836. container = next;
  11837. }
  11838. }
  11839. } // Root Container
  11840. class WebGLUniforms {
  11841. constructor(gl, program) {
  11842. this.seq = [];
  11843. this.map = {};
  11844. const n = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
  11845. for (let i = 0; i < n; ++i) {
  11846. const info = gl.getActiveUniform(program, i),
  11847. addr = gl.getUniformLocation(program, info.name);
  11848. parseUniform(info, addr, this);
  11849. }
  11850. }
  11851. setValue(gl, name, value, textures) {
  11852. const u = this.map[name];
  11853. if (u !== undefined) u.setValue(gl, value, textures);
  11854. }
  11855. setOptional(gl, object, name) {
  11856. const v = object[name];
  11857. if (v !== undefined) this.setValue(gl, name, v);
  11858. }
  11859. static upload(gl, seq, values, textures) {
  11860. for (let i = 0, n = seq.length; i !== n; ++i) {
  11861. const u = seq[i],
  11862. v = values[u.id];
  11863. if (v.needsUpdate !== false) {
  11864. // note: always updating when .needsUpdate is undefined
  11865. u.setValue(gl, v.value, textures);
  11866. }
  11867. }
  11868. }
  11869. static seqWithValue(seq, values) {
  11870. const r = [];
  11871. for (let i = 0, n = seq.length; i !== n; ++i) {
  11872. const u = seq[i];
  11873. if (u.id in values) r.push(u);
  11874. }
  11875. return r;
  11876. }
  11877. }
  11878. function WebGLShader(gl, type, string) {
  11879. const shader = gl.createShader(type);
  11880. gl.shaderSource(shader, string);
  11881. gl.compileShader(shader);
  11882. return shader;
  11883. }
  11884. let programIdCount = 0;
  11885. function handleSource(string, errorLine) {
  11886. const lines = string.split('\n');
  11887. const lines2 = [];
  11888. const from = Math.max(errorLine - 6, 0);
  11889. const to = Math.min(errorLine + 6, lines.length);
  11890. for (let i = from; i < to; i++) {
  11891. const line = i + 1;
  11892. lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`);
  11893. }
  11894. return lines2.join('\n');
  11895. }
  11896. function getEncodingComponents(encoding) {
  11897. switch (encoding) {
  11898. case LinearEncoding:
  11899. return ['Linear', '( value )'];
  11900. case sRGBEncoding:
  11901. return ['sRGB', '( value )'];
  11902. default:
  11903. console.warn('THREE.WebGLProgram: Unsupported encoding:', encoding);
  11904. return ['Linear', '( value )'];
  11905. }
  11906. }
  11907. function getShaderErrors(gl, shader, type) {
  11908. const status = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  11909. const errors = gl.getShaderInfoLog(shader).trim();
  11910. if (status && errors === '') return '';
  11911. const errorMatches = /ERROR: 0:(\d+)/.exec(errors);
  11912. if (errorMatches) {
  11913. // --enable-privileged-webgl-extension
  11914. // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );
  11915. const errorLine = parseInt(errorMatches[1]);
  11916. return type.toUpperCase() + '\n\n' + errors + '\n\n' + handleSource(gl.getShaderSource(shader), errorLine);
  11917. } else {
  11918. return errors;
  11919. }
  11920. }
  11921. function getTexelEncodingFunction(functionName, encoding) {
  11922. const components = getEncodingComponents(encoding);
  11923. return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[0] + components[1] + '; }';
  11924. }
  11925. function getToneMappingFunction(functionName, toneMapping) {
  11926. let toneMappingName;
  11927. switch (toneMapping) {
  11928. case LinearToneMapping:
  11929. toneMappingName = 'Linear';
  11930. break;
  11931. case ReinhardToneMapping:
  11932. toneMappingName = 'Reinhard';
  11933. break;
  11934. case CineonToneMapping:
  11935. toneMappingName = 'OptimizedCineon';
  11936. break;
  11937. case ACESFilmicToneMapping:
  11938. toneMappingName = 'ACESFilmic';
  11939. break;
  11940. case CustomToneMapping:
  11941. toneMappingName = 'Custom';
  11942. break;
  11943. default:
  11944. console.warn('THREE.WebGLProgram: Unsupported toneMapping:', toneMapping);
  11945. toneMappingName = 'Linear';
  11946. }
  11947. return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
  11948. }
  11949. function generateExtensions(parameters) {
  11950. const chunks = [parameters.extensionDerivatives || !!parameters.envMapCubeUVHeight || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading || parameters.shaderID === 'physical' ? '#extension GL_OES_standard_derivatives : enable' : '', (parameters.extensionFragDepth || parameters.logarithmicDepthBuffer) && parameters.rendererExtensionFragDepth ? '#extension GL_EXT_frag_depth : enable' : '', parameters.extensionDrawBuffers && parameters.rendererExtensionDrawBuffers ? '#extension GL_EXT_draw_buffers : require' : '', (parameters.extensionShaderTextureLOD || parameters.envMap || parameters.transmission) && parameters.rendererExtensionShaderTextureLod ? '#extension GL_EXT_shader_texture_lod : enable' : ''];
  11951. return chunks.filter(filterEmptyLine).join('\n');
  11952. }
  11953. function generateDefines(defines) {
  11954. const chunks = [];
  11955. for (const name in defines) {
  11956. const value = defines[name];
  11957. if (value === false) continue;
  11958. chunks.push('#define ' + name + ' ' + value);
  11959. }
  11960. return chunks.join('\n');
  11961. }
  11962. function fetchAttributeLocations(gl, program) {
  11963. const attributes = {};
  11964. const n = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
  11965. for (let i = 0; i < n; i++) {
  11966. const info = gl.getActiveAttrib(program, i);
  11967. const name = info.name;
  11968. let locationSize = 1;
  11969. if (info.type === gl.FLOAT_MAT2) locationSize = 2;
  11970. if (info.type === gl.FLOAT_MAT3) locationSize = 3;
  11971. if (info.type === gl.FLOAT_MAT4) locationSize = 4; // console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );
  11972. attributes[name] = {
  11973. type: info.type,
  11974. location: gl.getAttribLocation(program, name),
  11975. locationSize: locationSize
  11976. };
  11977. }
  11978. return attributes;
  11979. }
  11980. function filterEmptyLine(string) {
  11981. return string !== '';
  11982. }
  11983. function replaceLightNums(string, parameters) {
  11984. return string.replace(/NUM_DIR_LIGHTS/g, parameters.numDirLights).replace(/NUM_SPOT_LIGHTS/g, parameters.numSpotLights).replace(/NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g, parameters.numPointLights).replace(/NUM_HEMI_LIGHTS/g, parameters.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows);
  11985. }
  11986. function replaceClippingPlaneNums(string, parameters) {
  11987. return string.replace(/NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g, parameters.numClippingPlanes - parameters.numClipIntersection);
  11988. } // Resolve Includes
  11989. const includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
  11990. function resolveIncludes(string) {
  11991. return string.replace(includePattern, includeReplacer);
  11992. }
  11993. function includeReplacer(match, include) {
  11994. const string = ShaderChunk[include];
  11995. if (string === undefined) {
  11996. throw new Error('Can not resolve #include <' + include + '>');
  11997. }
  11998. return resolveIncludes(string);
  11999. } // Unroll Loops
  12000. const deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
  12001. const unrollLoopPattern = /#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;
  12002. function unrollLoops(string) {
  12003. return string.replace(unrollLoopPattern, loopReplacer).replace(deprecatedUnrollLoopPattern, deprecatedLoopReplacer);
  12004. }
  12005. function deprecatedLoopReplacer(match, start, end, snippet) {
  12006. console.warn('WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.');
  12007. return loopReplacer(match, start, end, snippet);
  12008. }
  12009. function loopReplacer(match, start, end, snippet) {
  12010. let string = '';
  12011. for (let i = parseInt(start); i < parseInt(end); i++) {
  12012. string += snippet.replace(/\[\s*i\s*\]/g, '[ ' + i + ' ]').replace(/UNROLLED_LOOP_INDEX/g, i);
  12013. }
  12014. return string;
  12015. } //
  12016. function generatePrecision(parameters) {
  12017. let precisionstring = 'precision ' + parameters.precision + ' float;\nprecision ' + parameters.precision + ' int;';
  12018. if (parameters.precision === 'highp') {
  12019. precisionstring += '\n#define HIGH_PRECISION';
  12020. } else if (parameters.precision === 'mediump') {
  12021. precisionstring += '\n#define MEDIUM_PRECISION';
  12022. } else if (parameters.precision === 'lowp') {
  12023. precisionstring += '\n#define LOW_PRECISION';
  12024. }
  12025. return precisionstring;
  12026. }
  12027. function generateShadowMapTypeDefine(parameters) {
  12028. let shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
  12029. if (parameters.shadowMapType === PCFShadowMap) {
  12030. shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
  12031. } else if (parameters.shadowMapType === PCFSoftShadowMap) {
  12032. shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
  12033. } else if (parameters.shadowMapType === VSMShadowMap) {
  12034. shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';
  12035. }
  12036. return shadowMapTypeDefine;
  12037. }
  12038. function generateEnvMapTypeDefine(parameters) {
  12039. let envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
  12040. if (parameters.envMap) {
  12041. switch (parameters.envMapMode) {
  12042. case CubeReflectionMapping:
  12043. case CubeRefractionMapping:
  12044. envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
  12045. break;
  12046. case CubeUVReflectionMapping:
  12047. envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
  12048. break;
  12049. }
  12050. }
  12051. return envMapTypeDefine;
  12052. }
  12053. function generateEnvMapModeDefine(parameters) {
  12054. let envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
  12055. if (parameters.envMap) {
  12056. switch (parameters.envMapMode) {
  12057. case CubeRefractionMapping:
  12058. envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
  12059. break;
  12060. }
  12061. }
  12062. return envMapModeDefine;
  12063. }
  12064. function generateEnvMapBlendingDefine(parameters) {
  12065. let envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
  12066. if (parameters.envMap) {
  12067. switch (parameters.combine) {
  12068. case MultiplyOperation:
  12069. envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
  12070. break;
  12071. case MixOperation:
  12072. envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
  12073. break;
  12074. case AddOperation:
  12075. envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
  12076. break;
  12077. }
  12078. }
  12079. return envMapBlendingDefine;
  12080. }
  12081. function generateCubeUVSize(parameters) {
  12082. const imageHeight = parameters.envMapCubeUVHeight;
  12083. if (imageHeight === null) return null;
  12084. const maxMip = Math.log2(imageHeight) - 2;
  12085. const texelHeight = 1.0 / imageHeight;
  12086. const texelWidth = 1.0 / (3 * Math.max(Math.pow(2, maxMip), 7 * 16));
  12087. return {
  12088. texelWidth,
  12089. texelHeight,
  12090. maxMip
  12091. };
  12092. }
  12093. function WebGLProgram(renderer, cacheKey, parameters, bindingStates) {
  12094. // TODO Send this event to Three.js DevTools
  12095. // console.log( 'WebGLProgram', cacheKey );
  12096. const gl = renderer.getContext();
  12097. const defines = parameters.defines;
  12098. let vertexShader = parameters.vertexShader;
  12099. let fragmentShader = parameters.fragmentShader;
  12100. const shadowMapTypeDefine = generateShadowMapTypeDefine(parameters);
  12101. const envMapTypeDefine = generateEnvMapTypeDefine(parameters);
  12102. const envMapModeDefine = generateEnvMapModeDefine(parameters);
  12103. const envMapBlendingDefine = generateEnvMapBlendingDefine(parameters);
  12104. const envMapCubeUVSize = generateCubeUVSize(parameters);
  12105. const customExtensions = parameters.isWebGL2 ? '' : generateExtensions(parameters);
  12106. const customDefines = generateDefines(defines);
  12107. const program = gl.createProgram();
  12108. let prefixVertex, prefixFragment;
  12109. let versionString = parameters.glslVersion ? '#version ' + parameters.glslVersion + '\n' : '';
  12110. if (parameters.isRawShaderMaterial) {
  12111. prefixVertex = [customDefines].filter(filterEmptyLine).join('\n');
  12112. if (prefixVertex.length > 0) {
  12113. prefixVertex += '\n';
  12114. }
  12115. prefixFragment = [customExtensions, customDefines].filter(filterEmptyLine).join('\n');
  12116. if (prefixFragment.length > 0) {
  12117. prefixFragment += '\n';
  12118. }
  12119. } else {
  12120. prefixVertex = [generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.instancing ? '#define USE_INSTANCING' : '', parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '', parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '', parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.skinning ? '#define USE_SKINNING' : '', parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '', parameters.morphColors && parameters.isWebGL2 ? '#define USE_MORPHCOLORS' : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE' : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_TEXTURE_STRIDE ' + parameters.morphTextureStride : '', parameters.morphTargetsCount > 0 && parameters.isWebGL2 ? '#define MORPHTARGETS_COUNT ' + parameters.morphTargetsCount : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 modelMatrix;', 'uniform mat4 modelViewMatrix;', 'uniform mat4 projectionMatrix;', 'uniform mat4 viewMatrix;', 'uniform mat3 normalMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', '#ifdef USE_INSTANCING', ' attribute mat4 instanceMatrix;', '#endif', '#ifdef USE_INSTANCING_COLOR', ' attribute vec3 instanceColor;', '#endif', 'attribute vec3 position;', 'attribute vec3 normal;', 'attribute vec2 uv;', '#ifdef USE_TANGENT', ' attribute vec4 tangent;', '#endif', '#if defined( USE_COLOR_ALPHA )', ' attribute vec4 color;', '#elif defined( USE_COLOR )', ' attribute vec3 color;', '#endif', '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', ' attribute vec3 morphTarget0;', ' attribute vec3 morphTarget1;', ' attribute vec3 morphTarget2;', ' attribute vec3 morphTarget3;', ' #ifdef USE_MORPHNORMALS', ' attribute vec3 morphNormal0;', ' attribute vec3 morphNormal1;', ' attribute vec3 morphNormal2;', ' attribute vec3 morphNormal3;', ' #else', ' attribute vec3 morphTarget4;', ' attribute vec3 morphTarget5;', ' attribute vec3 morphTarget6;', ' attribute vec3 morphTarget7;', ' #endif', '#endif', '#ifdef USE_SKINNING', ' attribute vec4 skinIndex;', ' attribute vec4 skinWeight;', '#endif', '\n'].filter(filterEmptyLine).join('\n');
  12121. prefixFragment = [customExtensions, generatePrecision(parameters), '#define SHADER_NAME ' + parameters.shaderName, customDefines, parameters.useFog && parameters.fog ? '#define USE_FOG' : '', parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', parameters.map ? '#define USE_MAP' : '', parameters.matcap ? '#define USE_MATCAP' : '', parameters.envMap ? '#define USE_ENVMAP' : '', parameters.envMap ? '#define ' + envMapTypeDefine : '', parameters.envMap ? '#define ' + envMapModeDefine : '', parameters.envMap ? '#define ' + envMapBlendingDefine : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_WIDTH ' + envMapCubeUVSize.texelWidth : '', envMapCubeUVSize ? '#define CUBEUV_TEXEL_HEIGHT ' + envMapCubeUVSize.texelHeight : '', envMapCubeUVSize ? '#define CUBEUV_MAX_MIP ' + envMapCubeUVSize.maxMip + '.0' : '', parameters.lightMap ? '#define USE_LIGHTMAP' : '', parameters.aoMap ? '#define USE_AOMAP' : '', parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', parameters.bumpMap ? '#define USE_BUMPMAP' : '', parameters.normalMap ? '#define USE_NORMALMAP' : '', parameters.normalMap && parameters.objectSpaceNormalMap ? '#define OBJECTSPACE_NORMALMAP' : '', parameters.normalMap && parameters.tangentSpaceNormalMap ? '#define TANGENTSPACE_NORMALMAP' : '', parameters.clearcoat ? '#define USE_CLEARCOAT' : '', parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', parameters.iridescence ? '#define USE_IRIDESCENCE' : '', parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', parameters.specularMap ? '#define USE_SPECULARMAP' : '', parameters.specularIntensityMap ? '#define USE_SPECULARINTENSITYMAP' : '', parameters.specularColorMap ? '#define USE_SPECULARCOLORMAP' : '', parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', parameters.alphaMap ? '#define USE_ALPHAMAP' : '', parameters.alphaTest ? '#define USE_ALPHATEST' : '', parameters.sheen ? '#define USE_SHEEN' : '', parameters.sheenColorMap ? '#define USE_SHEENCOLORMAP' : '', parameters.sheenRoughnessMap ? '#define USE_SHEENROUGHNESSMAP' : '', parameters.transmission ? '#define USE_TRANSMISSION' : '', parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', parameters.vertexTangents ? '#define USE_TANGENT' : '', parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', parameters.vertexUvs ? '#define USE_UV' : '', parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '', parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', parameters.flatShading ? '#define FLAT_SHADED' : '', parameters.doubleSided ? '#define DOUBLE_SIDED' : '', parameters.flipSided ? '#define FLIP_SIDED' : '', parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '', parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '', parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', parameters.logarithmicDepthBuffer && parameters.rendererExtensionFragDepth ? '#define USE_LOGDEPTHBUF_EXT' : '', 'uniform mat4 viewMatrix;', 'uniform vec3 cameraPosition;', 'uniform bool isOrthographic;', parameters.toneMapping !== NoToneMapping ? '#define TONE_MAPPING' : '', parameters.toneMapping !== NoToneMapping ? ShaderChunk['tonemapping_pars_fragment'] : '', // this code is required here because it is used by the toneMapping() function defined below
  12122. parameters.toneMapping !== NoToneMapping ? getToneMappingFunction('toneMapping', parameters.toneMapping) : '', parameters.dithering ? '#define DITHERING' : '', parameters.opaque ? '#define OPAQUE' : '', ShaderChunk['encodings_pars_fragment'], // this code is required here because it is used by the various encoding/decoding function defined below
  12123. getTexelEncodingFunction('linearToOutputTexel', parameters.outputEncoding), parameters.useDepthPacking ? '#define DEPTH_PACKING ' + parameters.depthPacking : '', '\n'].filter(filterEmptyLine).join('\n');
  12124. }
  12125. vertexShader = resolveIncludes(vertexShader);
  12126. vertexShader = replaceLightNums(vertexShader, parameters);
  12127. vertexShader = replaceClippingPlaneNums(vertexShader, parameters);
  12128. fragmentShader = resolveIncludes(fragmentShader);
  12129. fragmentShader = replaceLightNums(fragmentShader, parameters);
  12130. fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters);
  12131. vertexShader = unrollLoops(vertexShader);
  12132. fragmentShader = unrollLoops(fragmentShader);
  12133. if (parameters.isWebGL2 && parameters.isRawShaderMaterial !== true) {
  12134. // GLSL 3.0 conversion for built-in materials and ShaderMaterial
  12135. versionString = '#version 300 es\n';
  12136. prefixVertex = ['precision mediump sampler2DArray;', '#define attribute in', '#define varying out', '#define texture2D texture'].join('\n') + '\n' + prefixVertex;
  12137. prefixFragment = ['#define varying in', parameters.glslVersion === GLSL3 ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;', parameters.glslVersion === GLSL3 ? '' : '#define gl_FragColor pc_fragColor', '#define gl_FragDepthEXT gl_FragDepth', '#define texture2D texture', '#define textureCube texture', '#define texture2DProj textureProj', '#define texture2DLodEXT textureLod', '#define texture2DProjLodEXT textureProjLod', '#define textureCubeLodEXT textureLod', '#define texture2DGradEXT textureGrad', '#define texture2DProjGradEXT textureProjGrad', '#define textureCubeGradEXT textureGrad'].join('\n') + '\n' + prefixFragment;
  12138. }
  12139. const vertexGlsl = versionString + prefixVertex + vertexShader;
  12140. const fragmentGlsl = versionString + prefixFragment + fragmentShader; // console.log( '*VERTEX*', vertexGlsl );
  12141. // console.log( '*FRAGMENT*', fragmentGlsl );
  12142. const glVertexShader = WebGLShader(gl, gl.VERTEX_SHADER, vertexGlsl);
  12143. const glFragmentShader = WebGLShader(gl, gl.FRAGMENT_SHADER, fragmentGlsl);
  12144. gl.attachShader(program, glVertexShader);
  12145. gl.attachShader(program, glFragmentShader); // Force a particular attribute to index 0.
  12146. if (parameters.index0AttributeName !== undefined) {
  12147. gl.bindAttribLocation(program, 0, parameters.index0AttributeName);
  12148. } else if (parameters.morphTargets === true) {
  12149. // programs with morphTargets displace position out of attribute 0
  12150. gl.bindAttribLocation(program, 0, 'position');
  12151. }
  12152. gl.linkProgram(program); // check for link errors
  12153. if (renderer.debug.checkShaderErrors) {
  12154. const programLog = gl.getProgramInfoLog(program).trim();
  12155. const vertexLog = gl.getShaderInfoLog(glVertexShader).trim();
  12156. const fragmentLog = gl.getShaderInfoLog(glFragmentShader).trim();
  12157. let runnable = true;
  12158. let haveDiagnostics = true;
  12159. if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) {
  12160. runnable = false;
  12161. const vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex');
  12162. const fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment');
  12163. console.error('THREE.WebGLProgram: Shader Error ' + gl.getError() + ' - ' + 'VALIDATE_STATUS ' + gl.getProgramParameter(program, gl.VALIDATE_STATUS) + '\n\n' + 'Program Info Log: ' + programLog , '\nvertexErrors: ' + vertexErrors , '\n fragmentErrors: ' + fragmentErrors);
  12164. console.error('错误的shader的fragmentShader(log for mobile)', fragmentShader.slice(0,500))//xzw add for mobile
  12165. } else if (programLog !== '') {
  12166. console.warn('THREE.WebGLProgram: Program Info Log:', programLog);
  12167. } else if (vertexLog === '' || fragmentLog === '') {
  12168. haveDiagnostics = false;
  12169. }
  12170. if (haveDiagnostics) {
  12171. this.diagnostics = {
  12172. runnable: runnable,
  12173. programLog: programLog,
  12174. vertexShader: {
  12175. log: vertexLog,
  12176. prefix: prefixVertex
  12177. },
  12178. fragmentShader: {
  12179. log: fragmentLog,
  12180. prefix: prefixFragment
  12181. }
  12182. };
  12183. }
  12184. } // Clean up
  12185. // Crashes in iOS9 and iOS10. #18402
  12186. // gl.detachShader( program, glVertexShader );
  12187. // gl.detachShader( program, glFragmentShader );
  12188. gl.deleteShader(glVertexShader);
  12189. gl.deleteShader(glFragmentShader); // set up caching for uniform locations
  12190. let cachedUniforms;
  12191. this.getUniforms = function () {
  12192. if (cachedUniforms === undefined) {
  12193. cachedUniforms = new WebGLUniforms(gl, program);
  12194. }
  12195. return cachedUniforms;
  12196. }; // set up caching for attribute locations
  12197. let cachedAttributes;
  12198. this.getAttributes = function () {
  12199. if (cachedAttributes === undefined) {
  12200. cachedAttributes = fetchAttributeLocations(gl, program);
  12201. }
  12202. return cachedAttributes;
  12203. }; // free resource
  12204. this.destroy = function () {
  12205. bindingStates.releaseStatesOfProgram(this);
  12206. gl.deleteProgram(program);
  12207. this.program = undefined;
  12208. }; //
  12209. this.name = parameters.shaderName;
  12210. this.id = programIdCount++;
  12211. this.cacheKey = cacheKey;
  12212. this.usedTimes = 1;
  12213. this.program = program;
  12214. this.vertexShader = glVertexShader;
  12215. this.fragmentShader = glFragmentShader;
  12216. return this;
  12217. }
  12218. let _id = 0;
  12219. class WebGLShaderCache {
  12220. constructor() {
  12221. this.shaderCache = new Map();
  12222. this.materialCache = new Map();
  12223. }
  12224. update(material) {
  12225. const vertexShader = material.vertexShader;
  12226. const fragmentShader = material.fragmentShader;
  12227. const vertexShaderStage = this._getShaderStage(vertexShader);
  12228. const fragmentShaderStage = this._getShaderStage(fragmentShader);
  12229. const materialShaders = this._getShaderCacheForMaterial(material);
  12230. if (materialShaders.has(vertexShaderStage) === false) {
  12231. materialShaders.add(vertexShaderStage);
  12232. vertexShaderStage.usedTimes++;
  12233. }
  12234. if (materialShaders.has(fragmentShaderStage) === false) {
  12235. materialShaders.add(fragmentShaderStage);
  12236. fragmentShaderStage.usedTimes++;
  12237. }
  12238. return this;
  12239. }
  12240. remove(material) {
  12241. const materialShaders = this.materialCache.get(material);
  12242. for (const shaderStage of materialShaders) {
  12243. shaderStage.usedTimes--;
  12244. if (shaderStage.usedTimes === 0) this.shaderCache.delete(shaderStage.code);
  12245. }
  12246. this.materialCache.delete(material);
  12247. return this;
  12248. }
  12249. getVertexShaderID(material) {
  12250. return this._getShaderStage(material.vertexShader).id;
  12251. }
  12252. getFragmentShaderID(material) {
  12253. return this._getShaderStage(material.fragmentShader).id;
  12254. }
  12255. dispose() {
  12256. this.shaderCache.clear();
  12257. this.materialCache.clear();
  12258. }
  12259. _getShaderCacheForMaterial(material) {
  12260. const cache = this.materialCache;
  12261. if (cache.has(material) === false) {
  12262. cache.set(material, new Set());
  12263. }
  12264. return cache.get(material);
  12265. }
  12266. _getShaderStage(code) {
  12267. const cache = this.shaderCache;
  12268. if (cache.has(code) === false) {
  12269. const stage = new WebGLShaderStage(code);
  12270. cache.set(code, stage);
  12271. }
  12272. return cache.get(code);
  12273. }
  12274. }
  12275. class WebGLShaderStage {
  12276. constructor(code) {
  12277. this.id = _id++;
  12278. this.code = code;
  12279. this.usedTimes = 0;
  12280. }
  12281. }
  12282. function WebGLPrograms(renderer, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping) {
  12283. const _programLayers = new Layers();
  12284. const _customShaders = new WebGLShaderCache();
  12285. const programs = [];
  12286. const isWebGL2 = capabilities.isWebGL2;
  12287. const logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
  12288. const vertexTextures = capabilities.vertexTextures;
  12289. let precision = capabilities.precision;
  12290. const shaderIDs = {
  12291. MeshDepthMaterial: 'depth',
  12292. MeshDistanceMaterial: 'distanceRGBA',
  12293. MeshNormalMaterial: 'normal',
  12294. MeshBasicMaterial: 'basic',
  12295. MeshLambertMaterial: 'lambert',
  12296. MeshPhongMaterial: 'phong',
  12297. MeshToonMaterial: 'toon',
  12298. MeshStandardMaterial: 'physical',
  12299. MeshPhysicalMaterial: 'physical',
  12300. MeshMatcapMaterial: 'matcap',
  12301. LineBasicMaterial: 'basic',
  12302. LineDashedMaterial: 'dashed',
  12303. PointsMaterial: 'points',
  12304. ShadowMaterial: 'shadow',
  12305. SpriteMaterial: 'sprite'
  12306. };
  12307. function getParameters(material, lights, shadows, scene, object) {
  12308. const fog = scene.fog;
  12309. const geometry = object.geometry;
  12310. const environment = material.isMeshStandardMaterial ? scene.environment : null;
  12311. const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
  12312. const envMapCubeUVHeight = !!envMap && envMap.mapping === CubeUVReflectionMapping ? envMap.image.height : null;
  12313. const shaderID = shaderIDs[material.type]; // heuristics to create shader parameters according to lights in the scene
  12314. // (not to blow over maxLights budget)
  12315. if (material.precision !== null) {
  12316. precision = capabilities.getMaxPrecision(material.precision);
  12317. if (precision !== material.precision) {
  12318. console.warn('THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.');
  12319. }
  12320. } //
  12321. const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
  12322. const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
  12323. let morphTextureStride = 0;
  12324. if (geometry.morphAttributes.position !== undefined) morphTextureStride = 1;
  12325. if (geometry.morphAttributes.normal !== undefined) morphTextureStride = 2;
  12326. if (geometry.morphAttributes.color !== undefined) morphTextureStride = 3; //
  12327. let vertexShader, fragmentShader;
  12328. let customVertexShaderID, customFragmentShaderID;
  12329. if (shaderID) {
  12330. const shader = ShaderLib[shaderID];
  12331. vertexShader = shader.vertexShader;
  12332. fragmentShader = shader.fragmentShader;
  12333. } else {
  12334. vertexShader = material.vertexShader;
  12335. fragmentShader = material.fragmentShader;
  12336. _customShaders.update(material);
  12337. customVertexShaderID = _customShaders.getVertexShaderID(material);
  12338. customFragmentShaderID = _customShaders.getFragmentShaderID(material);
  12339. }
  12340. const currentRenderTarget = renderer.getRenderTarget();
  12341. const useAlphaTest = material.alphaTest > 0;
  12342. const useClearcoat = material.clearcoat > 0;
  12343. const useIridescence = material.iridescence > 0;
  12344. const parameters = {
  12345. isWebGL2: isWebGL2,
  12346. shaderID: shaderID,
  12347. shaderName: material.type,
  12348. vertexShader: vertexShader,
  12349. fragmentShader: fragmentShader,
  12350. defines: material.defines,
  12351. customVertexShaderID: customVertexShaderID,
  12352. customFragmentShaderID: customFragmentShaderID,
  12353. isRawShaderMaterial: material.isRawShaderMaterial === true,
  12354. glslVersion: material.glslVersion,
  12355. precision: precision,
  12356. instancing: object.isInstancedMesh === true,
  12357. instancingColor: object.isInstancedMesh === true && object.instanceColor !== null,
  12358. supportsVertexTextures: vertexTextures,
  12359. outputEncoding: currentRenderTarget === null ? renderer.outputEncoding : currentRenderTarget.isXRRenderTarget === true ? currentRenderTarget.texture.encoding : LinearEncoding,
  12360. map: !!material.map,
  12361. matcap: !!material.matcap,
  12362. envMap: !!envMap,
  12363. envMapMode: envMap && envMap.mapping,
  12364. envMapCubeUVHeight: envMapCubeUVHeight,
  12365. lightMap: !!material.lightMap,
  12366. aoMap: !!material.aoMap,
  12367. emissiveMap: !!material.emissiveMap,
  12368. bumpMap: !!material.bumpMap,
  12369. normalMap: !!material.normalMap,
  12370. objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,
  12371. tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,
  12372. decodeVideoTexture: !!material.map && material.map.isVideoTexture === true && material.map.encoding === sRGBEncoding,
  12373. clearcoat: useClearcoat,
  12374. clearcoatMap: useClearcoat && !!material.clearcoatMap,
  12375. clearcoatRoughnessMap: useClearcoat && !!material.clearcoatRoughnessMap,
  12376. clearcoatNormalMap: useClearcoat && !!material.clearcoatNormalMap,
  12377. iridescence: useIridescence,
  12378. iridescenceMap: useIridescence && !!material.iridescenceMap,
  12379. iridescenceThicknessMap: useIridescence && !!material.iridescenceThicknessMap,
  12380. displacementMap: !!material.displacementMap,
  12381. roughnessMap: !!material.roughnessMap,
  12382. metalnessMap: !!material.metalnessMap,
  12383. specularMap: !!material.specularMap,
  12384. specularIntensityMap: !!material.specularIntensityMap,
  12385. specularColorMap: !!material.specularColorMap,
  12386. opaque: material.transparent === false && material.blending === NormalBlending,
  12387. alphaMap: !!material.alphaMap,
  12388. alphaTest: useAlphaTest,
  12389. gradientMap: !!material.gradientMap,
  12390. sheen: material.sheen > 0,
  12391. sheenColorMap: !!material.sheenColorMap,
  12392. sheenRoughnessMap: !!material.sheenRoughnessMap,
  12393. transmission: material.transmission > 0,
  12394. transmissionMap: !!material.transmissionMap,
  12395. thicknessMap: !!material.thicknessMap,
  12396. combine: material.combine,
  12397. vertexTangents: !!material.normalMap && !!geometry.attributes.tangent,
  12398. vertexColors: material.vertexColors,
  12399. vertexAlphas: material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4,
  12400. vertexUvs: !!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatMap || !!material.clearcoatRoughnessMap || !!material.clearcoatNormalMap || !!material.iridescenceMap || !!material.iridescenceThicknessMap || !!material.displacementMap || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularColorMap || !!material.sheenColorMap || !!material.sheenRoughnessMap,
  12401. uvsVertexOnly: !(!!material.map || !!material.bumpMap || !!material.normalMap || !!material.specularMap || !!material.alphaMap || !!material.emissiveMap || !!material.roughnessMap || !!material.metalnessMap || !!material.clearcoatNormalMap || !!material.iridescenceMap || !!material.iridescenceThicknessMap || material.transmission > 0 || !!material.transmissionMap || !!material.thicknessMap || !!material.specularIntensityMap || !!material.specularColorMap || material.sheen > 0 || !!material.sheenColorMap || !!material.sheenRoughnessMap) && !!material.displacementMap,
  12402. fog: !!fog,
  12403. useFog: material.fog === true,
  12404. fogExp2: fog && fog.isFogExp2,
  12405. flatShading: !!material.flatShading,
  12406. sizeAttenuation: material.sizeAttenuation,
  12407. logarithmicDepthBuffer: logarithmicDepthBuffer,
  12408. skinning: object.isSkinnedMesh === true,
  12409. morphTargets: geometry.morphAttributes.position !== undefined,
  12410. morphNormals: geometry.morphAttributes.normal !== undefined,
  12411. morphColors: geometry.morphAttributes.color !== undefined,
  12412. morphTargetsCount: morphTargetsCount,
  12413. morphTextureStride: morphTextureStride,
  12414. numDirLights: lights.directional.length,
  12415. numPointLights: lights.point.length,
  12416. numSpotLights: lights.spot.length,
  12417. numRectAreaLights: lights.rectArea.length,
  12418. numHemiLights: lights.hemi.length,
  12419. numDirLightShadows: lights.directionalShadowMap.length,
  12420. numPointLightShadows: lights.pointShadowMap.length,
  12421. numSpotLightShadows: lights.spotShadowMap.length,
  12422. numClippingPlanes: clipping.numPlanes,
  12423. numClipIntersection: clipping.numIntersection,
  12424. dithering: material.dithering,
  12425. shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
  12426. shadowMapType: renderer.shadowMap.type,
  12427. toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
  12428. physicallyCorrectLights: renderer.physicallyCorrectLights,
  12429. premultipliedAlpha: material.premultipliedAlpha,
  12430. doubleSided: material.side === DoubleSide,
  12431. flipSided: material.side === BackSide,
  12432. useDepthPacking: !!material.depthPacking,
  12433. depthPacking: material.depthPacking || 0,
  12434. index0AttributeName: material.index0AttributeName,
  12435. extensionDerivatives: material.extensions && material.extensions.derivatives,
  12436. extensionFragDepth: material.extensions && material.extensions.fragDepth,
  12437. extensionDrawBuffers: material.extensions && material.extensions.drawBuffers,
  12438. extensionShaderTextureLOD: material.extensions && material.extensions.shaderTextureLOD,
  12439. rendererExtensionFragDepth: isWebGL2 || extensions.has('EXT_frag_depth'),
  12440. rendererExtensionDrawBuffers: isWebGL2 || extensions.has('WEBGL_draw_buffers'),
  12441. rendererExtensionShaderTextureLod: isWebGL2 || extensions.has('EXT_shader_texture_lod'),
  12442. customProgramCacheKey: material.customProgramCacheKey()
  12443. };
  12444. return parameters;
  12445. }
  12446. function getProgramCacheKey(parameters) {
  12447. const array = [];
  12448. if (parameters.shaderID) {
  12449. array.push(parameters.shaderID);
  12450. } else {
  12451. array.push(parameters.customVertexShaderID);
  12452. array.push(parameters.customFragmentShaderID);
  12453. }
  12454. if (parameters.defines !== undefined) {
  12455. for (const name in parameters.defines) {
  12456. array.push(name);
  12457. array.push(parameters.defines[name]);
  12458. }
  12459. }
  12460. if (parameters.isRawShaderMaterial === false) {
  12461. getProgramCacheKeyParameters(array, parameters);
  12462. getProgramCacheKeyBooleans(array, parameters);
  12463. array.push(renderer.outputEncoding);
  12464. }
  12465. array.push(parameters.customProgramCacheKey);
  12466. return array.join();
  12467. }
  12468. function getProgramCacheKeyParameters(array, parameters) {
  12469. array.push(parameters.precision);
  12470. array.push(parameters.outputEncoding);
  12471. array.push(parameters.envMapMode);
  12472. array.push(parameters.envMapCubeUVHeight);
  12473. array.push(parameters.combine);
  12474. array.push(parameters.vertexUvs);
  12475. array.push(parameters.fogExp2);
  12476. array.push(parameters.sizeAttenuation);
  12477. array.push(parameters.morphTargetsCount);
  12478. array.push(parameters.morphAttributeCount);
  12479. array.push(parameters.numDirLights);
  12480. array.push(parameters.numPointLights);
  12481. array.push(parameters.numSpotLights);
  12482. array.push(parameters.numHemiLights);
  12483. array.push(parameters.numRectAreaLights);
  12484. array.push(parameters.numDirLightShadows);
  12485. array.push(parameters.numPointLightShadows);
  12486. array.push(parameters.numSpotLightShadows);
  12487. array.push(parameters.shadowMapType);
  12488. array.push(parameters.toneMapping);
  12489. array.push(parameters.numClippingPlanes);
  12490. array.push(parameters.numClipIntersection);
  12491. array.push(parameters.depthPacking);
  12492. }
  12493. function getProgramCacheKeyBooleans(array, parameters) {
  12494. _programLayers.disableAll();
  12495. if (parameters.isWebGL2) _programLayers.enable(0);
  12496. if (parameters.supportsVertexTextures) _programLayers.enable(1);
  12497. if (parameters.instancing) _programLayers.enable(2);
  12498. if (parameters.instancingColor) _programLayers.enable(3);
  12499. if (parameters.map) _programLayers.enable(4);
  12500. if (parameters.matcap) _programLayers.enable(5);
  12501. if (parameters.envMap) _programLayers.enable(6);
  12502. if (parameters.lightMap) _programLayers.enable(7);
  12503. if (parameters.aoMap) _programLayers.enable(8);
  12504. if (parameters.emissiveMap) _programLayers.enable(9);
  12505. if (parameters.bumpMap) _programLayers.enable(10);
  12506. if (parameters.normalMap) _programLayers.enable(11);
  12507. if (parameters.objectSpaceNormalMap) _programLayers.enable(12);
  12508. if (parameters.tangentSpaceNormalMap) _programLayers.enable(13);
  12509. if (parameters.clearcoat) _programLayers.enable(14);
  12510. if (parameters.clearcoatMap) _programLayers.enable(15);
  12511. if (parameters.clearcoatRoughnessMap) _programLayers.enable(16);
  12512. if (parameters.clearcoatNormalMap) _programLayers.enable(17);
  12513. if (parameters.iridescence) _programLayers.enable(18);
  12514. if (parameters.iridescenceMap) _programLayers.enable(19);
  12515. if (parameters.iridescenceThicknessMap) _programLayers.enable(20);
  12516. if (parameters.displacementMap) _programLayers.enable(21);
  12517. if (parameters.specularMap) _programLayers.enable(22);
  12518. if (parameters.roughnessMap) _programLayers.enable(23);
  12519. if (parameters.metalnessMap) _programLayers.enable(24);
  12520. if (parameters.gradientMap) _programLayers.enable(25);
  12521. if (parameters.alphaMap) _programLayers.enable(26);
  12522. if (parameters.alphaTest) _programLayers.enable(27);
  12523. if (parameters.vertexColors) _programLayers.enable(28);
  12524. if (parameters.vertexAlphas) _programLayers.enable(29);
  12525. if (parameters.vertexUvs) _programLayers.enable(30);
  12526. if (parameters.vertexTangents) _programLayers.enable(31);
  12527. if (parameters.uvsVertexOnly) _programLayers.enable(32);
  12528. if (parameters.fog) _programLayers.enable(33);
  12529. array.push(_programLayers.mask);
  12530. _programLayers.disableAll();
  12531. if (parameters.useFog) _programLayers.enable(0);
  12532. if (parameters.flatShading) _programLayers.enable(1);
  12533. if (parameters.logarithmicDepthBuffer) _programLayers.enable(2);
  12534. if (parameters.skinning) _programLayers.enable(3);
  12535. if (parameters.morphTargets) _programLayers.enable(4);
  12536. if (parameters.morphNormals) _programLayers.enable(5);
  12537. if (parameters.morphColors) _programLayers.enable(6);
  12538. if (parameters.premultipliedAlpha) _programLayers.enable(7);
  12539. if (parameters.shadowMapEnabled) _programLayers.enable(8);
  12540. if (parameters.physicallyCorrectLights) _programLayers.enable(9);
  12541. if (parameters.doubleSided) _programLayers.enable(10);
  12542. if (parameters.flipSided) _programLayers.enable(11);
  12543. if (parameters.useDepthPacking) _programLayers.enable(12);
  12544. if (parameters.dithering) _programLayers.enable(13);
  12545. if (parameters.specularIntensityMap) _programLayers.enable(14);
  12546. if (parameters.specularColorMap) _programLayers.enable(15);
  12547. if (parameters.transmission) _programLayers.enable(16);
  12548. if (parameters.transmissionMap) _programLayers.enable(17);
  12549. if (parameters.thicknessMap) _programLayers.enable(18);
  12550. if (parameters.sheen) _programLayers.enable(19);
  12551. if (parameters.sheenColorMap) _programLayers.enable(20);
  12552. if (parameters.sheenRoughnessMap) _programLayers.enable(21);
  12553. if (parameters.decodeVideoTexture) _programLayers.enable(22);
  12554. if (parameters.opaque) _programLayers.enable(23);
  12555. array.push(_programLayers.mask);
  12556. }
  12557. function getUniforms(material) {
  12558. const shaderID = shaderIDs[material.type];
  12559. let uniforms;
  12560. if (shaderID) {
  12561. const shader = ShaderLib[shaderID];
  12562. uniforms = UniformsUtils.clone(shader.uniforms);
  12563. } else {
  12564. uniforms = material.uniforms;
  12565. }
  12566. return uniforms;
  12567. }
  12568. function acquireProgram(parameters, cacheKey) {
  12569. let program; // Check if code has been already compiled
  12570. for (let p = 0, pl = programs.length; p < pl; p++) {
  12571. const preexistingProgram = programs[p];
  12572. if (preexistingProgram.cacheKey === cacheKey) {
  12573. program = preexistingProgram;
  12574. ++program.usedTimes;
  12575. break;
  12576. }
  12577. }
  12578. if (program === undefined) {
  12579. program = new WebGLProgram(renderer, cacheKey, parameters, bindingStates);
  12580. programs.push(program);
  12581. }
  12582. return program;
  12583. }
  12584. function releaseProgram(program) {
  12585. if (--program.usedTimes === 0) {
  12586. // Remove from unordered set
  12587. const i = programs.indexOf(program);
  12588. programs[i] = programs[programs.length - 1];
  12589. programs.pop(); // Free WebGL resources
  12590. program.destroy();
  12591. }
  12592. }
  12593. function releaseShaderCache(material) {
  12594. _customShaders.remove(material);
  12595. }
  12596. function dispose() {
  12597. _customShaders.dispose();
  12598. }
  12599. return {
  12600. getParameters: getParameters,
  12601. getProgramCacheKey: getProgramCacheKey,
  12602. getUniforms: getUniforms,
  12603. acquireProgram: acquireProgram,
  12604. releaseProgram: releaseProgram,
  12605. releaseShaderCache: releaseShaderCache,
  12606. // Exposed for resource monitoring & error feedback via renderer.info:
  12607. programs: programs,
  12608. dispose: dispose
  12609. };
  12610. }
  12611. function WebGLProperties() {
  12612. let properties = new WeakMap();
  12613. function get(object) {
  12614. let map = properties.get(object);
  12615. if (map === undefined) {
  12616. map = {};
  12617. properties.set(object, map);
  12618. }
  12619. return map;
  12620. }
  12621. function remove(object) {
  12622. properties.delete(object);
  12623. }
  12624. function update(object, key, value) {
  12625. properties.get(object)[key] = value;
  12626. }
  12627. function dispose() {
  12628. properties = new WeakMap();
  12629. }
  12630. return {
  12631. get: get,
  12632. remove: remove,
  12633. update: update,
  12634. dispose: dispose
  12635. };
  12636. }
  12637. function painterSortStable(a, b) {
  12638. if (a.groupOrder !== b.groupOrder) {
  12639. return a.groupOrder - b.groupOrder;
  12640. } else if (a.renderOrder !== b.renderOrder) {
  12641. return a.renderOrder - b.renderOrder;
  12642. } else if (a.material.id !== b.material.id) {
  12643. return a.material.id - b.material.id;
  12644. } else if (a.z !== b.z) {
  12645. return a.z - b.z;
  12646. } else {
  12647. return a.id - b.id;
  12648. }
  12649. }
  12650. function reversePainterSortStable(a, b) {
  12651. if (a.groupOrder !== b.groupOrder) {
  12652. return a.groupOrder - b.groupOrder;
  12653. } else if (a.renderOrder !== b.renderOrder) {
  12654. return a.renderOrder - b.renderOrder;
  12655. } else if (a.z !== b.z) {
  12656. return b.z - a.z;
  12657. } else {
  12658. return a.id - b.id;
  12659. }
  12660. }
  12661. function WebGLRenderList() {
  12662. const renderItems = [];
  12663. let renderItemsIndex = 0;
  12664. const opaque = [];
  12665. const transmissive = [];
  12666. const transparent = [];
  12667. function init() {
  12668. renderItemsIndex = 0;
  12669. opaque.length = 0;
  12670. transmissive.length = 0;
  12671. transparent.length = 0;
  12672. }
  12673. function getNextRenderItem(object, geometry, material, groupOrder, z, group) {
  12674. let renderItem = renderItems[renderItemsIndex];
  12675. if (renderItem === undefined) {
  12676. renderItem = {
  12677. id: object.id,
  12678. object: object,
  12679. geometry: geometry,
  12680. material: material,
  12681. groupOrder: groupOrder,
  12682. renderOrder: object.renderOrder,
  12683. z: z,
  12684. group: group
  12685. };
  12686. renderItems[renderItemsIndex] = renderItem;
  12687. } else {
  12688. renderItem.id = object.id;
  12689. renderItem.object = object;
  12690. renderItem.geometry = geometry;
  12691. renderItem.material = material;
  12692. renderItem.groupOrder = groupOrder;
  12693. renderItem.renderOrder = object.renderOrder;
  12694. renderItem.z = z;
  12695. renderItem.group = group;
  12696. }
  12697. renderItemsIndex++;
  12698. return renderItem;
  12699. }
  12700. function push(object, geometry, material, groupOrder, z, group) {
  12701. const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
  12702. if (material.transmission > 0.0) {
  12703. transmissive.push(renderItem);
  12704. } else if (material.transparent === true) {
  12705. transparent.push(renderItem);
  12706. } else {
  12707. opaque.push(renderItem);
  12708. }
  12709. }
  12710. function unshift(object, geometry, material, groupOrder, z, group) {
  12711. const renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group);
  12712. if (material.transmission > 0.0) {
  12713. transmissive.unshift(renderItem);
  12714. } else if (material.transparent === true) {
  12715. transparent.unshift(renderItem);
  12716. } else {
  12717. opaque.unshift(renderItem);
  12718. }
  12719. }
  12720. function sort(customOpaqueSort, customTransparentSort) {
  12721. if (opaque.length > 1) opaque.sort(customOpaqueSort || painterSortStable);
  12722. if (transmissive.length > 1) transmissive.sort(customTransparentSort || reversePainterSortStable);
  12723. if (transparent.length > 1) transparent.sort(customTransparentSort || reversePainterSortStable);
  12724. }
  12725. function finish() {
  12726. // Clear references from inactive renderItems in the list
  12727. for (let i = renderItemsIndex, il = renderItems.length; i < il; i++) {
  12728. const renderItem = renderItems[i];
  12729. if (renderItem.id === null) break;
  12730. renderItem.id = null;
  12731. renderItem.object = null;
  12732. renderItem.geometry = null;
  12733. renderItem.material = null;
  12734. renderItem.group = null;
  12735. }
  12736. }
  12737. return {
  12738. opaque: opaque,
  12739. transmissive: transmissive,
  12740. transparent: transparent,
  12741. init: init,
  12742. push: push,
  12743. unshift: unshift,
  12744. finish: finish,
  12745. sort: sort
  12746. };
  12747. }
  12748. function WebGLRenderLists() {
  12749. let lists = new WeakMap();
  12750. function get(scene, renderCallDepth) {
  12751. let list;
  12752. if (lists.has(scene) === false) {
  12753. list = new WebGLRenderList();
  12754. lists.set(scene, [list]);
  12755. } else {
  12756. if (renderCallDepth >= lists.get(scene).length) {
  12757. list = new WebGLRenderList();
  12758. lists.get(scene).push(list);
  12759. } else {
  12760. list = lists.get(scene)[renderCallDepth];
  12761. }
  12762. }
  12763. return list;
  12764. }
  12765. function dispose() {
  12766. lists = new WeakMap();
  12767. }
  12768. return {
  12769. get: get,
  12770. dispose: dispose
  12771. };
  12772. }
  12773. function UniformsCache() {
  12774. const lights = {};
  12775. return {
  12776. get: function (light) {
  12777. if (lights[light.id] !== undefined) {
  12778. return lights[light.id];
  12779. }
  12780. let uniforms;
  12781. switch (light.type) {
  12782. case 'DirectionalLight':
  12783. uniforms = {
  12784. direction: new Vector3(),
  12785. color: new Color()
  12786. };
  12787. break;
  12788. case 'SpotLight':
  12789. uniforms = {
  12790. position: new Vector3(),
  12791. direction: new Vector3(),
  12792. color: new Color(),
  12793. distance: 0,
  12794. coneCos: 0,
  12795. penumbraCos: 0,
  12796. decay: 0
  12797. };
  12798. break;
  12799. case 'PointLight':
  12800. uniforms = {
  12801. position: new Vector3(),
  12802. color: new Color(),
  12803. distance: 0,
  12804. decay: 0
  12805. };
  12806. break;
  12807. case 'HemisphereLight':
  12808. uniforms = {
  12809. direction: new Vector3(),
  12810. skyColor: new Color(),
  12811. groundColor: new Color()
  12812. };
  12813. break;
  12814. case 'RectAreaLight':
  12815. uniforms = {
  12816. color: new Color(),
  12817. position: new Vector3(),
  12818. halfWidth: new Vector3(),
  12819. halfHeight: new Vector3()
  12820. };
  12821. break;
  12822. }
  12823. lights[light.id] = uniforms;
  12824. return uniforms;
  12825. }
  12826. };
  12827. }
  12828. function ShadowUniformsCache() {
  12829. const lights = {};
  12830. return {
  12831. get: function (light) {
  12832. if (lights[light.id] !== undefined) {
  12833. return lights[light.id];
  12834. }
  12835. let uniforms;
  12836. switch (light.type) {
  12837. case 'DirectionalLight':
  12838. uniforms = {
  12839. shadowBias: 0,
  12840. shadowNormalBias: 0,
  12841. shadowRadius: 1,
  12842. shadowMapSize: new Vector2()
  12843. };
  12844. break;
  12845. case 'SpotLight':
  12846. uniforms = {
  12847. shadowBias: 0,
  12848. shadowNormalBias: 0,
  12849. shadowRadius: 1,
  12850. shadowMapSize: new Vector2()
  12851. };
  12852. break;
  12853. case 'PointLight':
  12854. uniforms = {
  12855. shadowBias: 0,
  12856. shadowNormalBias: 0,
  12857. shadowRadius: 1,
  12858. shadowMapSize: new Vector2(),
  12859. shadowCameraNear: 1,
  12860. shadowCameraFar: 1000
  12861. };
  12862. break;
  12863. // TODO (abelnation): set RectAreaLight shadow uniforms
  12864. }
  12865. lights[light.id] = uniforms;
  12866. return uniforms;
  12867. }
  12868. };
  12869. }
  12870. let nextVersion = 0;
  12871. function shadowCastingLightsFirst(lightA, lightB) {
  12872. return (lightB.castShadow ? 1 : 0) - (lightA.castShadow ? 1 : 0);
  12873. }
  12874. function WebGLLights(extensions, capabilities) {
  12875. const cache = new UniformsCache();
  12876. const shadowCache = ShadowUniformsCache();
  12877. const state = {
  12878. version: 0,
  12879. hash: {
  12880. directionalLength: -1,
  12881. pointLength: -1,
  12882. spotLength: -1,
  12883. rectAreaLength: -1,
  12884. hemiLength: -1,
  12885. numDirectionalShadows: -1,
  12886. numPointShadows: -1,
  12887. numSpotShadows: -1
  12888. },
  12889. ambient: [0, 0, 0],
  12890. probe: [],
  12891. directional: [],
  12892. directionalShadow: [],
  12893. directionalShadowMap: [],
  12894. directionalShadowMatrix: [],
  12895. spot: [],
  12896. spotShadow: [],
  12897. spotShadowMap: [],
  12898. spotShadowMatrix: [],
  12899. rectArea: [],
  12900. rectAreaLTC1: null,
  12901. rectAreaLTC2: null,
  12902. point: [],
  12903. pointShadow: [],
  12904. pointShadowMap: [],
  12905. pointShadowMatrix: [],
  12906. hemi: []
  12907. };
  12908. for (let i = 0; i < 9; i++) state.probe.push(new Vector3());
  12909. const vector3 = new Vector3();
  12910. const matrix4 = new Matrix4();
  12911. const matrix42 = new Matrix4();
  12912. function setup(lights, physicallyCorrectLights) {
  12913. let r = 0,
  12914. g = 0,
  12915. b = 0;
  12916. for (let i = 0; i < 9; i++) state.probe[i].set(0, 0, 0);
  12917. let directionalLength = 0;
  12918. let pointLength = 0;
  12919. let spotLength = 0;
  12920. let rectAreaLength = 0;
  12921. let hemiLength = 0;
  12922. let numDirectionalShadows = 0;
  12923. let numPointShadows = 0;
  12924. let numSpotShadows = 0;
  12925. lights.sort(shadowCastingLightsFirst); // artist-friendly light intensity scaling factor
  12926. const scaleFactor = physicallyCorrectLights !== true ? Math.PI : 1;
  12927. for (let i = 0, l = lights.length; i < l; i++) {
  12928. const light = lights[i];
  12929. const color = light.color;
  12930. const intensity = light.intensity;
  12931. const distance = light.distance;
  12932. const shadowMap = light.shadow && light.shadow.map ? light.shadow.map.texture : null;
  12933. if (light.isAmbientLight) {
  12934. r += color.r * intensity * scaleFactor;
  12935. g += color.g * intensity * scaleFactor;
  12936. b += color.b * intensity * scaleFactor;
  12937. } else if (light.isLightProbe) {
  12938. for (let j = 0; j < 9; j++) {
  12939. state.probe[j].addScaledVector(light.sh.coefficients[j], intensity);
  12940. }
  12941. } else if (light.isDirectionalLight) {
  12942. const uniforms = cache.get(light);
  12943. uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor);
  12944. if (light.castShadow) {
  12945. const shadow = light.shadow;
  12946. const shadowUniforms = shadowCache.get(light);
  12947. shadowUniforms.shadowBias = shadow.bias;
  12948. shadowUniforms.shadowNormalBias = shadow.normalBias;
  12949. shadowUniforms.shadowRadius = shadow.radius;
  12950. shadowUniforms.shadowMapSize = shadow.mapSize;
  12951. state.directionalShadow[directionalLength] = shadowUniforms;
  12952. state.directionalShadowMap[directionalLength] = shadowMap;
  12953. state.directionalShadowMatrix[directionalLength] = light.shadow.matrix;
  12954. numDirectionalShadows++;
  12955. }
  12956. state.directional[directionalLength] = uniforms;
  12957. directionalLength++;
  12958. } else if (light.isSpotLight) {
  12959. const uniforms = cache.get(light);
  12960. uniforms.position.setFromMatrixPosition(light.matrixWorld);
  12961. uniforms.color.copy(color).multiplyScalar(intensity * scaleFactor);
  12962. uniforms.distance = distance;
  12963. uniforms.coneCos = Math.cos(light.angle);
  12964. uniforms.penumbraCos = Math.cos(light.angle * (1 - light.penumbra));
  12965. uniforms.decay = light.decay;
  12966. if (light.castShadow) {
  12967. const shadow = light.shadow;
  12968. const shadowUniforms = shadowCache.get(light);
  12969. shadowUniforms.shadowBias = shadow.bias;
  12970. shadowUniforms.shadowNormalBias = shadow.normalBias;
  12971. shadowUniforms.shadowRadius = shadow.radius;
  12972. shadowUniforms.shadowMapSize = shadow.mapSize;
  12973. state.spotShadow[spotLength] = shadowUniforms;
  12974. state.spotShadowMap[spotLength] = shadowMap;
  12975. state.spotShadowMatrix[spotLength] = light.shadow.matrix;
  12976. numSpotShadows++;
  12977. }
  12978. state.spot[spotLength] = uniforms;
  12979. spotLength++;
  12980. } else if (light.isRectAreaLight) {
  12981. const uniforms = cache.get(light); // (a) intensity is the total visible light emitted
  12982. //uniforms.color.copy( color ).multiplyScalar( intensity / ( light.width * light.height * Math.PI ) );
  12983. // (b) intensity is the brightness of the light
  12984. uniforms.color.copy(color).multiplyScalar(intensity);
  12985. uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
  12986. uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0);
  12987. state.rectArea[rectAreaLength] = uniforms;
  12988. rectAreaLength++;
  12989. } else if (light.isPointLight) {
  12990. const uniforms = cache.get(light);
  12991. uniforms.color.copy(light.color).multiplyScalar(light.intensity * scaleFactor);
  12992. uniforms.distance = light.distance;
  12993. uniforms.decay = light.decay;
  12994. if (light.castShadow) {
  12995. const shadow = light.shadow;
  12996. const shadowUniforms = shadowCache.get(light);
  12997. shadowUniforms.shadowBias = shadow.bias;
  12998. shadowUniforms.shadowNormalBias = shadow.normalBias;
  12999. shadowUniforms.shadowRadius = shadow.radius;
  13000. shadowUniforms.shadowMapSize = shadow.mapSize;
  13001. shadowUniforms.shadowCameraNear = shadow.camera.near;
  13002. shadowUniforms.shadowCameraFar = shadow.camera.far;
  13003. state.pointShadow[pointLength] = shadowUniforms;
  13004. state.pointShadowMap[pointLength] = shadowMap;
  13005. state.pointShadowMatrix[pointLength] = light.shadow.matrix;
  13006. numPointShadows++;
  13007. }
  13008. state.point[pointLength] = uniforms;
  13009. pointLength++;
  13010. } else if (light.isHemisphereLight) {
  13011. const uniforms = cache.get(light);
  13012. uniforms.skyColor.copy(light.color).multiplyScalar(intensity * scaleFactor);
  13013. uniforms.groundColor.copy(light.groundColor).multiplyScalar(intensity * scaleFactor);
  13014. state.hemi[hemiLength] = uniforms;
  13015. hemiLength++;
  13016. }
  13017. }
  13018. if (rectAreaLength > 0) {
  13019. if (capabilities.isWebGL2) {
  13020. // WebGL 2
  13021. state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
  13022. state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
  13023. } else {
  13024. // WebGL 1
  13025. if (extensions.has('OES_texture_float_linear') === true) {
  13026. state.rectAreaLTC1 = UniformsLib.LTC_FLOAT_1;
  13027. state.rectAreaLTC2 = UniformsLib.LTC_FLOAT_2;
  13028. } else if (extensions.has('OES_texture_half_float_linear') === true) {
  13029. state.rectAreaLTC1 = UniformsLib.LTC_HALF_1;
  13030. state.rectAreaLTC2 = UniformsLib.LTC_HALF_2;
  13031. } else {
  13032. console.error('THREE.WebGLRenderer: Unable to use RectAreaLight. Missing WebGL extensions.');
  13033. }
  13034. }
  13035. }
  13036. state.ambient[0] = r;
  13037. state.ambient[1] = g;
  13038. state.ambient[2] = b;
  13039. const hash = state.hash;
  13040. if (hash.directionalLength !== directionalLength || hash.pointLength !== pointLength || hash.spotLength !== spotLength || hash.rectAreaLength !== rectAreaLength || hash.hemiLength !== hemiLength || hash.numDirectionalShadows !== numDirectionalShadows || hash.numPointShadows !== numPointShadows || hash.numSpotShadows !== numSpotShadows) {
  13041. state.directional.length = directionalLength;
  13042. state.spot.length = spotLength;
  13043. state.rectArea.length = rectAreaLength;
  13044. state.point.length = pointLength;
  13045. state.hemi.length = hemiLength;
  13046. state.directionalShadow.length = numDirectionalShadows;
  13047. state.directionalShadowMap.length = numDirectionalShadows;
  13048. state.pointShadow.length = numPointShadows;
  13049. state.pointShadowMap.length = numPointShadows;
  13050. state.spotShadow.length = numSpotShadows;
  13051. state.spotShadowMap.length = numSpotShadows;
  13052. state.directionalShadowMatrix.length = numDirectionalShadows;
  13053. state.pointShadowMatrix.length = numPointShadows;
  13054. state.spotShadowMatrix.length = numSpotShadows;
  13055. hash.directionalLength = directionalLength;
  13056. hash.pointLength = pointLength;
  13057. hash.spotLength = spotLength;
  13058. hash.rectAreaLength = rectAreaLength;
  13059. hash.hemiLength = hemiLength;
  13060. hash.numDirectionalShadows = numDirectionalShadows;
  13061. hash.numPointShadows = numPointShadows;
  13062. hash.numSpotShadows = numSpotShadows;
  13063. state.version = nextVersion++;
  13064. }
  13065. }
  13066. function setupView(lights, camera) {
  13067. let directionalLength = 0;
  13068. let pointLength = 0;
  13069. let spotLength = 0;
  13070. let rectAreaLength = 0;
  13071. let hemiLength = 0;
  13072. const viewMatrix = camera.matrixWorldInverse;
  13073. for (let i = 0, l = lights.length; i < l; i++) {
  13074. const light = lights[i];
  13075. if (light.isDirectionalLight) {
  13076. const uniforms = state.directional[directionalLength];
  13077. uniforms.direction.setFromMatrixPosition(light.matrixWorld);
  13078. vector3.setFromMatrixPosition(light.target.matrixWorld);
  13079. uniforms.direction.sub(vector3);
  13080. uniforms.direction.transformDirection(viewMatrix);
  13081. directionalLength++;
  13082. } else if (light.isSpotLight) {
  13083. const uniforms = state.spot[spotLength];
  13084. uniforms.position.setFromMatrixPosition(light.matrixWorld);
  13085. uniforms.position.applyMatrix4(viewMatrix);
  13086. uniforms.direction.setFromMatrixPosition(light.matrixWorld);
  13087. vector3.setFromMatrixPosition(light.target.matrixWorld);
  13088. uniforms.direction.sub(vector3);
  13089. uniforms.direction.transformDirection(viewMatrix);
  13090. spotLength++;
  13091. } else if (light.isRectAreaLight) {
  13092. const uniforms = state.rectArea[rectAreaLength];
  13093. uniforms.position.setFromMatrixPosition(light.matrixWorld);
  13094. uniforms.position.applyMatrix4(viewMatrix); // extract local rotation of light to derive width/height half vectors
  13095. matrix42.identity();
  13096. matrix4.copy(light.matrixWorld);
  13097. matrix4.premultiply(viewMatrix);
  13098. matrix42.extractRotation(matrix4);
  13099. uniforms.halfWidth.set(light.width * 0.5, 0.0, 0.0);
  13100. uniforms.halfHeight.set(0.0, light.height * 0.5, 0.0);
  13101. uniforms.halfWidth.applyMatrix4(matrix42);
  13102. uniforms.halfHeight.applyMatrix4(matrix42);
  13103. rectAreaLength++;
  13104. } else if (light.isPointLight) {
  13105. const uniforms = state.point[pointLength];
  13106. uniforms.position.setFromMatrixPosition(light.matrixWorld);
  13107. uniforms.position.applyMatrix4(viewMatrix);
  13108. pointLength++;
  13109. } else if (light.isHemisphereLight) {
  13110. const uniforms = state.hemi[hemiLength];
  13111. uniforms.direction.setFromMatrixPosition(light.matrixWorld);
  13112. uniforms.direction.transformDirection(viewMatrix);
  13113. hemiLength++;
  13114. }
  13115. }
  13116. }
  13117. return {
  13118. setup: setup,
  13119. setupView: setupView,
  13120. state: state
  13121. };
  13122. }
  13123. function WebGLRenderState(extensions, capabilities) {
  13124. const lights = new WebGLLights(extensions, capabilities);
  13125. const lightsArray = [];
  13126. const shadowsArray = [];
  13127. function init() {
  13128. lightsArray.length = 0;
  13129. shadowsArray.length = 0;
  13130. }
  13131. function pushLight(light) {
  13132. lightsArray.push(light);
  13133. }
  13134. function pushShadow(shadowLight) {
  13135. shadowsArray.push(shadowLight);
  13136. }
  13137. function setupLights(physicallyCorrectLights) {
  13138. lights.setup(lightsArray, physicallyCorrectLights);
  13139. }
  13140. function setupLightsView(camera) {
  13141. lights.setupView(lightsArray, camera);
  13142. }
  13143. const state = {
  13144. lightsArray: lightsArray,
  13145. shadowsArray: shadowsArray,
  13146. lights: lights
  13147. };
  13148. return {
  13149. init: init,
  13150. state: state,
  13151. setupLights: setupLights,
  13152. setupLightsView: setupLightsView,
  13153. pushLight: pushLight,
  13154. pushShadow: pushShadow
  13155. };
  13156. }
  13157. function WebGLRenderStates(extensions, capabilities) {
  13158. let renderStates = new WeakMap();
  13159. function get(scene, renderCallDepth = 0) {
  13160. let renderState;
  13161. if (renderStates.has(scene) === false) {
  13162. renderState = new WebGLRenderState(extensions, capabilities);
  13163. renderStates.set(scene, [renderState]);
  13164. } else {
  13165. if (renderCallDepth >= renderStates.get(scene).length) {
  13166. renderState = new WebGLRenderState(extensions, capabilities);
  13167. renderStates.get(scene).push(renderState);
  13168. } else {
  13169. renderState = renderStates.get(scene)[renderCallDepth];
  13170. }
  13171. }
  13172. return renderState;
  13173. }
  13174. function dispose() {
  13175. renderStates = new WeakMap();
  13176. }
  13177. return {
  13178. get: get,
  13179. dispose: dispose
  13180. };
  13181. }
  13182. class MeshDepthMaterial extends Material {
  13183. constructor(parameters) {
  13184. super();
  13185. this.isMeshDepthMaterial = true;
  13186. this.type = 'MeshDepthMaterial';
  13187. this.depthPacking = BasicDepthPacking;
  13188. this.map = null;
  13189. this.alphaMap = null;
  13190. this.displacementMap = null;
  13191. this.displacementScale = 1;
  13192. this.displacementBias = 0;
  13193. this.wireframe = false;
  13194. this.wireframeLinewidth = 1;
  13195. this.setValues(parameters);
  13196. }
  13197. copy(source) {
  13198. super.copy(source);
  13199. this.depthPacking = source.depthPacking;
  13200. this.map = source.map;
  13201. this.alphaMap = source.alphaMap;
  13202. this.displacementMap = source.displacementMap;
  13203. this.displacementScale = source.displacementScale;
  13204. this.displacementBias = source.displacementBias;
  13205. this.wireframe = source.wireframe;
  13206. this.wireframeLinewidth = source.wireframeLinewidth;
  13207. return this;
  13208. }
  13209. }
  13210. class MeshDistanceMaterial extends Material {
  13211. constructor(parameters) {
  13212. super();
  13213. this.isMeshDistanceMaterial = true;
  13214. this.type = 'MeshDistanceMaterial';
  13215. this.referencePosition = new Vector3();
  13216. this.nearDistance = 1;
  13217. this.farDistance = 1000;
  13218. this.map = null;
  13219. this.alphaMap = null;
  13220. this.displacementMap = null;
  13221. this.displacementScale = 1;
  13222. this.displacementBias = 0;
  13223. this.setValues(parameters);
  13224. }
  13225. copy(source) {
  13226. super.copy(source);
  13227. this.referencePosition.copy(source.referencePosition);
  13228. this.nearDistance = source.nearDistance;
  13229. this.farDistance = source.farDistance;
  13230. this.map = source.map;
  13231. this.alphaMap = source.alphaMap;
  13232. this.displacementMap = source.displacementMap;
  13233. this.displacementScale = source.displacementScale;
  13234. this.displacementBias = source.displacementBias;
  13235. return this;
  13236. }
  13237. }
  13238. const vertex = "void main() {\n\tgl_Position = vec4( position, 1.0 );\n}";
  13239. const fragment = "uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\n#include <packing>\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) );\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) );\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( squared_mean - mean * mean );\n\tgl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) );\n}";
  13240. function WebGLShadowMap(_renderer, _objects, _capabilities) {
  13241. let _frustum = new Frustum();
  13242. const _shadowMapSize = new Vector2(),
  13243. _viewportSize = new Vector2(),
  13244. _viewport = new Vector4(),
  13245. _depthMaterial = new MeshDepthMaterial({
  13246. depthPacking: RGBADepthPacking
  13247. }),
  13248. _distanceMaterial = new MeshDistanceMaterial(),
  13249. _materialCache = {},
  13250. _maxTextureSize = _capabilities.maxTextureSize;
  13251. const shadowSide = {
  13252. 0: BackSide,
  13253. 1: FrontSide,
  13254. 2: DoubleSide
  13255. };
  13256. const shadowMaterialVertical = new ShaderMaterial({
  13257. defines: {
  13258. VSM_SAMPLES: 8
  13259. },
  13260. uniforms: {
  13261. shadow_pass: {
  13262. value: null
  13263. },
  13264. resolution: {
  13265. value: new Vector2()
  13266. },
  13267. radius: {
  13268. value: 4.0
  13269. }
  13270. },
  13271. vertexShader: vertex,
  13272. fragmentShader: fragment
  13273. });
  13274. const shadowMaterialHorizontal = shadowMaterialVertical.clone();
  13275. shadowMaterialHorizontal.defines.HORIZONTAL_PASS = 1;
  13276. const fullScreenTri = new BufferGeometry();
  13277. fullScreenTri.setAttribute('position', new BufferAttribute(new Float32Array([-1, -1, 0.5, 3, -1, 0.5, -1, 3, 0.5]), 3));
  13278. const fullScreenMesh = new Mesh(fullScreenTri, shadowMaterialVertical);
  13279. const scope = this;
  13280. this.enabled = false;
  13281. this.autoUpdate = true;
  13282. this.needsUpdate = false;
  13283. this.type = PCFShadowMap;
  13284. this.render = function (lights, scene, camera) {
  13285. if (scope.enabled === false) return;
  13286. if (scope.autoUpdate === false && scope.needsUpdate === false) return;
  13287. if (lights.length === 0) return;
  13288. const currentRenderTarget = _renderer.getRenderTarget();
  13289. const activeCubeFace = _renderer.getActiveCubeFace();
  13290. const activeMipmapLevel = _renderer.getActiveMipmapLevel();
  13291. const _state = _renderer.state; // Set GL state for depth map.
  13292. _state.setBlending(NoBlending);
  13293. _state.buffers.color.setClear(1, 1, 1, 1);
  13294. _state.buffers.depth.setTest(true);
  13295. _state.setScissorTest(false); // render depth map
  13296. for (let i = 0, il = lights.length; i < il; i++) {
  13297. const light = lights[i];
  13298. const shadow = light.shadow;
  13299. if (shadow === undefined) {
  13300. console.warn('THREE.WebGLShadowMap:', light, 'has no shadow.');
  13301. continue;
  13302. }
  13303. if (shadow.autoUpdate === false && shadow.needsUpdate === false) continue;
  13304. _shadowMapSize.copy(shadow.mapSize);
  13305. const shadowFrameExtents = shadow.getFrameExtents();
  13306. _shadowMapSize.multiply(shadowFrameExtents);
  13307. _viewportSize.copy(shadow.mapSize);
  13308. if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) {
  13309. if (_shadowMapSize.x > _maxTextureSize) {
  13310. _viewportSize.x = Math.floor(_maxTextureSize / shadowFrameExtents.x);
  13311. _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x;
  13312. shadow.mapSize.x = _viewportSize.x;
  13313. }
  13314. if (_shadowMapSize.y > _maxTextureSize) {
  13315. _viewportSize.y = Math.floor(_maxTextureSize / shadowFrameExtents.y);
  13316. _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y;
  13317. shadow.mapSize.y = _viewportSize.y;
  13318. }
  13319. }
  13320. if (shadow.map === null) {
  13321. const pars = this.type !== VSMShadowMap ? {
  13322. minFilter: NearestFilter,
  13323. magFilter: NearestFilter
  13324. } : {};
  13325. shadow.map = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y, pars);
  13326. shadow.map.texture.name = light.name + '.shadowMap';
  13327. shadow.camera.updateProjectionMatrix();
  13328. }
  13329. _renderer.setRenderTarget(shadow.map);
  13330. _renderer.clear();
  13331. const viewportCount = shadow.getViewportCount();
  13332. for (let vp = 0; vp < viewportCount; vp++) {
  13333. const viewport = shadow.getViewport(vp);
  13334. _viewport.set(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w);
  13335. _state.viewport(_viewport);
  13336. shadow.updateMatrices(light, vp);
  13337. _frustum = shadow.getFrustum();
  13338. renderObject(scene, camera, shadow.camera, light, this.type);
  13339. } // do blur pass for VSM
  13340. if (shadow.isPointLightShadow !== true && this.type === VSMShadowMap) {
  13341. VSMPass(shadow, camera);
  13342. }
  13343. shadow.needsUpdate = false;
  13344. }
  13345. scope.needsUpdate = false;
  13346. _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel);
  13347. };
  13348. function VSMPass(shadow, camera) {
  13349. const geometry = _objects.update(fullScreenMesh);
  13350. if (shadowMaterialVertical.defines.VSM_SAMPLES !== shadow.blurSamples) {
  13351. shadowMaterialVertical.defines.VSM_SAMPLES = shadow.blurSamples;
  13352. shadowMaterialHorizontal.defines.VSM_SAMPLES = shadow.blurSamples;
  13353. shadowMaterialVertical.needsUpdate = true;
  13354. shadowMaterialHorizontal.needsUpdate = true;
  13355. }
  13356. if (shadow.mapPass === null) {
  13357. shadow.mapPass = new WebGLRenderTarget(_shadowMapSize.x, _shadowMapSize.y);
  13358. } // vertical pass
  13359. shadowMaterialVertical.uniforms.shadow_pass.value = shadow.map.texture;
  13360. shadowMaterialVertical.uniforms.resolution.value = shadow.mapSize;
  13361. shadowMaterialVertical.uniforms.radius.value = shadow.radius;
  13362. _renderer.setRenderTarget(shadow.mapPass);
  13363. _renderer.clear();
  13364. _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); // horizontal pass
  13365. shadowMaterialHorizontal.uniforms.shadow_pass.value = shadow.mapPass.texture;
  13366. shadowMaterialHorizontal.uniforms.resolution.value = shadow.mapSize;
  13367. shadowMaterialHorizontal.uniforms.radius.value = shadow.radius;
  13368. _renderer.setRenderTarget(shadow.map);
  13369. _renderer.clear();
  13370. _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null);
  13371. }
  13372. function getDepthMaterial(object, material, light, shadowCameraNear, shadowCameraFar, type) {
  13373. let result = null;
  13374. const customMaterial = light.isPointLight === true ? object.customDistanceMaterial : object.customDepthMaterial;
  13375. if (customMaterial !== undefined) {
  13376. result = customMaterial;
  13377. } else {
  13378. result = light.isPointLight === true ? _distanceMaterial : _depthMaterial;
  13379. }
  13380. if (_renderer.localClippingEnabled && material.clipShadows === true && Array.isArray(material.clippingPlanes) && material.clippingPlanes.length !== 0 || material.displacementMap && material.displacementScale !== 0 || material.alphaMap && material.alphaTest > 0) {
  13381. // in this case we need a unique material instance reflecting the
  13382. // appropriate state
  13383. const keyA = result.uuid,
  13384. keyB = material.uuid;
  13385. let materialsForVariant = _materialCache[keyA];
  13386. if (materialsForVariant === undefined) {
  13387. materialsForVariant = {};
  13388. _materialCache[keyA] = materialsForVariant;
  13389. }
  13390. let cachedMaterial = materialsForVariant[keyB];
  13391. if (cachedMaterial === undefined) {
  13392. cachedMaterial = result.clone();
  13393. materialsForVariant[keyB] = cachedMaterial;
  13394. }
  13395. result = cachedMaterial;
  13396. }
  13397. result.visible = material.visible;
  13398. result.wireframe = material.wireframe;
  13399. if (type === VSMShadowMap) {
  13400. result.side = material.shadowSide !== null ? material.shadowSide : material.side;
  13401. } else {
  13402. result.side = material.shadowSide !== null ? material.shadowSide : shadowSide[material.side];
  13403. }
  13404. result.alphaMap = material.alphaMap;
  13405. result.alphaTest = material.alphaTest;
  13406. result.clipShadows = material.clipShadows;
  13407. result.clippingPlanes = material.clippingPlanes;
  13408. result.clipIntersection = material.clipIntersection;
  13409. result.displacementMap = material.displacementMap;
  13410. result.displacementScale = material.displacementScale;
  13411. result.displacementBias = material.displacementBias;
  13412. result.wireframeLinewidth = material.wireframeLinewidth;
  13413. result.linewidth = material.linewidth;
  13414. if (light.isPointLight === true && result.isMeshDistanceMaterial === true) {
  13415. result.referencePosition.setFromMatrixPosition(light.matrixWorld);
  13416. result.nearDistance = shadowCameraNear;
  13417. result.farDistance = shadowCameraFar;
  13418. }
  13419. return result;
  13420. }
  13421. function renderObject(object, camera, shadowCamera, light, type) {
  13422. if (object.visible === false) return;
  13423. const visible = object.layers.test(camera.layers);
  13424. if (visible && (object.isMesh || object.isLine || object.isPoints)) {
  13425. if ((object.castShadow || object.receiveShadow && type === VSMShadowMap) && (!object.frustumCulled || _frustum.intersectsObject(object))) {
  13426. object.modelViewMatrix.multiplyMatrices(shadowCamera.matrixWorldInverse, object.matrixWorld);
  13427. const geometry = _objects.update(object);
  13428. const material = object.material;
  13429. if (Array.isArray(material)) {
  13430. const groups = geometry.groups;
  13431. for (let k = 0, kl = groups.length; k < kl; k++) {
  13432. const group = groups[k];
  13433. const groupMaterial = material[group.materialIndex];
  13434. if (groupMaterial && groupMaterial.visible) {
  13435. const depthMaterial = getDepthMaterial(object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type);
  13436. _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group);
  13437. }
  13438. }
  13439. } else if (material.visible) {
  13440. const depthMaterial = getDepthMaterial(object, material, light, shadowCamera.near, shadowCamera.far, type);
  13441. _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null);
  13442. }
  13443. }
  13444. }
  13445. const children = object.children;
  13446. for (let i = 0, l = children.length; i < l; i++) {
  13447. renderObject(children[i], camera, shadowCamera, light, type);
  13448. }
  13449. }
  13450. }
  13451. function WebGLState(gl, extensions, capabilities) {
  13452. const isWebGL2 = capabilities.isWebGL2;
  13453. function ColorBuffer() {
  13454. let locked = false;
  13455. const color = new Vector4();
  13456. let currentColorMask = null;
  13457. const currentColorClear = new Vector4(0, 0, 0, 0);
  13458. return {
  13459. setMask: function (colorMask) {
  13460. if (currentColorMask !== colorMask && !locked) {
  13461. gl.colorMask(colorMask, colorMask, colorMask, colorMask);
  13462. currentColorMask = colorMask;
  13463. }
  13464. },
  13465. setLocked: function (lock) {
  13466. locked = lock;
  13467. },
  13468. setClear: function (r, g, b, a, premultipliedAlpha) {
  13469. if (premultipliedAlpha === true) {
  13470. r *= a;
  13471. g *= a;
  13472. b *= a;
  13473. }
  13474. color.set(r, g, b, a);
  13475. if (currentColorClear.equals(color) === false) {
  13476. gl.clearColor(r, g, b, a);
  13477. currentColorClear.copy(color);
  13478. }
  13479. },
  13480. reset: function () {
  13481. locked = false;
  13482. currentColorMask = null;
  13483. currentColorClear.set(-1, 0, 0, 0); // set to invalid state
  13484. }
  13485. };
  13486. }
  13487. function DepthBuffer() {
  13488. let locked = false;
  13489. let currentDepthMask = null;
  13490. let currentDepthFunc = null;
  13491. let currentDepthClear = null;
  13492. return {
  13493. setTest: function (depthTest) {
  13494. if (depthTest) {
  13495. enable(gl.DEPTH_TEST);
  13496. } else {
  13497. disable(gl.DEPTH_TEST);
  13498. }
  13499. },
  13500. setMask: function (depthMask) {
  13501. if (currentDepthMask !== depthMask && !locked) {
  13502. gl.depthMask(depthMask);
  13503. currentDepthMask = depthMask;
  13504. }
  13505. },
  13506. setFunc: function (depthFunc) {
  13507. if (currentDepthFunc !== depthFunc) {
  13508. if (depthFunc) {
  13509. switch (depthFunc) {
  13510. case NeverDepth:
  13511. gl.depthFunc(gl.NEVER);
  13512. break;
  13513. case AlwaysDepth:
  13514. gl.depthFunc(gl.ALWAYS);
  13515. break;
  13516. case LessDepth:
  13517. gl.depthFunc(gl.LESS);
  13518. break;
  13519. case LessEqualDepth:
  13520. gl.depthFunc(gl.LEQUAL);
  13521. break;
  13522. case EqualDepth:
  13523. gl.depthFunc(gl.EQUAL);
  13524. break;
  13525. case GreaterEqualDepth:
  13526. gl.depthFunc(gl.GEQUAL);
  13527. break;
  13528. case GreaterDepth:
  13529. gl.depthFunc(gl.GREATER);
  13530. break;
  13531. case NotEqualDepth:
  13532. gl.depthFunc(gl.NOTEQUAL);
  13533. break;
  13534. default:
  13535. gl.depthFunc(gl.LEQUAL);
  13536. }
  13537. } else {
  13538. gl.depthFunc(gl.LEQUAL);
  13539. }
  13540. currentDepthFunc = depthFunc;
  13541. }
  13542. },
  13543. setLocked: function (lock) {
  13544. locked = lock;
  13545. },
  13546. setClear: function (depth) {
  13547. if (currentDepthClear !== depth) {
  13548. gl.clearDepth(depth);
  13549. currentDepthClear = depth;
  13550. }
  13551. },
  13552. reset: function () {
  13553. locked = false;
  13554. currentDepthMask = null;
  13555. currentDepthFunc = null;
  13556. currentDepthClear = null;
  13557. }
  13558. };
  13559. }
  13560. function StencilBuffer() {
  13561. let locked = false;
  13562. let currentStencilMask = null;
  13563. let currentStencilFunc = null;
  13564. let currentStencilRef = null;
  13565. let currentStencilFuncMask = null;
  13566. let currentStencilFail = null;
  13567. let currentStencilZFail = null;
  13568. let currentStencilZPass = null;
  13569. let currentStencilClear = null;
  13570. return {
  13571. setTest: function (stencilTest) {
  13572. if (!locked) {
  13573. if (stencilTest) {
  13574. enable(gl.STENCIL_TEST);
  13575. } else {
  13576. disable(gl.STENCIL_TEST);
  13577. }
  13578. }
  13579. },
  13580. setMask: function (stencilMask) {
  13581. if (currentStencilMask !== stencilMask && !locked) {
  13582. gl.stencilMask(stencilMask);
  13583. currentStencilMask = stencilMask;
  13584. }
  13585. },
  13586. setFunc: function (stencilFunc, stencilRef, stencilMask) {
  13587. if (currentStencilFunc !== stencilFunc || currentStencilRef !== stencilRef || currentStencilFuncMask !== stencilMask) {
  13588. gl.stencilFunc(stencilFunc, stencilRef, stencilMask);
  13589. currentStencilFunc = stencilFunc;
  13590. currentStencilRef = stencilRef;
  13591. currentStencilFuncMask = stencilMask;
  13592. }
  13593. },
  13594. setOp: function (stencilFail, stencilZFail, stencilZPass) {
  13595. if (currentStencilFail !== stencilFail || currentStencilZFail !== stencilZFail || currentStencilZPass !== stencilZPass) {
  13596. gl.stencilOp(stencilFail, stencilZFail, stencilZPass);
  13597. currentStencilFail = stencilFail;
  13598. currentStencilZFail = stencilZFail;
  13599. currentStencilZPass = stencilZPass;
  13600. }
  13601. },
  13602. setLocked: function (lock) {
  13603. locked = lock;
  13604. },
  13605. setClear: function (stencil) {
  13606. if (currentStencilClear !== stencil) {
  13607. gl.clearStencil(stencil);
  13608. currentStencilClear = stencil;
  13609. }
  13610. },
  13611. reset: function () {
  13612. locked = false;
  13613. currentStencilMask = null;
  13614. currentStencilFunc = null;
  13615. currentStencilRef = null;
  13616. currentStencilFuncMask = null;
  13617. currentStencilFail = null;
  13618. currentStencilZFail = null;
  13619. currentStencilZPass = null;
  13620. currentStencilClear = null;
  13621. }
  13622. };
  13623. } //
  13624. const colorBuffer = new ColorBuffer();
  13625. const depthBuffer = new DepthBuffer();
  13626. const stencilBuffer = new StencilBuffer();
  13627. const uboBindings = new WeakMap();
  13628. const uboProgamMap = new WeakMap();
  13629. let enabledCapabilities = {};
  13630. let currentBoundFramebuffers = {};
  13631. let currentDrawbuffers = new WeakMap();
  13632. let defaultDrawbuffers = [];
  13633. let currentProgram = null;
  13634. let currentBlendingEnabled = false;
  13635. let currentBlending = null;
  13636. let currentBlendEquation = null;
  13637. let currentBlendSrc = null;
  13638. let currentBlendDst = null;
  13639. let currentBlendEquationAlpha = null;
  13640. let currentBlendSrcAlpha = null;
  13641. let currentBlendDstAlpha = null;
  13642. let currentPremultipledAlpha = false;
  13643. let currentFlipSided = null;
  13644. let currentCullFace = null;
  13645. let currentLineWidth = null;
  13646. let currentPolygonOffsetFactor = null;
  13647. let currentPolygonOffsetUnits = null;
  13648. const maxTextures = gl.getParameter(gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS);
  13649. let lineWidthAvailable = false;
  13650. let version = 0;
  13651. const glVersion = gl.getParameter(gl.VERSION);
  13652. if (glVersion.indexOf('WebGL') !== -1) {
  13653. version = parseFloat(/^WebGL (\d)/.exec(glVersion)[1]);
  13654. lineWidthAvailable = version >= 1.0;
  13655. } else if (glVersion.indexOf('OpenGL ES') !== -1) {
  13656. version = parseFloat(/^OpenGL ES (\d)/.exec(glVersion)[1]);
  13657. lineWidthAvailable = version >= 2.0;
  13658. }
  13659. let currentTextureSlot = null;
  13660. let currentBoundTextures = {};
  13661. const scissorParam = gl.getParameter(gl.SCISSOR_BOX);
  13662. const viewportParam = gl.getParameter(gl.VIEWPORT);
  13663. const currentScissor = new Vector4().fromArray(scissorParam);
  13664. const currentViewport = new Vector4().fromArray(viewportParam);
  13665. function createTexture(type, target, count) {
  13666. const data = new Uint8Array(4); // 4 is required to match default unpack alignment of 4.
  13667. const texture = gl.createTexture();
  13668. gl.bindTexture(type, texture);
  13669. gl.texParameteri(type, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
  13670. gl.texParameteri(type, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  13671. for (let i = 0; i < count; i++) {
  13672. gl.texImage2D(target + i, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
  13673. }
  13674. return texture;
  13675. }
  13676. const emptyTextures = {};
  13677. emptyTextures[gl.TEXTURE_2D] = createTexture(gl.TEXTURE_2D, gl.TEXTURE_2D, 1);
  13678. emptyTextures[gl.TEXTURE_CUBE_MAP] = createTexture(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_CUBE_MAP_POSITIVE_X, 6); // init
  13679. colorBuffer.setClear(0, 0, 0, 1);
  13680. depthBuffer.setClear(1);
  13681. stencilBuffer.setClear(0);
  13682. enable(gl.DEPTH_TEST);
  13683. depthBuffer.setFunc(LessEqualDepth);
  13684. setFlipSided(false);
  13685. setCullFace(CullFaceBack);
  13686. enable(gl.CULL_FACE);
  13687. setBlending(NoBlending); //
  13688. function enable(id) {
  13689. if (enabledCapabilities[id] !== true) {
  13690. gl.enable(id);
  13691. enabledCapabilities[id] = true;
  13692. }
  13693. }
  13694. function disable(id) {
  13695. if (enabledCapabilities[id] !== false) {
  13696. gl.disable(id);
  13697. enabledCapabilities[id] = false;
  13698. }
  13699. }
  13700. function bindFramebuffer(target, framebuffer) {
  13701. if (currentBoundFramebuffers[target] !== framebuffer) {
  13702. gl.bindFramebuffer(target, framebuffer);
  13703. currentBoundFramebuffers[target] = framebuffer;
  13704. if (isWebGL2) {
  13705. // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER
  13706. if (target === gl.DRAW_FRAMEBUFFER) {
  13707. currentBoundFramebuffers[gl.FRAMEBUFFER] = framebuffer;
  13708. }
  13709. if (target === gl.FRAMEBUFFER) {
  13710. currentBoundFramebuffers[gl.DRAW_FRAMEBUFFER] = framebuffer;
  13711. }
  13712. }
  13713. return true;
  13714. }
  13715. return false;
  13716. }
  13717. function drawBuffers(renderTarget, framebuffer) {
  13718. let drawBuffers = defaultDrawbuffers;
  13719. let needsUpdate = false;
  13720. if (renderTarget) {
  13721. drawBuffers = currentDrawbuffers.get(framebuffer);
  13722. if (drawBuffers === undefined) {
  13723. drawBuffers = [];
  13724. currentDrawbuffers.set(framebuffer, drawBuffers);
  13725. }
  13726. if (renderTarget.isWebGLMultipleRenderTargets) {
  13727. const textures = renderTarget.texture;
  13728. if (drawBuffers.length !== textures.length || drawBuffers[0] !== gl.COLOR_ATTACHMENT0) {
  13729. for (let i = 0, il = textures.length; i < il; i++) {
  13730. drawBuffers[i] = gl.COLOR_ATTACHMENT0 + i;
  13731. }
  13732. drawBuffers.length = textures.length;
  13733. needsUpdate = true;
  13734. }
  13735. } else {
  13736. if (drawBuffers[0] !== gl.COLOR_ATTACHMENT0) {
  13737. drawBuffers[0] = gl.COLOR_ATTACHMENT0;
  13738. needsUpdate = true;
  13739. }
  13740. }
  13741. } else {
  13742. if (drawBuffers[0] !== gl.BACK) {
  13743. drawBuffers[0] = gl.BACK;
  13744. needsUpdate = true;
  13745. }
  13746. }
  13747. if (needsUpdate) {
  13748. if (capabilities.isWebGL2) {
  13749. gl.drawBuffers(drawBuffers);
  13750. } else {
  13751. extensions.get('WEBGL_draw_buffers').drawBuffersWEBGL(drawBuffers);
  13752. }
  13753. }
  13754. }
  13755. function useProgram(program) {
  13756. if (currentProgram !== program) {
  13757. gl.useProgram(program);
  13758. currentProgram = program;
  13759. return true;
  13760. }
  13761. return false;
  13762. }
  13763. const equationToGL = {
  13764. [AddEquation]: gl.FUNC_ADD,
  13765. [SubtractEquation]: gl.FUNC_SUBTRACT,
  13766. [ReverseSubtractEquation]: gl.FUNC_REVERSE_SUBTRACT
  13767. };
  13768. if (isWebGL2) {
  13769. equationToGL[MinEquation] = gl.MIN;
  13770. equationToGL[MaxEquation] = gl.MAX;
  13771. } else {
  13772. const extension = extensions.get('EXT_blend_minmax');
  13773. if (extension !== null) {
  13774. equationToGL[MinEquation] = extension.MIN_EXT;
  13775. equationToGL[MaxEquation] = extension.MAX_EXT;
  13776. }
  13777. }
  13778. const factorToGL = {
  13779. [ZeroFactor]: gl.ZERO,
  13780. [OneFactor]: gl.ONE,
  13781. [SrcColorFactor]: gl.SRC_COLOR,
  13782. [SrcAlphaFactor]: gl.SRC_ALPHA,
  13783. [SrcAlphaSaturateFactor]: gl.SRC_ALPHA_SATURATE,
  13784. [DstColorFactor]: gl.DST_COLOR,
  13785. [DstAlphaFactor]: gl.DST_ALPHA,
  13786. [OneMinusSrcColorFactor]: gl.ONE_MINUS_SRC_COLOR,
  13787. [OneMinusSrcAlphaFactor]: gl.ONE_MINUS_SRC_ALPHA,
  13788. [OneMinusDstColorFactor]: gl.ONE_MINUS_DST_COLOR,
  13789. [OneMinusDstAlphaFactor]: gl.ONE_MINUS_DST_ALPHA
  13790. };
  13791. function setBlending(blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha, premultipliedAlpha) {
  13792. if (blending === NoBlending) {
  13793. if (currentBlendingEnabled === true) {
  13794. disable(gl.BLEND);
  13795. currentBlendingEnabled = false;
  13796. }
  13797. return;
  13798. }
  13799. if (currentBlendingEnabled === false) {
  13800. enable(gl.BLEND);
  13801. currentBlendingEnabled = true;
  13802. }
  13803. if (blending !== CustomBlending) {
  13804. if (blending !== currentBlending || premultipliedAlpha !== currentPremultipledAlpha) {
  13805. if (currentBlendEquation !== AddEquation || currentBlendEquationAlpha !== AddEquation) {
  13806. gl.blendEquation(gl.FUNC_ADD);
  13807. currentBlendEquation = AddEquation;
  13808. currentBlendEquationAlpha = AddEquation;
  13809. }
  13810. if (premultipliedAlpha) {
  13811. switch (blending) {
  13812. case NormalBlending:
  13813. gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  13814. break;
  13815. case AdditiveBlending:
  13816. gl.blendFunc(gl.ONE, gl.ONE);
  13817. break;
  13818. case SubtractiveBlending:
  13819. gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE);
  13820. break;
  13821. case MultiplyBlending:
  13822. gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA);
  13823. break;
  13824. default:
  13825. console.error('THREE.WebGLState: Invalid blending: ', blending);
  13826. break;
  13827. }
  13828. } else {
  13829. switch (blending) {
  13830. case NormalBlending:
  13831. gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  13832. break;
  13833. case AdditiveBlending:
  13834. gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
  13835. break;
  13836. case SubtractiveBlending:
  13837. gl.blendFuncSeparate(gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE);
  13838. break;
  13839. case MultiplyBlending:
  13840. gl.blendFunc(gl.ZERO, gl.SRC_COLOR);
  13841. break;
  13842. default:
  13843. console.error('THREE.WebGLState: Invalid blending: ', blending);
  13844. break;
  13845. }
  13846. }
  13847. currentBlendSrc = null;
  13848. currentBlendDst = null;
  13849. currentBlendSrcAlpha = null;
  13850. currentBlendDstAlpha = null;
  13851. currentBlending = blending;
  13852. currentPremultipledAlpha = premultipliedAlpha;
  13853. }
  13854. return;
  13855. } // custom blending
  13856. blendEquationAlpha = blendEquationAlpha || blendEquation;
  13857. blendSrcAlpha = blendSrcAlpha || blendSrc;
  13858. blendDstAlpha = blendDstAlpha || blendDst;
  13859. if (blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha) {
  13860. gl.blendEquationSeparate(equationToGL[blendEquation], equationToGL[blendEquationAlpha]);
  13861. currentBlendEquation = blendEquation;
  13862. currentBlendEquationAlpha = blendEquationAlpha;
  13863. }
  13864. if (blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha) {
  13865. gl.blendFuncSeparate(factorToGL[blendSrc], factorToGL[blendDst], factorToGL[blendSrcAlpha], factorToGL[blendDstAlpha]);
  13866. currentBlendSrc = blendSrc;
  13867. currentBlendDst = blendDst;
  13868. currentBlendSrcAlpha = blendSrcAlpha;
  13869. currentBlendDstAlpha = blendDstAlpha;
  13870. }
  13871. currentBlending = blending;
  13872. currentPremultipledAlpha = null;
  13873. }
  13874. function setMaterial(material, frontFaceCW) {
  13875. material.side === DoubleSide ? disable(gl.CULL_FACE) : enable(gl.CULL_FACE);
  13876. let flipSided = material.side === BackSide;
  13877. if (frontFaceCW) flipSided = !flipSided;
  13878. setFlipSided(flipSided);
  13879. material.blending === NormalBlending && material.transparent === false ? setBlending(NoBlending) : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst, material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha);
  13880. depthBuffer.setFunc(material.depthFunc);
  13881. depthBuffer.setTest(material.depthTest);
  13882. depthBuffer.setMask(material.depthWrite);
  13883. colorBuffer.setMask(material.colorWrite);
  13884. const stencilWrite = material.stencilWrite;
  13885. stencilBuffer.setTest(stencilWrite);
  13886. if (stencilWrite) {
  13887. stencilBuffer.setMask(material.stencilWriteMask);
  13888. stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask);
  13889. stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass);
  13890. }
  13891. setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits);
  13892. material.alphaToCoverage === true ? enable(gl.SAMPLE_ALPHA_TO_COVERAGE) : disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
  13893. } //
  13894. function setFlipSided(flipSided) {
  13895. if (currentFlipSided !== flipSided) {
  13896. if (flipSided) {
  13897. gl.frontFace(gl.CW);
  13898. } else {
  13899. gl.frontFace(gl.CCW);
  13900. }
  13901. currentFlipSided = flipSided;
  13902. }
  13903. }
  13904. function setCullFace(cullFace) {
  13905. if (cullFace !== CullFaceNone) {
  13906. enable(gl.CULL_FACE);
  13907. if (cullFace !== currentCullFace) {
  13908. if (cullFace === CullFaceBack) {
  13909. gl.cullFace(gl.BACK);
  13910. } else if (cullFace === CullFaceFront) {
  13911. gl.cullFace(gl.FRONT);
  13912. } else {
  13913. gl.cullFace(gl.FRONT_AND_BACK);
  13914. }
  13915. }
  13916. } else {
  13917. disable(gl.CULL_FACE);
  13918. }
  13919. currentCullFace = cullFace;
  13920. }
  13921. function setLineWidth(width) {
  13922. if (width !== currentLineWidth) {
  13923. if (lineWidthAvailable) gl.lineWidth(width);
  13924. currentLineWidth = width;
  13925. }
  13926. }
  13927. function setPolygonOffset(polygonOffset, factor, units) {
  13928. if (polygonOffset) {
  13929. enable(gl.POLYGON_OFFSET_FILL);
  13930. if (currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units) {
  13931. gl.polygonOffset(factor, units);
  13932. currentPolygonOffsetFactor = factor;
  13933. currentPolygonOffsetUnits = units;
  13934. }
  13935. } else {
  13936. disable(gl.POLYGON_OFFSET_FILL);
  13937. }
  13938. }
  13939. function setScissorTest(scissorTest) {
  13940. if (scissorTest) {
  13941. enable(gl.SCISSOR_TEST);
  13942. } else {
  13943. disable(gl.SCISSOR_TEST);
  13944. }
  13945. } // texture
  13946. function activeTexture(webglSlot) {
  13947. if (webglSlot === undefined) webglSlot = gl.TEXTURE0 + maxTextures - 1;
  13948. if (currentTextureSlot !== webglSlot) {
  13949. gl.activeTexture(webglSlot);
  13950. currentTextureSlot = webglSlot;
  13951. }
  13952. }
  13953. function bindTexture(webglType, webglTexture) {
  13954. if (currentTextureSlot === null) {
  13955. activeTexture();
  13956. }
  13957. let boundTexture = currentBoundTextures[currentTextureSlot];
  13958. if (boundTexture === undefined) {
  13959. boundTexture = {
  13960. type: undefined,
  13961. texture: undefined
  13962. };
  13963. currentBoundTextures[currentTextureSlot] = boundTexture;
  13964. }
  13965. if (boundTexture.type !== webglType || boundTexture.texture !== webglTexture) {
  13966. gl.bindTexture(webglType, webglTexture || emptyTextures[webglType]);
  13967. boundTexture.type = webglType;
  13968. boundTexture.texture = webglTexture;
  13969. }
  13970. }
  13971. function unbindTexture() {
  13972. const boundTexture = currentBoundTextures[currentTextureSlot];
  13973. if (boundTexture !== undefined && boundTexture.type !== undefined) {
  13974. gl.bindTexture(boundTexture.type, null);
  13975. boundTexture.type = undefined;
  13976. boundTexture.texture = undefined;
  13977. }
  13978. }
  13979. function compressedTexImage2D() {
  13980. try {
  13981. gl.compressedTexImage2D.apply(gl, arguments);
  13982. } catch (error) {
  13983. console.error('THREE.WebGLState:', error);
  13984. }
  13985. }
  13986. function texSubImage2D() {
  13987. try {
  13988. gl.texSubImage2D.apply(gl, arguments);
  13989. } catch (error) {
  13990. console.error('THREE.WebGLState:', error);
  13991. }
  13992. }
  13993. function texSubImage3D() {
  13994. try {
  13995. gl.texSubImage3D.apply(gl, arguments);
  13996. } catch (error) {
  13997. console.error('THREE.WebGLState:', error);
  13998. }
  13999. }
  14000. function compressedTexSubImage2D() {
  14001. try {
  14002. gl.compressedTexSubImage2D.apply(gl, arguments);
  14003. } catch (error) {
  14004. console.error('THREE.WebGLState:', error);
  14005. }
  14006. }
  14007. function texStorage2D() {
  14008. try {
  14009. gl.texStorage2D.apply(gl, arguments);
  14010. } catch (error) {
  14011. console.error('THREE.WebGLState:', error);
  14012. }
  14013. }
  14014. function texStorage3D() {
  14015. try {
  14016. gl.texStorage3D.apply(gl, arguments);
  14017. } catch (error) {
  14018. console.error('THREE.WebGLState:', error);
  14019. }
  14020. }
  14021. function texImage2D() {
  14022. try {
  14023. gl.texImage2D.apply(gl, arguments);
  14024. } catch (error) {
  14025. console.error('THREE.WebGLState:', error);
  14026. }
  14027. }
  14028. function texImage3D() {
  14029. try {
  14030. gl.texImage3D.apply(gl, arguments);
  14031. } catch (error) {
  14032. console.error('THREE.WebGLState:', error);
  14033. }
  14034. } //
  14035. function scissor(scissor) {
  14036. if (currentScissor.equals(scissor) === false) {
  14037. gl.scissor(scissor.x, scissor.y, scissor.z, scissor.w);
  14038. currentScissor.copy(scissor);
  14039. }
  14040. }
  14041. function viewport(viewport) {
  14042. if (currentViewport.equals(viewport) === false) {
  14043. gl.viewport(viewport.x, viewport.y, viewport.z, viewport.w);
  14044. currentViewport.copy(viewport);
  14045. }
  14046. }
  14047. function updateUBOMapping(uniformsGroup, program) {
  14048. let mapping = uboProgamMap.get(program);
  14049. if (mapping === undefined) {
  14050. mapping = new WeakMap();
  14051. uboProgamMap.set(program, mapping);
  14052. }
  14053. let blockIndex = mapping.get(uniformsGroup);
  14054. if (blockIndex === undefined) {
  14055. blockIndex = gl.getUniformBlockIndex(program, uniformsGroup.name);
  14056. mapping.set(uniformsGroup, blockIndex);
  14057. }
  14058. }
  14059. function uniformBlockBinding(uniformsGroup, program) {
  14060. const mapping = uboProgamMap.get(program);
  14061. const blockIndex = mapping.get(uniformsGroup);
  14062. if (uboBindings.get(uniformsGroup) !== blockIndex) {
  14063. // bind shader specific block index to global block point
  14064. gl.uniformBlockBinding(program, blockIndex, uniformsGroup.__bindingPointIndex);
  14065. uboBindings.set(uniformsGroup, blockIndex);
  14066. }
  14067. } //
  14068. function reset() {
  14069. // reset state
  14070. gl.disable(gl.BLEND);
  14071. gl.disable(gl.CULL_FACE);
  14072. gl.disable(gl.DEPTH_TEST);
  14073. gl.disable(gl.POLYGON_OFFSET_FILL);
  14074. gl.disable(gl.SCISSOR_TEST);
  14075. gl.disable(gl.STENCIL_TEST);
  14076. gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
  14077. gl.blendEquation(gl.FUNC_ADD);
  14078. gl.blendFunc(gl.ONE, gl.ZERO);
  14079. gl.blendFuncSeparate(gl.ONE, gl.ZERO, gl.ONE, gl.ZERO);
  14080. gl.colorMask(true, true, true, true);
  14081. gl.clearColor(0, 0, 0, 0);
  14082. gl.depthMask(true);
  14083. gl.depthFunc(gl.LESS);
  14084. gl.clearDepth(1);
  14085. gl.stencilMask(0xffffffff);
  14086. gl.stencilFunc(gl.ALWAYS, 0, 0xffffffff);
  14087. gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
  14088. gl.clearStencil(0);
  14089. gl.cullFace(gl.BACK);
  14090. gl.frontFace(gl.CCW);
  14091. gl.polygonOffset(0, 0);
  14092. gl.activeTexture(gl.TEXTURE0);
  14093. gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  14094. if (isWebGL2 === true) {
  14095. gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
  14096. gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
  14097. }
  14098. gl.useProgram(null);
  14099. gl.lineWidth(1);
  14100. gl.scissor(0, 0, gl.canvas.width, gl.canvas.height);
  14101. gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); // reset internals
  14102. enabledCapabilities = {};
  14103. currentTextureSlot = null;
  14104. currentBoundTextures = {};
  14105. currentBoundFramebuffers = {};
  14106. currentDrawbuffers = new WeakMap();
  14107. defaultDrawbuffers = [];
  14108. currentProgram = null;
  14109. currentBlendingEnabled = false;
  14110. currentBlending = null;
  14111. currentBlendEquation = null;
  14112. currentBlendSrc = null;
  14113. currentBlendDst = null;
  14114. currentBlendEquationAlpha = null;
  14115. currentBlendSrcAlpha = null;
  14116. currentBlendDstAlpha = null;
  14117. currentPremultipledAlpha = false;
  14118. currentFlipSided = null;
  14119. currentCullFace = null;
  14120. currentLineWidth = null;
  14121. currentPolygonOffsetFactor = null;
  14122. currentPolygonOffsetUnits = null;
  14123. currentScissor.set(0, 0, gl.canvas.width, gl.canvas.height);
  14124. currentViewport.set(0, 0, gl.canvas.width, gl.canvas.height);
  14125. colorBuffer.reset();
  14126. depthBuffer.reset();
  14127. stencilBuffer.reset();
  14128. }
  14129. return {
  14130. buffers: {
  14131. color: colorBuffer,
  14132. depth: depthBuffer,
  14133. stencil: stencilBuffer
  14134. },
  14135. enable: enable,
  14136. disable: disable,
  14137. bindFramebuffer: bindFramebuffer,
  14138. drawBuffers: drawBuffers,
  14139. useProgram: useProgram,
  14140. setBlending: setBlending,
  14141. setMaterial: setMaterial,
  14142. setFlipSided: setFlipSided,
  14143. setCullFace: setCullFace,
  14144. setLineWidth: setLineWidth,
  14145. setPolygonOffset: setPolygonOffset,
  14146. setScissorTest: setScissorTest,
  14147. activeTexture: activeTexture,
  14148. bindTexture: bindTexture,
  14149. unbindTexture: unbindTexture,
  14150. compressedTexImage2D: compressedTexImage2D,
  14151. texImage2D: texImage2D,
  14152. texImage3D: texImage3D,
  14153. updateUBOMapping: updateUBOMapping,
  14154. uniformBlockBinding: uniformBlockBinding,
  14155. texStorage2D: texStorage2D,
  14156. texStorage3D: texStorage3D,
  14157. texSubImage2D: texSubImage2D,
  14158. texSubImage3D: texSubImage3D,
  14159. compressedTexSubImage2D: compressedTexSubImage2D,
  14160. scissor: scissor,
  14161. viewport: viewport,
  14162. reset: reset
  14163. };
  14164. }
  14165. function WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info) {
  14166. const isWebGL2 = capabilities.isWebGL2;
  14167. const maxTextures = capabilities.maxTextures;
  14168. const maxCubemapSize = capabilities.maxCubemapSize;
  14169. const maxTextureSize = capabilities.maxTextureSize;
  14170. const maxSamples = capabilities.maxSamples;
  14171. const multisampledRTTExt = extensions.has('WEBGL_multisampled_render_to_texture') ? extensions.get('WEBGL_multisampled_render_to_texture') : null;
  14172. const supportsInvalidateFramebuffer = /OculusBrowser/g.test(navigator.userAgent);
  14173. const _videoTextures = new WeakMap();
  14174. let _canvas;
  14175. const _sources = new WeakMap(); // maps WebglTexture objects to instances of Source
  14176. // cordova iOS (as of 5.0) still uses UIWebView, which provides OffscreenCanvas,
  14177. // also OffscreenCanvas.getContext("webgl"), but not OffscreenCanvas.getContext("2d")!
  14178. // Some implementations may only implement OffscreenCanvas partially (e.g. lacking 2d).
  14179. let useOffscreenCanvas = false;
  14180. try {
  14181. useOffscreenCanvas = typeof OffscreenCanvas !== 'undefined' // eslint-disable-next-line compat/compat
  14182. && new OffscreenCanvas(1, 1).getContext('2d') !== null;
  14183. } catch (err) {// Ignore any errors
  14184. }
  14185. function createCanvas(width, height) {
  14186. // Use OffscreenCanvas when available. Specially needed in web workers
  14187. return useOffscreenCanvas ? // eslint-disable-next-line compat/compat
  14188. new OffscreenCanvas(width, height) : createElementNS('canvas');
  14189. }
  14190. function resizeImage(image, needsPowerOfTwo, needsNewCanvas, maxSize) {
  14191. let scale = 1; // handle case if texture exceeds max size
  14192. if (image.width > maxSize || image.height > maxSize) {
  14193. scale = maxSize / Math.max(image.width, image.height);
  14194. } // only perform resize if necessary
  14195. if (scale < 1 || needsPowerOfTwo === true) {
  14196. // only perform resize for certain image types
  14197. if (typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement || typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement || typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap) {
  14198. const floor = needsPowerOfTwo ? floorPowerOfTwo : Math.floor;
  14199. const width = floor(scale * image.width);
  14200. const height = floor(scale * image.height);
  14201. if (_canvas === undefined) _canvas = createCanvas(width, height); // cube textures can't reuse the same canvas
  14202. const canvas = needsNewCanvas ? createCanvas(width, height) : _canvas;
  14203. canvas.width = width;
  14204. canvas.height = height;
  14205. const context = canvas.getContext('2d');
  14206. context.drawImage(image, 0, 0, width, height);
  14207. console.warn('THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').');
  14208. return canvas;
  14209. } else {
  14210. if ('data' in image) {
  14211. console.warn('THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').');
  14212. }
  14213. return image;
  14214. }
  14215. }
  14216. return image;
  14217. }
  14218. function isPowerOfTwo$1(image) {
  14219. return isPowerOfTwo(image.width) && isPowerOfTwo(image.height);
  14220. }
  14221. function textureNeedsPowerOfTwo(texture) {
  14222. if (isWebGL2) return false;
  14223. return texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping || texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
  14224. }
  14225. function textureNeedsGenerateMipmaps(texture, supportsMips) {
  14226. return texture.generateMipmaps && supportsMips && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter;
  14227. }
  14228. function generateMipmap(target) {
  14229. _gl.generateMipmap(target);
  14230. }
  14231. function getInternalFormat(internalFormatName, glFormat, glType, encoding, isVideoTexture = false) {
  14232. if (isWebGL2 === false) return glFormat;
  14233. if (internalFormatName !== null) {
  14234. if (_gl[internalFormatName] !== undefined) return _gl[internalFormatName];
  14235. console.warn('THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'');
  14236. }
  14237. let internalFormat = glFormat;
  14238. if (glFormat === _gl.RED) {
  14239. if (glType === _gl.FLOAT) internalFormat = _gl.R32F;
  14240. if (glType === _gl.HALF_FLOAT) internalFormat = _gl.R16F;
  14241. if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.R8;
  14242. }
  14243. if (glFormat === _gl.RG) {
  14244. if (glType === _gl.FLOAT) internalFormat = _gl.RG32F;
  14245. if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RG16F;
  14246. if (glType === _gl.UNSIGNED_BYTE) internalFormat = _gl.RG8;
  14247. }
  14248. if (glFormat === _gl.RGBA) {
  14249. if (glType === _gl.FLOAT) internalFormat = _gl.RGBA32F;
  14250. if (glType === _gl.HALF_FLOAT) internalFormat = _gl.RGBA16F;
  14251. if (glType === _gl.UNSIGNED_BYTE) internalFormat = encoding === sRGBEncoding && isVideoTexture === false ? _gl.SRGB8_ALPHA8 : _gl.RGBA8;
  14252. if (glType === _gl.UNSIGNED_SHORT_4_4_4_4) internalFormat = _gl.RGBA4;
  14253. if (glType === _gl.UNSIGNED_SHORT_5_5_5_1) internalFormat = _gl.RGB5_A1;
  14254. }
  14255. if (internalFormat === _gl.R16F || internalFormat === _gl.R32F || internalFormat === _gl.RG16F || internalFormat === _gl.RG32F || internalFormat === _gl.RGBA16F || internalFormat === _gl.RGBA32F) {
  14256. extensions.get('EXT_color_buffer_float');
  14257. }
  14258. return internalFormat;
  14259. }
  14260. function getMipLevels(texture, image, supportsMips) {
  14261. if (textureNeedsGenerateMipmaps(texture, supportsMips) === true || texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) {
  14262. return Math.log2(Math.max(image.width, image.height)) + 1;
  14263. } else if (texture.mipmaps !== undefined && texture.mipmaps.length > 0) {
  14264. // user-defined mipmaps
  14265. return texture.mipmaps.length;
  14266. } else if (texture.isCompressedTexture && Array.isArray(texture.image)) {
  14267. return image.mipmaps.length;
  14268. } else {
  14269. // texture without mipmaps (only base level)
  14270. return 1;
  14271. }
  14272. } // Fallback filters for non-power-of-2 textures
  14273. function filterFallback(f) {
  14274. if (f === NearestFilter || f === NearestMipmapNearestFilter || f === NearestMipmapLinearFilter) {
  14275. return _gl.NEAREST;
  14276. }
  14277. return _gl.LINEAR;
  14278. } //
  14279. function onTextureDispose(event) {
  14280. const texture = event.target;
  14281. texture.removeEventListener('dispose', onTextureDispose);
  14282. deallocateTexture(texture);
  14283. if (texture.isVideoTexture) {
  14284. _videoTextures.delete(texture);
  14285. }
  14286. }
  14287. function onRenderTargetDispose(event) {
  14288. const renderTarget = event.target;
  14289. renderTarget.removeEventListener('dispose', onRenderTargetDispose);
  14290. deallocateRenderTarget(renderTarget);
  14291. } //
  14292. function deallocateTexture(texture) {
  14293. const textureProperties = properties.get(texture);
  14294. if (textureProperties.__webglInit === undefined) return; // check if it's necessary to remove the WebGLTexture object
  14295. const source = texture.source;
  14296. const webglTextures = _sources.get(source);
  14297. if (webglTextures) {
  14298. const webglTexture = webglTextures[textureProperties.__cacheKey];
  14299. webglTexture.usedTimes--; // the WebGLTexture object is not used anymore, remove it
  14300. if (webglTexture.usedTimes === 0) {
  14301. deleteTexture(texture);
  14302. } // remove the weak map entry if no WebGLTexture uses the source anymore
  14303. if (Object.keys(webglTextures).length === 0) {
  14304. _sources.delete(source);
  14305. }
  14306. }
  14307. properties.remove(texture);
  14308. }
  14309. function deleteTexture(texture) {
  14310. const textureProperties = properties.get(texture);
  14311. _gl.deleteTexture(textureProperties.__webglTexture);
  14312. const source = texture.source;
  14313. const webglTextures = _sources.get(source);
  14314. delete webglTextures[textureProperties.__cacheKey];
  14315. info.memory.textures--;
  14316. }
  14317. function deallocateRenderTarget(renderTarget) {
  14318. const texture = renderTarget.texture;
  14319. const renderTargetProperties = properties.get(renderTarget);
  14320. const textureProperties = properties.get(texture);
  14321. if (textureProperties.__webglTexture !== undefined) {
  14322. _gl.deleteTexture(textureProperties.__webglTexture);
  14323. info.memory.textures--;
  14324. }
  14325. if (renderTarget.depthTexture) {
  14326. renderTarget.depthTexture.dispose();
  14327. }
  14328. if (renderTarget.isWebGLCubeRenderTarget) {
  14329. for (let i = 0; i < 6; i++) {
  14330. _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer[i]);
  14331. if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer[i]);
  14332. }
  14333. } else {
  14334. _gl.deleteFramebuffer(renderTargetProperties.__webglFramebuffer);
  14335. if (renderTargetProperties.__webglDepthbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthbuffer);
  14336. if (renderTargetProperties.__webglMultisampledFramebuffer) _gl.deleteFramebuffer(renderTargetProperties.__webglMultisampledFramebuffer);
  14337. if (renderTargetProperties.__webglColorRenderbuffer) {
  14338. for (let i = 0; i < renderTargetProperties.__webglColorRenderbuffer.length; i++) {
  14339. if (renderTargetProperties.__webglColorRenderbuffer[i]) _gl.deleteRenderbuffer(renderTargetProperties.__webglColorRenderbuffer[i]);
  14340. }
  14341. }
  14342. if (renderTargetProperties.__webglDepthRenderbuffer) _gl.deleteRenderbuffer(renderTargetProperties.__webglDepthRenderbuffer);
  14343. }
  14344. if (renderTarget.isWebGLMultipleRenderTargets) {
  14345. for (let i = 0, il = texture.length; i < il; i++) {
  14346. const attachmentProperties = properties.get(texture[i]);
  14347. if (attachmentProperties.__webglTexture) {
  14348. _gl.deleteTexture(attachmentProperties.__webglTexture);
  14349. info.memory.textures--;
  14350. }
  14351. properties.remove(texture[i]);
  14352. }
  14353. }
  14354. properties.remove(texture);
  14355. properties.remove(renderTarget);
  14356. } //
  14357. let textureUnits = 0;
  14358. function resetTextureUnits() {
  14359. textureUnits = 0;
  14360. }
  14361. function allocateTextureUnit() {
  14362. const textureUnit = textureUnits;
  14363. if (textureUnit >= maxTextures) {
  14364. console.warn('THREE.WebGLTextures: Trying to use ' + textureUnit + ' texture units while this GPU supports only ' + maxTextures);
  14365. }
  14366. textureUnits += 1;
  14367. return textureUnit;
  14368. }
  14369. function getTextureCacheKey(texture) {
  14370. const array = [];
  14371. array.push(texture.wrapS);
  14372. array.push(texture.wrapT);
  14373. array.push(texture.magFilter);
  14374. array.push(texture.minFilter);
  14375. array.push(texture.anisotropy);
  14376. array.push(texture.internalFormat);
  14377. array.push(texture.format);
  14378. array.push(texture.type);
  14379. array.push(texture.generateMipmaps);
  14380. array.push(texture.premultiplyAlpha);
  14381. array.push(texture.flipY);
  14382. array.push(texture.unpackAlignment);
  14383. array.push(texture.encoding);
  14384. return array.join();
  14385. } //
  14386. function setTexture2D(texture, slot) {
  14387. const textureProperties = properties.get(texture);
  14388. if (texture.isVideoTexture) updateVideoTexture(texture);
  14389. if (texture.isRenderTargetTexture === false && texture.version > 0 && textureProperties.__version !== texture.version) {
  14390. const image = texture.image;
  14391. if (image === null) {
  14392. console.warn('THREE.WebGLRenderer: Texture marked for update but no image data found.');
  14393. } else if (image.complete === false) {
  14394. console.warn('THREE.WebGLRenderer: Texture marked for update but image is incomplete');
  14395. } else {
  14396. uploadTexture(textureProperties, texture, slot);
  14397. return;
  14398. }
  14399. }
  14400. state.activeTexture(_gl.TEXTURE0 + slot);
  14401. state.bindTexture(_gl.TEXTURE_2D, textureProperties.__webglTexture);
  14402. }
  14403. function setTexture2DArray(texture, slot) {
  14404. const textureProperties = properties.get(texture);
  14405. if (texture.version > 0 && textureProperties.__version !== texture.version) {
  14406. uploadTexture(textureProperties, texture, slot);
  14407. return;
  14408. }
  14409. state.activeTexture(_gl.TEXTURE0 + slot);
  14410. state.bindTexture(_gl.TEXTURE_2D_ARRAY, textureProperties.__webglTexture);
  14411. }
  14412. function setTexture3D(texture, slot) {
  14413. const textureProperties = properties.get(texture);
  14414. if (texture.version > 0 && textureProperties.__version !== texture.version) {
  14415. uploadTexture(textureProperties, texture, slot);
  14416. return;
  14417. }
  14418. state.activeTexture(_gl.TEXTURE0 + slot);
  14419. state.bindTexture(_gl.TEXTURE_3D, textureProperties.__webglTexture);
  14420. }
  14421. function setTextureCube(texture, slot) {
  14422. const textureProperties = properties.get(texture);
  14423. if (texture.version > 0 && textureProperties.__version !== texture.version) {
  14424. uploadCubeTexture(textureProperties, texture, slot);
  14425. return;
  14426. }
  14427. state.activeTexture(_gl.TEXTURE0 + slot);
  14428. state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
  14429. }
  14430. const wrappingToGL = {
  14431. [RepeatWrapping]: _gl.REPEAT,
  14432. [ClampToEdgeWrapping]: _gl.CLAMP_TO_EDGE,
  14433. [MirroredRepeatWrapping]: _gl.MIRRORED_REPEAT
  14434. };
  14435. const filterToGL = {
  14436. [NearestFilter]: _gl.NEAREST,
  14437. [NearestMipmapNearestFilter]: _gl.NEAREST_MIPMAP_NEAREST,
  14438. [NearestMipmapLinearFilter]: _gl.NEAREST_MIPMAP_LINEAR,
  14439. [LinearFilter]: _gl.LINEAR,
  14440. [LinearMipmapNearestFilter]: _gl.LINEAR_MIPMAP_NEAREST,
  14441. [LinearMipmapLinearFilter]: _gl.LINEAR_MIPMAP_LINEAR
  14442. };
  14443. function setTextureParameters(textureType, texture, supportsMips) {
  14444. if (supportsMips) {
  14445. _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, wrappingToGL[texture.wrapS]);
  14446. _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, wrappingToGL[texture.wrapT]);
  14447. if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) {
  14448. _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, wrappingToGL[texture.wrapR]);
  14449. }
  14450. _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterToGL[texture.magFilter]);
  14451. _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterToGL[texture.minFilter]);
  14452. } else {
  14453. _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE);
  14454. _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE);
  14455. if (textureType === _gl.TEXTURE_3D || textureType === _gl.TEXTURE_2D_ARRAY) {
  14456. _gl.texParameteri(textureType, _gl.TEXTURE_WRAP_R, _gl.CLAMP_TO_EDGE);
  14457. }
  14458. if (texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping) {
  14459. console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.');
  14460. }
  14461. _gl.texParameteri(textureType, _gl.TEXTURE_MAG_FILTER, filterFallback(texture.magFilter));
  14462. _gl.texParameteri(textureType, _gl.TEXTURE_MIN_FILTER, filterFallback(texture.minFilter));
  14463. if (texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter) {
  14464. console.warn('THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.');
  14465. }
  14466. }
  14467. if (extensions.has('EXT_texture_filter_anisotropic') === true) {
  14468. const extension = extensions.get('EXT_texture_filter_anisotropic');
  14469. if (texture.type === FloatType && extensions.has('OES_texture_float_linear') === false) return; // verify extension for WebGL 1 and WebGL 2
  14470. if (isWebGL2 === false && texture.type === HalfFloatType && extensions.has('OES_texture_half_float_linear') === false) return; // verify extension for WebGL 1 only
  14471. if (texture.anisotropy > 1 || properties.get(texture).__currentAnisotropy) {
  14472. _gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min(texture.anisotropy, capabilities.getMaxAnisotropy()));
  14473. properties.get(texture).__currentAnisotropy = texture.anisotropy;
  14474. }
  14475. }
  14476. }
  14477. function initTexture(textureProperties, texture) {
  14478. let forceUpload = false;
  14479. if (textureProperties.__webglInit === undefined) {
  14480. textureProperties.__webglInit = true;
  14481. texture.addEventListener('dispose', onTextureDispose);
  14482. } // create Source <-> WebGLTextures mapping if necessary
  14483. const source = texture.source;
  14484. let webglTextures = _sources.get(source);
  14485. if (webglTextures === undefined) {
  14486. webglTextures = {};
  14487. _sources.set(source, webglTextures);
  14488. } // check if there is already a WebGLTexture object for the given texture parameters
  14489. const textureCacheKey = getTextureCacheKey(texture);
  14490. if (textureCacheKey !== textureProperties.__cacheKey) {
  14491. // if not, create a new instance of WebGLTexture
  14492. if (webglTextures[textureCacheKey] === undefined) {
  14493. // create new entry
  14494. webglTextures[textureCacheKey] = {
  14495. texture: _gl.createTexture(),
  14496. usedTimes: 0
  14497. };
  14498. info.memory.textures++; // when a new instance of WebGLTexture was created, a texture upload is required
  14499. // even if the image contents are identical
  14500. forceUpload = true;
  14501. }
  14502. webglTextures[textureCacheKey].usedTimes++; // every time the texture cache key changes, it's necessary to check if an instance of
  14503. // WebGLTexture can be deleted in order to avoid a memory leak.
  14504. const webglTexture = webglTextures[textureProperties.__cacheKey];
  14505. if (webglTexture !== undefined) {
  14506. webglTextures[textureProperties.__cacheKey].usedTimes--;
  14507. if (webglTexture.usedTimes === 0) {
  14508. deleteTexture(texture);
  14509. }
  14510. } // store references to cache key and WebGLTexture object
  14511. textureProperties.__cacheKey = textureCacheKey;
  14512. textureProperties.__webglTexture = webglTextures[textureCacheKey].texture;
  14513. }
  14514. return forceUpload;
  14515. }
  14516. function uploadTexture(textureProperties, texture, slot) {
  14517. let textureType = _gl.TEXTURE_2D;
  14518. if (texture.isDataArrayTexture) textureType = _gl.TEXTURE_2D_ARRAY;
  14519. if (texture.isData3DTexture) textureType = _gl.TEXTURE_3D;
  14520. const forceUpload = initTexture(textureProperties, texture);
  14521. const source = texture.source;
  14522. state.activeTexture(_gl.TEXTURE0 + slot);
  14523. state.bindTexture(textureType, textureProperties.__webglTexture);
  14524. if (source.version !== source.__currentVersion || forceUpload === true) {
  14525. _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
  14526. _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
  14527. _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
  14528. _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE);
  14529. const needsPowerOfTwo = textureNeedsPowerOfTwo(texture) && isPowerOfTwo$1(texture.image) === false;
  14530. let image = resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize);
  14531. image = verifyColorSpace(texture, image);
  14532. const supportsMips = isPowerOfTwo$1(image) || isWebGL2,
  14533. glFormat = utils.convert(texture.format, texture.encoding);
  14534. let glType = utils.convert(texture.type),
  14535. glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding, texture.isVideoTexture);
  14536. setTextureParameters(textureType, texture, supportsMips);
  14537. let mipmap;
  14538. const mipmaps = texture.mipmaps;
  14539. const useTexStorage = isWebGL2 && texture.isVideoTexture !== true;
  14540. const allocateMemory = source.__currentVersion === undefined || forceUpload === true;
  14541. const levels = getMipLevels(texture, image, supportsMips);
  14542. if (texture.isDepthTexture) {
  14543. // populate depth texture with dummy data
  14544. glInternalFormat = _gl.DEPTH_COMPONENT;
  14545. if (isWebGL2) {
  14546. if (texture.type === FloatType) {
  14547. glInternalFormat = _gl.DEPTH_COMPONENT32F;
  14548. } else if (texture.type === UnsignedIntType) {
  14549. glInternalFormat = _gl.DEPTH_COMPONENT24;
  14550. } else if (texture.type === UnsignedInt248Type) {
  14551. glInternalFormat = _gl.DEPTH24_STENCIL8;
  14552. } else {
  14553. glInternalFormat = _gl.DEPTH_COMPONENT16; // WebGL2 requires sized internalformat for glTexImage2D
  14554. }
  14555. } else {
  14556. if (texture.type === FloatType) {
  14557. console.error('WebGLRenderer: Floating point depth texture requires WebGL2.');
  14558. }
  14559. } // validation checks for WebGL 1
  14560. if (texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT) {
  14561. // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
  14562. // DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
  14563. // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
  14564. if (texture.type !== UnsignedShortType && texture.type !== UnsignedIntType) {
  14565. console.warn('THREE.WebGLRenderer: Use UnsignedShortType or UnsignedIntType for DepthFormat DepthTexture.');
  14566. texture.type = UnsignedIntType;
  14567. glType = utils.convert(texture.type);
  14568. }
  14569. }
  14570. if (texture.format === DepthStencilFormat && glInternalFormat === _gl.DEPTH_COMPONENT) {
  14571. // Depth stencil textures need the DEPTH_STENCIL internal format
  14572. // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
  14573. glInternalFormat = _gl.DEPTH_STENCIL; // The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
  14574. // DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
  14575. // (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
  14576. if (texture.type !== UnsignedInt248Type) {
  14577. console.warn('THREE.WebGLRenderer: Use UnsignedInt248Type for DepthStencilFormat DepthTexture.');
  14578. texture.type = UnsignedInt248Type;
  14579. glType = utils.convert(texture.type);
  14580. }
  14581. } //
  14582. if (allocateMemory) {
  14583. if (useTexStorage) {
  14584. state.texStorage2D(_gl.TEXTURE_2D, 1, glInternalFormat, image.width, image.height);
  14585. } else {
  14586. state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null);
  14587. }
  14588. }
  14589. } else if (texture.isDataTexture) {
  14590. // use manually created mipmaps if available
  14591. // if there are no manual mipmaps
  14592. // set 0 level mipmap and then use GL to generate other mipmap levels
  14593. if (mipmaps.length > 0 && supportsMips) {
  14594. if (useTexStorage && allocateMemory) {
  14595. state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
  14596. }
  14597. for (let i = 0, il = mipmaps.length; i < il; i++) {
  14598. mipmap = mipmaps[i];
  14599. if (useTexStorage) {
  14600. state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
  14601. } else {
  14602. state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
  14603. }
  14604. }
  14605. texture.generateMipmaps = false;
  14606. } else {
  14607. if (useTexStorage) {
  14608. if (allocateMemory) {
  14609. state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
  14610. }
  14611. state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data);
  14612. } else {
  14613. state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data);
  14614. }
  14615. }
  14616. } else if (texture.isCompressedTexture) {
  14617. if (useTexStorage && allocateMemory) {
  14618. state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
  14619. }
  14620. for (let i = 0, il = mipmaps.length; i < il; i++) {
  14621. mipmap = mipmaps[i];
  14622. if (texture.format !== RGBAFormat) {
  14623. if (glFormat !== null) {
  14624. if (useTexStorage) {
  14625. state.compressedTexSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
  14626. } else {
  14627. state.compressedTexImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
  14628. }
  14629. } else {
  14630. console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()');
  14631. }
  14632. } else {
  14633. if (useTexStorage) {
  14634. state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
  14635. } else {
  14636. state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
  14637. }
  14638. }
  14639. }
  14640. } else if (texture.isDataArrayTexture) {
  14641. if (useTexStorage) {
  14642. if (allocateMemory) {
  14643. state.texStorage3D(_gl.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth);
  14644. }
  14645. state.texSubImage3D(_gl.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
  14646. } else {
  14647. state.texImage3D(_gl.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data);
  14648. }
  14649. } else if (texture.isData3DTexture) {
  14650. if (useTexStorage) {
  14651. if (allocateMemory) {
  14652. state.texStorage3D(_gl.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth);
  14653. }
  14654. state.texSubImage3D(_gl.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data);
  14655. } else {
  14656. state.texImage3D(_gl.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data);
  14657. }
  14658. } else if (texture.isFramebufferTexture) {
  14659. if (allocateMemory) {
  14660. if (useTexStorage) {
  14661. state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
  14662. } else {
  14663. let width = image.width,
  14664. height = image.height;
  14665. for (let i = 0; i < levels; i++) {
  14666. state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null);
  14667. width >>= 1;
  14668. height >>= 1;
  14669. }
  14670. }
  14671. }
  14672. } else {
  14673. // regular Texture (image, video, canvas)
  14674. // use manually created mipmaps if available
  14675. // if there are no manual mipmaps
  14676. // set 0 level mipmap and then use GL to generate other mipmap levels
  14677. if (mipmaps.length > 0 && supportsMips) {
  14678. if (useTexStorage && allocateMemory) {
  14679. state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height);
  14680. }
  14681. for (let i = 0, il = mipmaps.length; i < il; i++) {
  14682. mipmap = mipmaps[i];
  14683. if (useTexStorage) {
  14684. state.texSubImage2D(_gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap);
  14685. } else {
  14686. state.texImage2D(_gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap);
  14687. }
  14688. }
  14689. texture.generateMipmaps = false;
  14690. } else {
  14691. if (useTexStorage) {
  14692. if (allocateMemory) {
  14693. state.texStorage2D(_gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height);
  14694. }
  14695. state.texSubImage2D(_gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image);
  14696. } else {
  14697. state.texImage2D(_gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image);
  14698. }
  14699. }
  14700. }
  14701. if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
  14702. generateMipmap(textureType);
  14703. }
  14704. source.__currentVersion = source.version;
  14705. if (texture.onUpdate) texture.onUpdate(texture);
  14706. }
  14707. textureProperties.__version = texture.version;
  14708. }
  14709. function uploadCubeTexture(textureProperties, texture, slot) {
  14710. if (texture.image.length !== 6) return;
  14711. const forceUpload = initTexture(textureProperties, texture);
  14712. const source = texture.source;
  14713. state.activeTexture(_gl.TEXTURE0 + slot);
  14714. state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
  14715. if (source.version !== source.__currentVersion || forceUpload === true) {
  14716. _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, texture.flipY);
  14717. _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha);
  14718. _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, texture.unpackAlignment);
  14719. _gl.pixelStorei(_gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, _gl.NONE);
  14720. const isCompressed = texture.isCompressedTexture || texture.image[0].isCompressedTexture;
  14721. const isDataTexture = texture.image[0] && texture.image[0].isDataTexture;
  14722. const cubeImage = [];
  14723. for (let i = 0; i < 6; i++) {
  14724. if (!isCompressed && !isDataTexture) {
  14725. cubeImage[i] = resizeImage(texture.image[i], false, true, maxCubemapSize);
  14726. } else {
  14727. cubeImage[i] = isDataTexture ? texture.image[i].image : texture.image[i];
  14728. }
  14729. cubeImage[i] = verifyColorSpace(texture, cubeImage[i]);
  14730. }
  14731. const image = cubeImage[0],
  14732. supportsMips = isPowerOfTwo$1(image) || isWebGL2,
  14733. glFormat = utils.convert(texture.format, texture.encoding),
  14734. glType = utils.convert(texture.type),
  14735. glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
  14736. const useTexStorage = isWebGL2 && texture.isVideoTexture !== true;
  14737. const allocateMemory = source.__currentVersion === undefined || forceUpload === true;
  14738. let levels = getMipLevels(texture, image, supportsMips);
  14739. setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips);
  14740. let mipmaps;
  14741. if (isCompressed) {
  14742. if (useTexStorage && allocateMemory) {
  14743. state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height);
  14744. }
  14745. for (let i = 0; i < 6; i++) {
  14746. mipmaps = cubeImage[i].mipmaps;
  14747. for (let j = 0; j < mipmaps.length; j++) {
  14748. const mipmap = mipmaps[j];
  14749. if (texture.format !== RGBAFormat) {
  14750. if (glFormat !== null) {
  14751. if (useTexStorage) {
  14752. state.compressedTexSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data);
  14753. } else {
  14754. state.compressedTexImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data);
  14755. }
  14756. } else {
  14757. console.warn('THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()');
  14758. }
  14759. } else {
  14760. if (useTexStorage) {
  14761. state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data);
  14762. } else {
  14763. state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data);
  14764. }
  14765. }
  14766. }
  14767. }
  14768. } else {
  14769. mipmaps = texture.mipmaps;
  14770. if (useTexStorage && allocateMemory) {
  14771. // TODO: Uniformly handle mipmap definitions
  14772. // Normal textures and compressed cube textures define base level + mips with their mipmap array
  14773. // Uncompressed cube textures use their mipmap array only for mips (no base level)
  14774. if (mipmaps.length > 0) levels++;
  14775. state.texStorage2D(_gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height);
  14776. }
  14777. for (let i = 0; i < 6; i++) {
  14778. if (isDataTexture) {
  14779. if (useTexStorage) {
  14780. state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data);
  14781. } else {
  14782. state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width, cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data);
  14783. }
  14784. for (let j = 0; j < mipmaps.length; j++) {
  14785. const mipmap = mipmaps[j];
  14786. const mipmapImage = mipmap.image[i].image;
  14787. if (useTexStorage) {
  14788. state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, mipmapImage.height, glFormat, glType, mipmapImage.data);
  14789. } else {
  14790. state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, mipmapImage.height, 0, glFormat, glType, mipmapImage.data);
  14791. }
  14792. }
  14793. } else {
  14794. if (useTexStorage) {
  14795. state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]);
  14796. } else {
  14797. state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]);
  14798. }
  14799. for (let j = 0; j < mipmaps.length; j++) {
  14800. const mipmap = mipmaps[j];
  14801. if (useTexStorage) {
  14802. state.texSubImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]);
  14803. } else {
  14804. state.texImage2D(_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]);
  14805. }
  14806. }
  14807. }
  14808. }
  14809. }
  14810. if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
  14811. // We assume images for cube map have the same size.
  14812. generateMipmap(_gl.TEXTURE_CUBE_MAP);
  14813. }
  14814. source.__currentVersion = source.version;
  14815. if (texture.onUpdate) texture.onUpdate(texture);
  14816. }
  14817. textureProperties.__version = texture.version;
  14818. } // Render targets
  14819. // Setup storage for target texture and bind it to correct framebuffer
  14820. function setupFrameBufferTexture(framebuffer, renderTarget, texture, attachment, textureTarget) {
  14821. const glFormat = utils.convert(texture.format, texture.encoding);
  14822. const glType = utils.convert(texture.type);
  14823. const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
  14824. const renderTargetProperties = properties.get(renderTarget);
  14825. if (!renderTargetProperties.__hasExternalTextures) {
  14826. if (textureTarget === _gl.TEXTURE_3D || textureTarget === _gl.TEXTURE_2D_ARRAY) {
  14827. state.texImage3D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, renderTarget.depth, 0, glFormat, glType, null);
  14828. } else {
  14829. state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null);
  14830. }
  14831. }
  14832. state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
  14833. if (useMultisampledRTT(renderTarget)) {
  14834. multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0, getRenderTargetSamples(renderTarget));
  14835. } else {
  14836. _gl.framebufferTexture2D(_gl.FRAMEBUFFER, attachment, textureTarget, properties.get(texture).__webglTexture, 0);
  14837. }
  14838. state.bindFramebuffer(_gl.FRAMEBUFFER, null);
  14839. } // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
  14840. function setupRenderBufferStorage(renderbuffer, renderTarget, isMultisample) {
  14841. _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderbuffer);
  14842. if (renderTarget.depthBuffer && !renderTarget.stencilBuffer) {
  14843. let glInternalFormat = _gl.DEPTH_COMPONENT16;
  14844. if (isMultisample || useMultisampledRTT(renderTarget)) {
  14845. const depthTexture = renderTarget.depthTexture;
  14846. if (depthTexture && depthTexture.isDepthTexture) {
  14847. if (depthTexture.type === FloatType) {
  14848. glInternalFormat = _gl.DEPTH_COMPONENT32F;
  14849. } else if (depthTexture.type === UnsignedIntType) {
  14850. glInternalFormat = _gl.DEPTH_COMPONENT24;
  14851. }
  14852. }
  14853. const samples = getRenderTargetSamples(renderTarget);
  14854. if (useMultisampledRTT(renderTarget)) {
  14855. multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
  14856. } else {
  14857. _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
  14858. }
  14859. } else {
  14860. _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height);
  14861. }
  14862. _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer);
  14863. } else if (renderTarget.depthBuffer && renderTarget.stencilBuffer) {
  14864. const samples = getRenderTargetSamples(renderTarget);
  14865. if (isMultisample && useMultisampledRTT(renderTarget) === false) {
  14866. _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height);
  14867. } else if (useMultisampledRTT(renderTarget)) {
  14868. multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height);
  14869. } else {
  14870. _gl.renderbufferStorage(_gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height);
  14871. }
  14872. _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer);
  14873. } else {
  14874. const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture];
  14875. for (let i = 0; i < textures.length; i++) {
  14876. const texture = textures[i];
  14877. const glFormat = utils.convert(texture.format, texture.encoding);
  14878. const glType = utils.convert(texture.type);
  14879. const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
  14880. const samples = getRenderTargetSamples(renderTarget);
  14881. if (isMultisample && useMultisampledRTT(renderTarget) === false) {
  14882. _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
  14883. } else if (useMultisampledRTT(renderTarget)) {
  14884. multisampledRTTExt.renderbufferStorageMultisampleEXT(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
  14885. } else {
  14886. _gl.renderbufferStorage(_gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height);
  14887. }
  14888. }
  14889. }
  14890. _gl.bindRenderbuffer(_gl.RENDERBUFFER, null);
  14891. } // Setup resources for a Depth Texture for a FBO (needs an extension)
  14892. function setupDepthTexture(framebuffer, renderTarget) {
  14893. const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget;
  14894. if (isCube) throw new Error('Depth Texture with cube render targets is not supported');
  14895. state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
  14896. if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) {
  14897. throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
  14898. } // upload an empty depth texture with framebuffer size
  14899. if (!properties.get(renderTarget.depthTexture).__webglTexture || renderTarget.depthTexture.image.width !== renderTarget.width || renderTarget.depthTexture.image.height !== renderTarget.height) {
  14900. renderTarget.depthTexture.image.width = renderTarget.width;
  14901. renderTarget.depthTexture.image.height = renderTarget.height;
  14902. renderTarget.depthTexture.needsUpdate = true;
  14903. }
  14904. setTexture2D(renderTarget.depthTexture, 0);
  14905. const webglDepthTexture = properties.get(renderTarget.depthTexture).__webglTexture;
  14906. const samples = getRenderTargetSamples(renderTarget);
  14907. if (renderTarget.depthTexture.format === DepthFormat) {
  14908. if (useMultisampledRTT(renderTarget)) {
  14909. multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples);
  14910. } else {
  14911. _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0);
  14912. }
  14913. } else if (renderTarget.depthTexture.format === DepthStencilFormat) {
  14914. if (useMultisampledRTT(renderTarget)) {
  14915. multisampledRTTExt.framebufferTexture2DMultisampleEXT(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0, samples);
  14916. } else {
  14917. _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0);
  14918. }
  14919. } else {
  14920. throw new Error('Unknown depthTexture format');
  14921. }
  14922. } // Setup GL resources for a non-texture depth buffer
  14923. function setupDepthRenderbuffer(renderTarget) {
  14924. const renderTargetProperties = properties.get(renderTarget);
  14925. const isCube = renderTarget.isWebGLCubeRenderTarget === true;
  14926. if (renderTarget.depthTexture && !renderTargetProperties.__autoAllocateDepthBuffer) {
  14927. if (isCube) throw new Error('target.depthTexture not supported in Cube render targets');
  14928. setupDepthTexture(renderTargetProperties.__webglFramebuffer, renderTarget);
  14929. } else {
  14930. if (isCube) {
  14931. renderTargetProperties.__webglDepthbuffer = [];
  14932. for (let i = 0; i < 6; i++) {
  14933. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[i]);
  14934. renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer();
  14935. setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false);
  14936. }
  14937. } else {
  14938. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
  14939. renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
  14940. setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false);
  14941. }
  14942. }
  14943. state.bindFramebuffer(_gl.FRAMEBUFFER, null);
  14944. } // rebind framebuffer with external textures
  14945. function rebindTextures(renderTarget, colorTexture, depthTexture) {
  14946. const renderTargetProperties = properties.get(renderTarget);
  14947. if (colorTexture !== undefined) {
  14948. setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, renderTarget.texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D);
  14949. }
  14950. if (depthTexture !== undefined) {
  14951. setupDepthRenderbuffer(renderTarget);
  14952. }
  14953. } // Set up GL resources for the render target
  14954. function setupRenderTarget(renderTarget) {
  14955. const texture = renderTarget.texture;
  14956. const renderTargetProperties = properties.get(renderTarget);
  14957. const textureProperties = properties.get(texture);
  14958. renderTarget.addEventListener('dispose', onRenderTargetDispose);
  14959. if (renderTarget.isWebGLMultipleRenderTargets !== true) {
  14960. if (textureProperties.__webglTexture === undefined) {
  14961. textureProperties.__webglTexture = _gl.createTexture();
  14962. }
  14963. textureProperties.__version = texture.version;
  14964. info.memory.textures++;
  14965. }
  14966. const isCube = renderTarget.isWebGLCubeRenderTarget === true;
  14967. const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true;
  14968. const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2; // Setup framebuffer
  14969. if (isCube) {
  14970. renderTargetProperties.__webglFramebuffer = [];
  14971. for (let i = 0; i < 6; i++) {
  14972. renderTargetProperties.__webglFramebuffer[i] = _gl.createFramebuffer();
  14973. }
  14974. } else {
  14975. renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
  14976. if (isMultipleRenderTargets) {
  14977. if (capabilities.drawBuffers) {
  14978. const textures = renderTarget.texture;
  14979. for (let i = 0, il = textures.length; i < il; i++) {
  14980. const attachmentProperties = properties.get(textures[i]);
  14981. if (attachmentProperties.__webglTexture === undefined) {
  14982. attachmentProperties.__webglTexture = _gl.createTexture();
  14983. info.memory.textures++;
  14984. }
  14985. }
  14986. } else {
  14987. console.warn('THREE.WebGLRenderer: WebGLMultipleRenderTargets can only be used with WebGL2 or WEBGL_draw_buffers extension.');
  14988. }
  14989. }
  14990. if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) {
  14991. const textures = isMultipleRenderTargets ? texture : [texture];
  14992. renderTargetProperties.__webglMultisampledFramebuffer = _gl.createFramebuffer();
  14993. renderTargetProperties.__webglColorRenderbuffer = [];
  14994. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
  14995. for (let i = 0; i < textures.length; i++) {
  14996. const texture = textures[i];
  14997. renderTargetProperties.__webglColorRenderbuffer[i] = _gl.createRenderbuffer();
  14998. _gl.bindRenderbuffer(_gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
  14999. const glFormat = utils.convert(texture.format, texture.encoding);
  15000. const glType = utils.convert(texture.type);
  15001. const glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.encoding);
  15002. const samples = getRenderTargetSamples(renderTarget);
  15003. _gl.renderbufferStorageMultisample(_gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height);
  15004. _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
  15005. }
  15006. _gl.bindRenderbuffer(_gl.RENDERBUFFER, null);
  15007. if (renderTarget.depthBuffer) {
  15008. renderTargetProperties.__webglDepthRenderbuffer = _gl.createRenderbuffer();
  15009. setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true);
  15010. }
  15011. state.bindFramebuffer(_gl.FRAMEBUFFER, null);
  15012. }
  15013. } // Setup color buffer
  15014. if (isCube) {
  15015. state.bindTexture(_gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture);
  15016. setTextureParameters(_gl.TEXTURE_CUBE_MAP, texture, supportsMips);
  15017. for (let i = 0; i < 6; i++) {
  15018. setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer[i], renderTarget, texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i);
  15019. }
  15020. if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
  15021. generateMipmap(_gl.TEXTURE_CUBE_MAP);
  15022. }
  15023. state.unbindTexture();
  15024. } else if (isMultipleRenderTargets) {
  15025. const textures = renderTarget.texture;
  15026. for (let i = 0, il = textures.length; i < il; i++) {
  15027. const attachment = textures[i];
  15028. const attachmentProperties = properties.get(attachment);
  15029. state.bindTexture(_gl.TEXTURE_2D, attachmentProperties.__webglTexture);
  15030. setTextureParameters(_gl.TEXTURE_2D, attachment, supportsMips);
  15031. setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, attachment, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D);
  15032. if (textureNeedsGenerateMipmaps(attachment, supportsMips)) {
  15033. generateMipmap(_gl.TEXTURE_2D);
  15034. }
  15035. }
  15036. state.unbindTexture();
  15037. } else {
  15038. let glTextureType = _gl.TEXTURE_2D;
  15039. if (renderTarget.isWebGL3DRenderTarget || renderTarget.isWebGLArrayRenderTarget) {
  15040. if (isWebGL2) {
  15041. glTextureType = renderTarget.isWebGL3DRenderTarget ? _gl.TEXTURE_3D : _gl.TEXTURE_2D_ARRAY;
  15042. } else {
  15043. console.error('THREE.WebGLTextures: THREE.Data3DTexture and THREE.DataArrayTexture only supported with WebGL2.');
  15044. }
  15045. }
  15046. state.bindTexture(glTextureType, textureProperties.__webglTexture);
  15047. setTextureParameters(glTextureType, texture, supportsMips);
  15048. setupFrameBufferTexture(renderTargetProperties.__webglFramebuffer, renderTarget, texture, _gl.COLOR_ATTACHMENT0, glTextureType);
  15049. if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
  15050. generateMipmap(glTextureType);
  15051. }
  15052. state.unbindTexture();
  15053. } // Setup depth and stencil buffers
  15054. if (renderTarget.depthBuffer) {
  15055. setupDepthRenderbuffer(renderTarget);
  15056. }
  15057. }
  15058. function updateRenderTargetMipmap(renderTarget) {
  15059. const supportsMips = isPowerOfTwo$1(renderTarget) || isWebGL2;
  15060. const textures = renderTarget.isWebGLMultipleRenderTargets === true ? renderTarget.texture : [renderTarget.texture];
  15061. for (let i = 0, il = textures.length; i < il; i++) {
  15062. const texture = textures[i];
  15063. if (textureNeedsGenerateMipmaps(texture, supportsMips)) {
  15064. const target = renderTarget.isWebGLCubeRenderTarget ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
  15065. const webglTexture = properties.get(texture).__webglTexture;
  15066. state.bindTexture(target, webglTexture);
  15067. generateMipmap(target);
  15068. state.unbindTexture();
  15069. }
  15070. }
  15071. }
  15072. function updateMultisampleRenderTarget(renderTarget) {
  15073. if (isWebGL2 && renderTarget.samples > 0 && useMultisampledRTT(renderTarget) === false) {
  15074. const textures = renderTarget.isWebGLMultipleRenderTargets ? renderTarget.texture : [renderTarget.texture];
  15075. const width = renderTarget.width;
  15076. const height = renderTarget.height;
  15077. let mask = _gl.COLOR_BUFFER_BIT;
  15078. const invalidationArray = [];
  15079. const depthStyle = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
  15080. const renderTargetProperties = properties.get(renderTarget);
  15081. const isMultipleRenderTargets = renderTarget.isWebGLMultipleRenderTargets === true; // If MRT we need to remove FBO attachments
  15082. if (isMultipleRenderTargets) {
  15083. for (let i = 0; i < textures.length; i++) {
  15084. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
  15085. _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, null);
  15086. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
  15087. _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, null, 0);
  15088. }
  15089. }
  15090. state.bindFramebuffer(_gl.READ_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
  15091. state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
  15092. for (let i = 0; i < textures.length; i++) {
  15093. invalidationArray.push(_gl.COLOR_ATTACHMENT0 + i);
  15094. if (renderTarget.depthBuffer) {
  15095. invalidationArray.push(depthStyle);
  15096. }
  15097. const ignoreDepthValues = renderTargetProperties.__ignoreDepthValues !== undefined ? renderTargetProperties.__ignoreDepthValues : false;
  15098. if (ignoreDepthValues === false) {
  15099. if (renderTarget.depthBuffer) mask |= _gl.DEPTH_BUFFER_BIT;
  15100. if (renderTarget.stencilBuffer) mask |= _gl.STENCIL_BUFFER_BIT;
  15101. }
  15102. if (isMultipleRenderTargets) {
  15103. _gl.framebufferRenderbuffer(_gl.READ_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
  15104. }
  15105. if (ignoreDepthValues === true) {
  15106. _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, [depthStyle]);
  15107. _gl.invalidateFramebuffer(_gl.DRAW_FRAMEBUFFER, [depthStyle]);
  15108. }
  15109. if (isMultipleRenderTargets) {
  15110. const webglTexture = properties.get(textures[i]).__webglTexture;
  15111. _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D, webglTexture, 0);
  15112. }
  15113. _gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, _gl.NEAREST);
  15114. if (supportsInvalidateFramebuffer) {
  15115. _gl.invalidateFramebuffer(_gl.READ_FRAMEBUFFER, invalidationArray);
  15116. }
  15117. }
  15118. state.bindFramebuffer(_gl.READ_FRAMEBUFFER, null);
  15119. state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, null); // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments
  15120. if (isMultipleRenderTargets) {
  15121. for (let i = 0; i < textures.length; i++) {
  15122. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
  15123. _gl.framebufferRenderbuffer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.RENDERBUFFER, renderTargetProperties.__webglColorRenderbuffer[i]);
  15124. const webglTexture = properties.get(textures[i]).__webglTexture;
  15125. state.bindFramebuffer(_gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer);
  15126. _gl.framebufferTexture2D(_gl.DRAW_FRAMEBUFFER, _gl.COLOR_ATTACHMENT0 + i, _gl.TEXTURE_2D, webglTexture, 0);
  15127. }
  15128. }
  15129. state.bindFramebuffer(_gl.DRAW_FRAMEBUFFER, renderTargetProperties.__webglMultisampledFramebuffer);
  15130. }
  15131. }
  15132. function getRenderTargetSamples(renderTarget) {
  15133. return Math.min(maxSamples, renderTarget.samples);
  15134. }
  15135. function useMultisampledRTT(renderTarget) {
  15136. const renderTargetProperties = properties.get(renderTarget);
  15137. return isWebGL2 && renderTarget.samples > 0 && extensions.has('WEBGL_multisampled_render_to_texture') === true && renderTargetProperties.__useRenderToTexture !== false;
  15138. }
  15139. function updateVideoTexture(texture) {
  15140. const frame = info.render.frame; // Check the last frame we updated the VideoTexture
  15141. if (_videoTextures.get(texture) !== frame) {
  15142. _videoTextures.set(texture, frame);
  15143. texture.update();
  15144. }
  15145. }
  15146. function verifyColorSpace(texture, image) {
  15147. const encoding = texture.encoding;
  15148. const format = texture.format;
  15149. const type = texture.type;
  15150. if (texture.isCompressedTexture === true || texture.isVideoTexture === true || texture.format === _SRGBAFormat) return image;
  15151. if (encoding !== LinearEncoding) {
  15152. // sRGB
  15153. if (encoding === sRGBEncoding) {
  15154. if (isWebGL2 === false) {
  15155. // in WebGL 1, try to use EXT_sRGB extension and unsized formats
  15156. if (extensions.has('EXT_sRGB') === true && format === RGBAFormat) {
  15157. texture.format = _SRGBAFormat; // it's not possible to generate mips in WebGL 1 with this extension
  15158. texture.minFilter = LinearFilter;
  15159. texture.generateMipmaps = false;
  15160. } else {
  15161. // slow fallback (CPU decode)
  15162. image = ImageUtils.sRGBToLinear(image);
  15163. }
  15164. } else {
  15165. // in WebGL 2 uncompressed textures can only be sRGB encoded if they have the RGBA8 format
  15166. if (format !== RGBAFormat || type !== UnsignedByteType) {
  15167. console.warn('THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.');
  15168. }
  15169. }
  15170. } else {
  15171. console.error('THREE.WebGLTextures: Unsupported texture encoding:', encoding);
  15172. }
  15173. }
  15174. return image;
  15175. } //
  15176. this.allocateTextureUnit = allocateTextureUnit;
  15177. this.resetTextureUnits = resetTextureUnits;
  15178. this.setTexture2D = setTexture2D;
  15179. this.setTexture2DArray = setTexture2DArray;
  15180. this.setTexture3D = setTexture3D;
  15181. this.setTextureCube = setTextureCube;
  15182. this.rebindTextures = rebindTextures;
  15183. this.setupRenderTarget = setupRenderTarget;
  15184. this.updateRenderTargetMipmap = updateRenderTargetMipmap;
  15185. this.updateMultisampleRenderTarget = updateMultisampleRenderTarget;
  15186. this.setupDepthRenderbuffer = setupDepthRenderbuffer;
  15187. this.setupFrameBufferTexture = setupFrameBufferTexture;
  15188. this.useMultisampledRTT = useMultisampledRTT;
  15189. }
  15190. function WebGLUtils(gl, extensions, capabilities) {
  15191. const isWebGL2 = capabilities.isWebGL2;
  15192. function convert(p, encoding = null) {
  15193. let extension;
  15194. if (p === UnsignedByteType) return gl.UNSIGNED_BYTE;
  15195. if (p === UnsignedShort4444Type) return gl.UNSIGNED_SHORT_4_4_4_4;
  15196. if (p === UnsignedShort5551Type) return gl.UNSIGNED_SHORT_5_5_5_1;
  15197. if (p === ByteType) return gl.BYTE;
  15198. if (p === ShortType) return gl.SHORT;
  15199. if (p === UnsignedShortType) return gl.UNSIGNED_SHORT;
  15200. if (p === IntType) return gl.INT;
  15201. if (p === UnsignedIntType) return gl.UNSIGNED_INT;
  15202. if (p === FloatType) return gl.FLOAT;
  15203. if (p === HalfFloatType) {
  15204. if (isWebGL2) return gl.HALF_FLOAT;
  15205. extension = extensions.get('OES_texture_half_float');
  15206. if (extension !== null) {
  15207. return extension.HALF_FLOAT_OES;
  15208. } else {
  15209. return null;
  15210. }
  15211. }
  15212. if (p === AlphaFormat) return gl.ALPHA;
  15213. if (p === RGBAFormat) return gl.RGBA;
  15214. if (p === LuminanceFormat) return gl.LUMINANCE;
  15215. if (p === LuminanceAlphaFormat) return gl.LUMINANCE_ALPHA;
  15216. if (p === DepthFormat) return gl.DEPTH_COMPONENT;
  15217. if (p === DepthStencilFormat) return gl.DEPTH_STENCIL;
  15218. if (p === RedFormat) return gl.RED;
  15219. if (p === RGBFormat) {
  15220. console.warn('THREE.WebGLRenderer: THREE.RGBFormat has been removed. Use THREE.RGBAFormat instead. https://github.com/mrdoob/three.js/pull/23228');
  15221. return gl.RGBA;
  15222. } // WebGL 1 sRGB fallback
  15223. if (p === _SRGBAFormat) {
  15224. extension = extensions.get('EXT_sRGB');
  15225. if (extension !== null) {
  15226. return extension.SRGB_ALPHA_EXT;
  15227. } else {
  15228. return null;
  15229. }
  15230. } // WebGL2 formats.
  15231. if (p === RedIntegerFormat) return gl.RED_INTEGER;
  15232. if (p === RGFormat) return gl.RG;
  15233. if (p === RGIntegerFormat) return gl.RG_INTEGER;
  15234. if (p === RGBAIntegerFormat) return gl.RGBA_INTEGER; // S3TC
  15235. if (p === RGB_S3TC_DXT1_Format || p === RGBA_S3TC_DXT1_Format || p === RGBA_S3TC_DXT3_Format || p === RGBA_S3TC_DXT5_Format) {
  15236. if (encoding === sRGBEncoding) {
  15237. extension = extensions.get('WEBGL_compressed_texture_s3tc_srgb');
  15238. if (extension !== null) {
  15239. if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT;
  15240. if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  15241. if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  15242. if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  15243. } else {
  15244. return null;
  15245. }
  15246. } else {
  15247. extension = extensions.get('WEBGL_compressed_texture_s3tc');
  15248. if (extension !== null) {
  15249. if (p === RGB_S3TC_DXT1_Format) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT;
  15250. if (p === RGBA_S3TC_DXT1_Format) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT;
  15251. if (p === RGBA_S3TC_DXT3_Format) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT;
  15252. if (p === RGBA_S3TC_DXT5_Format) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT;
  15253. } else {
  15254. return null;
  15255. }
  15256. }
  15257. } // PVRTC
  15258. if (p === RGB_PVRTC_4BPPV1_Format || p === RGB_PVRTC_2BPPV1_Format || p === RGBA_PVRTC_4BPPV1_Format || p === RGBA_PVRTC_2BPPV1_Format) {
  15259. extension = extensions.get('WEBGL_compressed_texture_pvrtc');
  15260. if (extension !== null) {
  15261. if (p === RGB_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  15262. if (p === RGB_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  15263. if (p === RGBA_PVRTC_4BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  15264. if (p === RGBA_PVRTC_2BPPV1_Format) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  15265. } else {
  15266. return null;
  15267. }
  15268. } // ETC1
  15269. if (p === RGB_ETC1_Format) {
  15270. extension = extensions.get('WEBGL_compressed_texture_etc1');
  15271. if (extension !== null) {
  15272. return extension.COMPRESSED_RGB_ETC1_WEBGL;
  15273. } else {
  15274. return null;
  15275. }
  15276. } // ETC2
  15277. if (p === RGB_ETC2_Format || p === RGBA_ETC2_EAC_Format) {
  15278. extension = extensions.get('WEBGL_compressed_texture_etc');
  15279. if (extension !== null) {
  15280. if (p === RGB_ETC2_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2;
  15281. if (p === RGBA_ETC2_EAC_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC;
  15282. } else {
  15283. return null;
  15284. }
  15285. } // ASTC
  15286. if (p === RGBA_ASTC_4x4_Format || p === RGBA_ASTC_5x4_Format || p === RGBA_ASTC_5x5_Format || p === RGBA_ASTC_6x5_Format || p === RGBA_ASTC_6x6_Format || p === RGBA_ASTC_8x5_Format || p === RGBA_ASTC_8x6_Format || p === RGBA_ASTC_8x8_Format || p === RGBA_ASTC_10x5_Format || p === RGBA_ASTC_10x6_Format || p === RGBA_ASTC_10x8_Format || p === RGBA_ASTC_10x10_Format || p === RGBA_ASTC_12x10_Format || p === RGBA_ASTC_12x12_Format) {
  15287. extension = extensions.get('WEBGL_compressed_texture_astc');
  15288. if (extension !== null) {
  15289. if (p === RGBA_ASTC_4x4_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR;
  15290. if (p === RGBA_ASTC_5x4_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR;
  15291. if (p === RGBA_ASTC_5x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR;
  15292. if (p === RGBA_ASTC_6x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR;
  15293. if (p === RGBA_ASTC_6x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR;
  15294. if (p === RGBA_ASTC_8x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR;
  15295. if (p === RGBA_ASTC_8x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR;
  15296. if (p === RGBA_ASTC_8x8_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR;
  15297. if (p === RGBA_ASTC_10x5_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR;
  15298. if (p === RGBA_ASTC_10x6_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR;
  15299. if (p === RGBA_ASTC_10x8_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR;
  15300. if (p === RGBA_ASTC_10x10_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR;
  15301. if (p === RGBA_ASTC_12x10_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR;
  15302. if (p === RGBA_ASTC_12x12_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR;
  15303. } else {
  15304. return null;
  15305. }
  15306. } // BPTC
  15307. if (p === RGBA_BPTC_Format) {
  15308. extension = extensions.get('EXT_texture_compression_bptc');
  15309. if (extension !== null) {
  15310. if (p === RGBA_BPTC_Format) return encoding === sRGBEncoding ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT;
  15311. } else {
  15312. return null;
  15313. }
  15314. } //
  15315. if (p === UnsignedInt248Type) {
  15316. if (isWebGL2) return gl.UNSIGNED_INT_24_8;
  15317. extension = extensions.get('WEBGL_depth_texture');
  15318. if (extension !== null) {
  15319. return extension.UNSIGNED_INT_24_8_WEBGL;
  15320. } else {
  15321. return null;
  15322. }
  15323. } // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats)
  15324. return gl[p] !== undefined ? gl[p] : null;
  15325. }
  15326. return {
  15327. convert: convert
  15328. };
  15329. }
  15330. class ArrayCamera extends PerspectiveCamera {
  15331. constructor(array = []) {
  15332. super();
  15333. this.isArrayCamera = true;
  15334. this.cameras = array;
  15335. }
  15336. }
  15337. class Group extends Object3D {
  15338. constructor() {
  15339. super();
  15340. this.isGroup = true;
  15341. this.type = 'Group';
  15342. }
  15343. }
  15344. const _moveEvent = {
  15345. type: 'move'
  15346. };
  15347. class WebXRController {
  15348. constructor() {
  15349. this._targetRay = null;
  15350. this._grip = null;
  15351. this._hand = null;
  15352. }
  15353. getHandSpace() {
  15354. if (this._hand === null) {
  15355. this._hand = new Group();
  15356. this._hand.matrixAutoUpdate = false;
  15357. this._hand.visible = false;
  15358. this._hand.joints = {};
  15359. this._hand.inputState = {
  15360. pinching: false
  15361. };
  15362. }
  15363. return this._hand;
  15364. }
  15365. getTargetRaySpace() {
  15366. if (this._targetRay === null) {
  15367. this._targetRay = new Group();
  15368. this._targetRay.matrixAutoUpdate = false;
  15369. this._targetRay.visible = false;
  15370. this._targetRay.hasLinearVelocity = false;
  15371. this._targetRay.linearVelocity = new Vector3();
  15372. this._targetRay.hasAngularVelocity = false;
  15373. this._targetRay.angularVelocity = new Vector3();
  15374. }
  15375. return this._targetRay;
  15376. }
  15377. getGripSpace() {
  15378. if (this._grip === null) {
  15379. this._grip = new Group();
  15380. this._grip.matrixAutoUpdate = false;
  15381. this._grip.visible = false;
  15382. this._grip.hasLinearVelocity = false;
  15383. this._grip.linearVelocity = new Vector3();
  15384. this._grip.hasAngularVelocity = false;
  15385. this._grip.angularVelocity = new Vector3();
  15386. }
  15387. return this._grip;
  15388. }
  15389. dispatchEvent(event) {
  15390. if (this._targetRay !== null) {
  15391. this._targetRay.dispatchEvent(event);
  15392. }
  15393. if (this._grip !== null) {
  15394. this._grip.dispatchEvent(event);
  15395. }
  15396. if (this._hand !== null) {
  15397. this._hand.dispatchEvent(event);
  15398. }
  15399. return this;
  15400. }
  15401. disconnect(inputSource) {
  15402. this.dispatchEvent({
  15403. type: 'disconnected',
  15404. data: inputSource
  15405. });
  15406. if (this._targetRay !== null) {
  15407. this._targetRay.visible = false;
  15408. }
  15409. if (this._grip !== null) {
  15410. this._grip.visible = false;
  15411. }
  15412. if (this._hand !== null) {
  15413. this._hand.visible = false;
  15414. }
  15415. return this;
  15416. }
  15417. update(inputSource, frame, referenceSpace) {
  15418. let inputPose = null;
  15419. let gripPose = null;
  15420. let handPose = null;
  15421. const targetRay = this._targetRay;
  15422. const grip = this._grip;
  15423. const hand = this._hand;
  15424. if (inputSource && frame.session.visibilityState !== 'visible-blurred') {
  15425. if (hand && inputSource.hand) {
  15426. handPose = true;
  15427. for (const inputjoint of inputSource.hand.values()) {
  15428. // Update the joints groups with the XRJoint poses
  15429. const jointPose = frame.getJointPose(inputjoint, referenceSpace);
  15430. if (hand.joints[inputjoint.jointName] === undefined) {
  15431. // The transform of this joint will be updated with the joint pose on each frame
  15432. const joint = new Group();
  15433. joint.matrixAutoUpdate = false;
  15434. joint.visible = false;
  15435. hand.joints[inputjoint.jointName] = joint; // ??
  15436. hand.add(joint);
  15437. }
  15438. const joint = hand.joints[inputjoint.jointName];
  15439. if (jointPose !== null) {
  15440. joint.matrix.fromArray(jointPose.transform.matrix);
  15441. joint.matrix.decompose(joint.position, joint.rotation, joint.scale);
  15442. joint.jointRadius = jointPose.radius;
  15443. }
  15444. joint.visible = jointPose !== null;
  15445. } // Custom events
  15446. // Check pinchz
  15447. const indexTip = hand.joints['index-finger-tip'];
  15448. const thumbTip = hand.joints['thumb-tip'];
  15449. const distance = indexTip.position.distanceTo(thumbTip.position);
  15450. const distanceToPinch = 0.02;
  15451. const threshold = 0.005;
  15452. if (hand.inputState.pinching && distance > distanceToPinch + threshold) {
  15453. hand.inputState.pinching = false;
  15454. this.dispatchEvent({
  15455. type: 'pinchend',
  15456. handedness: inputSource.handedness,
  15457. target: this
  15458. });
  15459. } else if (!hand.inputState.pinching && distance <= distanceToPinch - threshold) {
  15460. hand.inputState.pinching = true;
  15461. this.dispatchEvent({
  15462. type: 'pinchstart',
  15463. handedness: inputSource.handedness,
  15464. target: this
  15465. });
  15466. }
  15467. } else {
  15468. if (grip !== null && inputSource.gripSpace) {
  15469. gripPose = frame.getPose(inputSource.gripSpace, referenceSpace);
  15470. if (gripPose !== null) {
  15471. grip.matrix.fromArray(gripPose.transform.matrix);
  15472. grip.matrix.decompose(grip.position, grip.rotation, grip.scale);
  15473. if (gripPose.linearVelocity) {
  15474. grip.hasLinearVelocity = true;
  15475. grip.linearVelocity.copy(gripPose.linearVelocity);
  15476. } else {
  15477. grip.hasLinearVelocity = false;
  15478. }
  15479. if (gripPose.angularVelocity) {
  15480. grip.hasAngularVelocity = true;
  15481. grip.angularVelocity.copy(gripPose.angularVelocity);
  15482. } else {
  15483. grip.hasAngularVelocity = false;
  15484. }
  15485. }
  15486. }
  15487. }
  15488. if (targetRay !== null) {
  15489. inputPose = frame.getPose(inputSource.targetRaySpace, referenceSpace); // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it
  15490. if (inputPose === null && gripPose !== null) {
  15491. inputPose = gripPose;
  15492. }
  15493. if (inputPose !== null) {
  15494. targetRay.matrix.fromArray(inputPose.transform.matrix);
  15495. targetRay.matrix.decompose(targetRay.position, targetRay.rotation, targetRay.scale);
  15496. if (inputPose.linearVelocity) {
  15497. targetRay.hasLinearVelocity = true;
  15498. targetRay.linearVelocity.copy(inputPose.linearVelocity);
  15499. } else {
  15500. targetRay.hasLinearVelocity = false;
  15501. }
  15502. if (inputPose.angularVelocity) {
  15503. targetRay.hasAngularVelocity = true;
  15504. targetRay.angularVelocity.copy(inputPose.angularVelocity);
  15505. } else {
  15506. targetRay.hasAngularVelocity = false;
  15507. }
  15508. this.dispatchEvent(_moveEvent);
  15509. }
  15510. }
  15511. }
  15512. if (targetRay !== null) {
  15513. targetRay.visible = inputPose !== null;
  15514. }
  15515. if (grip !== null) {
  15516. grip.visible = gripPose !== null;
  15517. }
  15518. if (hand !== null) {
  15519. hand.visible = handPose !== null;
  15520. }
  15521. return this;
  15522. }
  15523. }
  15524. class DepthTexture extends Texture {
  15525. constructor(width, height, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, format) {
  15526. format = format !== undefined ? format : DepthFormat;
  15527. if (format !== DepthFormat && format !== DepthStencilFormat) {
  15528. throw new Error('DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat');
  15529. }
  15530. if (type === undefined && format === DepthFormat) type = UnsignedIntType;
  15531. if (type === undefined && format === DepthStencilFormat) type = UnsignedInt248Type;
  15532. super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
  15533. this.isDepthTexture = true;
  15534. this.image = {
  15535. width: width,
  15536. height: height
  15537. };
  15538. this.magFilter = magFilter !== undefined ? magFilter : NearestFilter;
  15539. this.minFilter = minFilter !== undefined ? minFilter : NearestFilter;
  15540. this.flipY = false;
  15541. this.generateMipmaps = false;
  15542. }
  15543. }
  15544. class WebXRManager extends EventDispatcher {
  15545. constructor(renderer, gl) {
  15546. super();
  15547. const scope = this;
  15548. let session = null;
  15549. let framebufferScaleFactor = 1.0;
  15550. let referenceSpace = null;
  15551. let referenceSpaceType = 'local-floor';
  15552. let customReferenceSpace = null;
  15553. let pose = null;
  15554. let glBinding = null;
  15555. let glProjLayer = null;
  15556. let glBaseLayer = null;
  15557. let xrFrame = null;
  15558. const attributes = gl.getContextAttributes();
  15559. let initialRenderTarget = null;
  15560. let newRenderTarget = null;
  15561. const controllers = [];
  15562. const controllerInputSources = []; //
  15563. const cameraL = new PerspectiveCamera();
  15564. cameraL.layers.enable(1);
  15565. cameraL.viewport = new Vector4();
  15566. const cameraR = new PerspectiveCamera();
  15567. cameraR.layers.enable(2);
  15568. cameraR.viewport = new Vector4();
  15569. const cameras = [cameraL, cameraR];
  15570. const cameraVR = new ArrayCamera();
  15571. cameraVR.layers.enable(1);
  15572. cameraVR.layers.enable(2);
  15573. let _currentDepthNear = null;
  15574. let _currentDepthFar = null; //
  15575. this.cameraAutoUpdate = true;
  15576. this.enabled = false;
  15577. this.isPresenting = false;
  15578. this.getController = function (index) {
  15579. let controller = controllers[index];
  15580. if (controller === undefined) {
  15581. controller = new WebXRController();
  15582. controllers[index] = controller;
  15583. }
  15584. return controller.getTargetRaySpace();
  15585. };
  15586. this.getControllerGrip = function (index) {
  15587. let controller = controllers[index];
  15588. if (controller === undefined) {
  15589. controller = new WebXRController();
  15590. controllers[index] = controller;
  15591. }
  15592. return controller.getGripSpace();
  15593. };
  15594. this.getHand = function (index) {
  15595. let controller = controllers[index];
  15596. if (controller === undefined) {
  15597. controller = new WebXRController();
  15598. controllers[index] = controller;
  15599. }
  15600. return controller.getHandSpace();
  15601. }; //
  15602. function onSessionEvent(event) {
  15603. const controllerIndex = controllerInputSources.indexOf(event.inputSource);
  15604. if (controllerIndex === -1) {
  15605. return;
  15606. }
  15607. const controller = controllers[controllerIndex];
  15608. if (controller !== undefined) {
  15609. controller.dispatchEvent({
  15610. type: event.type,
  15611. data: event.inputSource
  15612. });
  15613. }
  15614. }
  15615. function onSessionEnd() {
  15616. session.removeEventListener('select', onSessionEvent);
  15617. session.removeEventListener('selectstart', onSessionEvent);
  15618. session.removeEventListener('selectend', onSessionEvent);
  15619. session.removeEventListener('squeeze', onSessionEvent);
  15620. session.removeEventListener('squeezestart', onSessionEvent);
  15621. session.removeEventListener('squeezeend', onSessionEvent);
  15622. session.removeEventListener('end', onSessionEnd);
  15623. session.removeEventListener('inputsourceschange', onInputSourcesChange);
  15624. for (let i = 0; i < controllers.length; i++) {
  15625. const inputSource = controllerInputSources[i];
  15626. if (inputSource === null) continue;
  15627. controllerInputSources[i] = null;
  15628. controllers[i].disconnect(inputSource);
  15629. }
  15630. _currentDepthNear = null;
  15631. _currentDepthFar = null; // restore framebuffer/rendering state
  15632. renderer.setRenderTarget(initialRenderTarget);
  15633. glBaseLayer = null;
  15634. glProjLayer = null;
  15635. glBinding = null;
  15636. session = null;
  15637. newRenderTarget = null; //
  15638. animation.stop();
  15639. scope.isPresenting = false;
  15640. scope.dispatchEvent({
  15641. type: 'sessionend'
  15642. });
  15643. }
  15644. this.setFramebufferScaleFactor = function (value) {
  15645. framebufferScaleFactor = value;
  15646. if (scope.isPresenting === true) {
  15647. console.warn('THREE.WebXRManager: Cannot change framebuffer scale while presenting.');
  15648. }
  15649. };
  15650. this.setReferenceSpaceType = function (value) {
  15651. referenceSpaceType = value;
  15652. if (scope.isPresenting === true) {
  15653. console.warn('THREE.WebXRManager: Cannot change reference space type while presenting.');
  15654. }
  15655. };
  15656. this.getReferenceSpace = function () {
  15657. return customReferenceSpace || referenceSpace;
  15658. };
  15659. this.setReferenceSpace = function (space) {
  15660. customReferenceSpace = space;
  15661. };
  15662. this.getBaseLayer = function () {
  15663. return glProjLayer !== null ? glProjLayer : glBaseLayer;
  15664. };
  15665. this.getBinding = function () {
  15666. return glBinding;
  15667. };
  15668. this.getFrame = function () {
  15669. return xrFrame;
  15670. };
  15671. this.getSession = function () {
  15672. return session;
  15673. };
  15674. this.setSession = async function (value) {
  15675. session = value;
  15676. if (session !== null) {
  15677. initialRenderTarget = renderer.getRenderTarget();
  15678. session.addEventListener('select', onSessionEvent);
  15679. session.addEventListener('selectstart', onSessionEvent);
  15680. session.addEventListener('selectend', onSessionEvent);
  15681. session.addEventListener('squeeze', onSessionEvent);
  15682. session.addEventListener('squeezestart', onSessionEvent);
  15683. session.addEventListener('squeezeend', onSessionEvent);
  15684. session.addEventListener('end', onSessionEnd);
  15685. session.addEventListener('inputsourceschange', onInputSourcesChange);
  15686. if (attributes.xrCompatible !== true) {
  15687. await gl.makeXRCompatible();
  15688. }
  15689. if (session.renderState.layers === undefined || renderer.capabilities.isWebGL2 === false) {
  15690. const layerInit = {
  15691. antialias: session.renderState.layers === undefined ? attributes.antialias : true,
  15692. alpha: attributes.alpha,
  15693. depth: attributes.depth,
  15694. stencil: attributes.stencil,
  15695. framebufferScaleFactor: framebufferScaleFactor
  15696. };
  15697. glBaseLayer = new XRWebGLLayer(session, gl, layerInit);
  15698. session.updateRenderState({
  15699. baseLayer: glBaseLayer
  15700. });
  15701. newRenderTarget = new WebGLRenderTarget(glBaseLayer.framebufferWidth, glBaseLayer.framebufferHeight, {
  15702. format: RGBAFormat,
  15703. type: UnsignedByteType,
  15704. encoding: renderer.outputEncoding
  15705. });
  15706. } else {
  15707. let depthFormat = null;
  15708. let depthType = null;
  15709. let glDepthFormat = null;
  15710. if (attributes.depth) {
  15711. glDepthFormat = attributes.stencil ? gl.DEPTH24_STENCIL8 : gl.DEPTH_COMPONENT24;
  15712. depthFormat = attributes.stencil ? DepthStencilFormat : DepthFormat;
  15713. depthType = attributes.stencil ? UnsignedInt248Type : UnsignedIntType;
  15714. }
  15715. const projectionlayerInit = {
  15716. colorFormat: gl.RGBA8,
  15717. depthFormat: glDepthFormat,
  15718. scaleFactor: framebufferScaleFactor
  15719. };
  15720. glBinding = new XRWebGLBinding(session, gl);
  15721. glProjLayer = glBinding.createProjectionLayer(projectionlayerInit);
  15722. session.updateRenderState({
  15723. layers: [glProjLayer]
  15724. });
  15725. newRenderTarget = new WebGLRenderTarget(glProjLayer.textureWidth, glProjLayer.textureHeight, {
  15726. format: RGBAFormat,
  15727. type: UnsignedByteType,
  15728. depthTexture: new DepthTexture(glProjLayer.textureWidth, glProjLayer.textureHeight, depthType, undefined, undefined, undefined, undefined, undefined, undefined, depthFormat),
  15729. stencilBuffer: attributes.stencil,
  15730. encoding: renderer.outputEncoding,
  15731. samples: attributes.antialias ? 4 : 0
  15732. });
  15733. const renderTargetProperties = renderer.properties.get(newRenderTarget);
  15734. renderTargetProperties.__ignoreDepthValues = glProjLayer.ignoreDepthValues;
  15735. }
  15736. newRenderTarget.isXRRenderTarget = true; // TODO Remove this when possible, see #23278
  15737. // Set foveation to maximum.
  15738. this.setFoveation(1.0);
  15739. customReferenceSpace = null;
  15740. referenceSpace = await session.requestReferenceSpace(referenceSpaceType);
  15741. animation.setContext(session);
  15742. animation.start();
  15743. scope.isPresenting = true;
  15744. scope.dispatchEvent({
  15745. type: 'sessionstart'
  15746. });
  15747. }
  15748. };
  15749. function onInputSourcesChange(event) {
  15750. // Notify disconnected
  15751. for (let i = 0; i < event.removed.length; i++) {
  15752. const inputSource = event.removed[i];
  15753. const index = controllerInputSources.indexOf(inputSource);
  15754. if (index >= 0) {
  15755. controllerInputSources[index] = null;
  15756. controllers[index].dispatchEvent({
  15757. type: 'disconnected',
  15758. data: inputSource
  15759. });
  15760. }
  15761. } // Notify connected
  15762. for (let i = 0; i < event.added.length; i++) {
  15763. const inputSource = event.added[i];
  15764. let controllerIndex = controllerInputSources.indexOf(inputSource);
  15765. if (controllerIndex === -1) {
  15766. // Assign input source a controller that currently has no input source
  15767. for (let i = 0; i < controllers.length; i++) {
  15768. if (i >= controllerInputSources.length) {
  15769. controllerInputSources.push(inputSource);
  15770. controllerIndex = i;
  15771. break;
  15772. } else if (controllerInputSources[i] === null) {
  15773. controllerInputSources[i] = inputSource;
  15774. controllerIndex = i;
  15775. break;
  15776. }
  15777. } // If all controllers do currently receive input we ignore new ones
  15778. if (controllerIndex === -1) break;
  15779. }
  15780. const controller = controllers[controllerIndex];
  15781. if (controller) {
  15782. controller.dispatchEvent({
  15783. type: 'connected',
  15784. data: inputSource
  15785. });
  15786. }
  15787. }
  15788. } //
  15789. const cameraLPos = new Vector3();
  15790. const cameraRPos = new Vector3();
  15791. /**
  15792. * Assumes 2 cameras that are parallel and share an X-axis, and that
  15793. * the cameras' projection and world matrices have already been set.
  15794. * And that near and far planes are identical for both cameras.
  15795. * Visualization of this technique: https://computergraphics.stackexchange.com/a/4765
  15796. */
  15797. function setProjectionFromUnion(camera, cameraL, cameraR) {
  15798. cameraLPos.setFromMatrixPosition(cameraL.matrixWorld);
  15799. cameraRPos.setFromMatrixPosition(cameraR.matrixWorld);
  15800. const ipd = cameraLPos.distanceTo(cameraRPos);
  15801. const projL = cameraL.projectionMatrix.elements;
  15802. const projR = cameraR.projectionMatrix.elements; // VR systems will have identical far and near planes, and
  15803. // most likely identical top and bottom frustum extents.
  15804. // Use the left camera for these values.
  15805. const near = projL[14] / (projL[10] - 1);
  15806. const far = projL[14] / (projL[10] + 1);
  15807. const topFov = (projL[9] + 1) / projL[5];
  15808. const bottomFov = (projL[9] - 1) / projL[5];
  15809. const leftFov = (projL[8] - 1) / projL[0];
  15810. const rightFov = (projR[8] + 1) / projR[0];
  15811. const left = near * leftFov;
  15812. const right = near * rightFov; // Calculate the new camera's position offset from the
  15813. // left camera. xOffset should be roughly half `ipd`.
  15814. const zOffset = ipd / (-leftFov + rightFov);
  15815. const xOffset = zOffset * -leftFov; // TODO: Better way to apply this offset?
  15816. cameraL.matrixWorld.decompose(camera.position, camera.quaternion, camera.scale);
  15817. camera.translateX(xOffset);
  15818. camera.translateZ(zOffset);
  15819. camera.matrixWorld.compose(camera.position, camera.quaternion, camera.scale);
  15820. camera.matrixWorldInverse.copy(camera.matrixWorld).invert(); // Find the union of the frustum values of the cameras and scale
  15821. // the values so that the near plane's position does not change in world space,
  15822. // although must now be relative to the new union camera.
  15823. const near2 = near + zOffset;
  15824. const far2 = far + zOffset;
  15825. const left2 = left - xOffset;
  15826. const right2 = right + (ipd - xOffset);
  15827. const top2 = topFov * far / far2 * near2;
  15828. const bottom2 = bottomFov * far / far2 * near2;
  15829. camera.projectionMatrix.makePerspective(left2, right2, top2, bottom2, near2, far2);
  15830. }
  15831. function updateCamera(camera, parent) {
  15832. if (parent === null) {
  15833. camera.matrixWorld.copy(camera.matrix);
  15834. } else {
  15835. camera.matrixWorld.multiplyMatrices(parent.matrixWorld, camera.matrix);
  15836. }
  15837. camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
  15838. }
  15839. this.updateCamera = function (camera) {
  15840. if (session === null) return;
  15841. cameraVR.near = cameraR.near = cameraL.near = camera.near;
  15842. cameraVR.far = cameraR.far = cameraL.far = camera.far;
  15843. if (_currentDepthNear !== cameraVR.near || _currentDepthFar !== cameraVR.far) {
  15844. // Note that the new renderState won't apply until the next frame. See #18320
  15845. session.updateRenderState({
  15846. depthNear: cameraVR.near,
  15847. depthFar: cameraVR.far
  15848. });
  15849. _currentDepthNear = cameraVR.near;
  15850. _currentDepthFar = cameraVR.far;
  15851. }
  15852. const parent = camera.parent;
  15853. const cameras = cameraVR.cameras;
  15854. updateCamera(cameraVR, parent);
  15855. for (let i = 0; i < cameras.length; i++) {
  15856. updateCamera(cameras[i], parent);
  15857. }
  15858. cameraVR.matrixWorld.decompose(cameraVR.position, cameraVR.quaternion, cameraVR.scale); // update user camera and its children
  15859. camera.position.copy(cameraVR.position);
  15860. camera.quaternion.copy(cameraVR.quaternion);
  15861. camera.scale.copy(cameraVR.scale);
  15862. camera.matrix.copy(cameraVR.matrix);
  15863. camera.matrixWorld.copy(cameraVR.matrixWorld);
  15864. const children = camera.children;
  15865. for (let i = 0, l = children.length; i < l; i++) {
  15866. children[i].updateMatrixWorld(true);
  15867. } // update projection matrix for proper view frustum culling
  15868. if (cameras.length === 2) {
  15869. setProjectionFromUnion(cameraVR, cameraL, cameraR);
  15870. } else {
  15871. // assume single camera setup (AR)
  15872. cameraVR.projectionMatrix.copy(cameraL.projectionMatrix);
  15873. }
  15874. };
  15875. this.getCamera = function () {
  15876. return cameraVR;
  15877. };
  15878. this.getFoveation = function () {
  15879. if (glProjLayer !== null) {
  15880. return glProjLayer.fixedFoveation;
  15881. }
  15882. if (glBaseLayer !== null) {
  15883. return glBaseLayer.fixedFoveation;
  15884. }
  15885. return undefined;
  15886. };
  15887. this.setFoveation = function (foveation) {
  15888. // 0 = no foveation = full resolution
  15889. // 1 = maximum foveation = the edges render at lower resolution
  15890. if (glProjLayer !== null) {
  15891. glProjLayer.fixedFoveation = foveation;
  15892. }
  15893. if (glBaseLayer !== null && glBaseLayer.fixedFoveation !== undefined) {
  15894. glBaseLayer.fixedFoveation = foveation;
  15895. }
  15896. }; // Animation Loop
  15897. let onAnimationFrameCallback = null;
  15898. function onAnimationFrame(time, frame) {
  15899. pose = frame.getViewerPose(customReferenceSpace || referenceSpace);
  15900. xrFrame = frame;
  15901. if (pose !== null) {
  15902. const views = pose.views;
  15903. if (glBaseLayer !== null) {
  15904. renderer.setRenderTargetFramebuffer(newRenderTarget, glBaseLayer.framebuffer);
  15905. renderer.setRenderTarget(newRenderTarget);
  15906. }
  15907. let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list
  15908. if (views.length !== cameraVR.cameras.length) {
  15909. cameraVR.cameras.length = 0;
  15910. cameraVRNeedsUpdate = true;
  15911. }
  15912. for (let i = 0; i < views.length; i++) {
  15913. const view = views[i];
  15914. let viewport = null;
  15915. if (glBaseLayer !== null) {
  15916. viewport = glBaseLayer.getViewport(view);
  15917. } else {
  15918. const glSubImage = glBinding.getViewSubImage(glProjLayer, view);
  15919. viewport = glSubImage.viewport; // For side-by-side projection, we only produce a single texture for both eyes.
  15920. if (i === 0) {
  15921. renderer.setRenderTargetTextures(newRenderTarget, glSubImage.colorTexture, glProjLayer.ignoreDepthValues ? undefined : glSubImage.depthStencilTexture);
  15922. renderer.setRenderTarget(newRenderTarget);
  15923. }
  15924. }
  15925. let camera = cameras[i];
  15926. if (camera === undefined) {
  15927. camera = new PerspectiveCamera();
  15928. camera.layers.enable(i);
  15929. camera.viewport = new Vector4();
  15930. cameras[i] = camera;
  15931. }
  15932. camera.matrix.fromArray(view.transform.matrix);
  15933. camera.projectionMatrix.fromArray(view.projectionMatrix);
  15934. camera.viewport.set(viewport.x, viewport.y, viewport.width, viewport.height);
  15935. if (i === 0) {
  15936. cameraVR.matrix.copy(camera.matrix);
  15937. }
  15938. if (cameraVRNeedsUpdate === true) {
  15939. cameraVR.cameras.push(camera);
  15940. }
  15941. }
  15942. } //
  15943. for (let i = 0; i < controllers.length; i++) {
  15944. const inputSource = controllerInputSources[i];
  15945. const controller = controllers[i];
  15946. if (inputSource !== null && controller !== undefined) {
  15947. controller.update(inputSource, frame, customReferenceSpace || referenceSpace);
  15948. }
  15949. }
  15950. if (onAnimationFrameCallback) onAnimationFrameCallback(time, frame);
  15951. xrFrame = null;
  15952. }
  15953. const animation = new WebGLAnimation();
  15954. animation.setAnimationLoop(onAnimationFrame);
  15955. this.setAnimationLoop = function (callback) {
  15956. onAnimationFrameCallback = callback;
  15957. };
  15958. this.dispose = function () {};
  15959. }
  15960. }
  15961. function WebGLMaterials(renderer, properties) {
  15962. function refreshFogUniforms(uniforms, fog) {
  15963. uniforms.fogColor.value.copy(fog.color);
  15964. if (fog.isFog) {
  15965. uniforms.fogNear.value = fog.near;
  15966. uniforms.fogFar.value = fog.far;
  15967. } else if (fog.isFogExp2) {
  15968. uniforms.fogDensity.value = fog.density;
  15969. }
  15970. }
  15971. function refreshMaterialUniforms(uniforms, material, pixelRatio, height, transmissionRenderTarget) {
  15972. if (material.isMeshBasicMaterial) {
  15973. refreshUniformsCommon(uniforms, material);
  15974. } else if (material.isMeshLambertMaterial) {
  15975. refreshUniformsCommon(uniforms, material);
  15976. } else if (material.isMeshToonMaterial) {
  15977. refreshUniformsCommon(uniforms, material);
  15978. refreshUniformsToon(uniforms, material);
  15979. } else if (material.isMeshPhongMaterial) {
  15980. refreshUniformsCommon(uniforms, material);
  15981. refreshUniformsPhong(uniforms, material);
  15982. } else if (material.isMeshStandardMaterial) {
  15983. refreshUniformsCommon(uniforms, material);
  15984. refreshUniformsStandard(uniforms, material);
  15985. if (material.isMeshPhysicalMaterial) {
  15986. refreshUniformsPhysical(uniforms, material, transmissionRenderTarget);
  15987. }
  15988. } else if (material.isMeshMatcapMaterial) {
  15989. refreshUniformsCommon(uniforms, material);
  15990. refreshUniformsMatcap(uniforms, material);
  15991. } else if (material.isMeshDepthMaterial) {
  15992. refreshUniformsCommon(uniforms, material);
  15993. } else if (material.isMeshDistanceMaterial) {
  15994. refreshUniformsCommon(uniforms, material);
  15995. refreshUniformsDistance(uniforms, material);
  15996. } else if (material.isMeshNormalMaterial) {
  15997. refreshUniformsCommon(uniforms, material);
  15998. } else if (material.isLineBasicMaterial) {
  15999. refreshUniformsLine(uniforms, material);
  16000. if (material.isLineDashedMaterial) {
  16001. refreshUniformsDash(uniforms, material);
  16002. }
  16003. } else if (material.isPointsMaterial) {
  16004. refreshUniformsPoints(uniforms, material, pixelRatio, height);
  16005. } else if (material.isSpriteMaterial) {
  16006. refreshUniformsSprites(uniforms, material);
  16007. } else if (material.isShadowMaterial) {
  16008. uniforms.color.value.copy(material.color);
  16009. uniforms.opacity.value = material.opacity;
  16010. } else if (material.isShaderMaterial) {
  16011. material.uniformsNeedUpdate = false; // #15581
  16012. }
  16013. }
  16014. function refreshUniformsCommon(uniforms, material) {
  16015. uniforms.opacity.value = material.opacity;
  16016. if (material.color) {
  16017. uniforms.diffuse.value.copy(material.color);
  16018. }
  16019. if (material.emissive) {
  16020. uniforms.emissive.value.copy(material.emissive).multiplyScalar(material.emissiveIntensity);
  16021. }
  16022. if (material.map) {
  16023. uniforms.map.value = material.map;
  16024. }
  16025. if (material.alphaMap) {
  16026. uniforms.alphaMap.value = material.alphaMap;
  16027. }
  16028. if (material.bumpMap) {
  16029. uniforms.bumpMap.value = material.bumpMap;
  16030. uniforms.bumpScale.value = material.bumpScale;
  16031. if (material.side === BackSide) uniforms.bumpScale.value *= -1;
  16032. }
  16033. if (material.displacementMap) {
  16034. uniforms.displacementMap.value = material.displacementMap;
  16035. uniforms.displacementScale.value = material.displacementScale;
  16036. uniforms.displacementBias.value = material.displacementBias;
  16037. }
  16038. if (material.emissiveMap) {
  16039. uniforms.emissiveMap.value = material.emissiveMap;
  16040. }
  16041. if (material.normalMap) {
  16042. uniforms.normalMap.value = material.normalMap;
  16043. uniforms.normalScale.value.copy(material.normalScale);
  16044. if (material.side === BackSide) uniforms.normalScale.value.negate();
  16045. }
  16046. if (material.specularMap) {
  16047. uniforms.specularMap.value = material.specularMap;
  16048. }
  16049. if (material.alphaTest > 0) {
  16050. uniforms.alphaTest.value = material.alphaTest;
  16051. }
  16052. const envMap = properties.get(material).envMap;
  16053. if (envMap) {
  16054. uniforms.envMap.value = envMap;
  16055. uniforms.flipEnvMap.value = envMap.isCubeTexture && envMap.isRenderTargetTexture === false ? -1 : 1;
  16056. uniforms.reflectivity.value = material.reflectivity;
  16057. uniforms.ior.value = material.ior;
  16058. uniforms.refractionRatio.value = material.refractionRatio;
  16059. }
  16060. if (material.lightMap) {
  16061. uniforms.lightMap.value = material.lightMap; // artist-friendly light intensity scaling factor
  16062. const scaleFactor = renderer.physicallyCorrectLights !== true ? Math.PI : 1;
  16063. uniforms.lightMapIntensity.value = material.lightMapIntensity * scaleFactor;
  16064. }
  16065. if (material.aoMap) {
  16066. uniforms.aoMap.value = material.aoMap;
  16067. uniforms.aoMapIntensity.value = material.aoMapIntensity;
  16068. } // uv repeat and offset setting priorities
  16069. // 1. color map
  16070. // 2. specular map
  16071. // 3. displacementMap map
  16072. // 4. normal map
  16073. // 5. bump map
  16074. // 6. roughnessMap map
  16075. // 7. metalnessMap map
  16076. // 8. alphaMap map
  16077. // 9. emissiveMap map
  16078. // 10. clearcoat map
  16079. // 11. clearcoat normal map
  16080. // 12. clearcoat roughnessMap map
  16081. // 13. iridescence map
  16082. // 14. iridescence thickness map
  16083. // 15. specular intensity map
  16084. // 16. specular tint map
  16085. // 17. transmission map
  16086. // 18. thickness map
  16087. let uvScaleMap;
  16088. if (material.map) {
  16089. uvScaleMap = material.map;
  16090. } else if (material.specularMap) {
  16091. uvScaleMap = material.specularMap;
  16092. } else if (material.displacementMap) {
  16093. uvScaleMap = material.displacementMap;
  16094. } else if (material.normalMap) {
  16095. uvScaleMap = material.normalMap;
  16096. } else if (material.bumpMap) {
  16097. uvScaleMap = material.bumpMap;
  16098. } else if (material.roughnessMap) {
  16099. uvScaleMap = material.roughnessMap;
  16100. } else if (material.metalnessMap) {
  16101. uvScaleMap = material.metalnessMap;
  16102. } else if (material.alphaMap) {
  16103. uvScaleMap = material.alphaMap;
  16104. } else if (material.emissiveMap) {
  16105. uvScaleMap = material.emissiveMap;
  16106. } else if (material.clearcoatMap) {
  16107. uvScaleMap = material.clearcoatMap;
  16108. } else if (material.clearcoatNormalMap) {
  16109. uvScaleMap = material.clearcoatNormalMap;
  16110. } else if (material.clearcoatRoughnessMap) {
  16111. uvScaleMap = material.clearcoatRoughnessMap;
  16112. } else if (material.iridescenceMap) {
  16113. uvScaleMap = material.iridescenceMap;
  16114. } else if (material.iridescenceThicknessMap) {
  16115. uvScaleMap = material.iridescenceThicknessMap;
  16116. } else if (material.specularIntensityMap) {
  16117. uvScaleMap = material.specularIntensityMap;
  16118. } else if (material.specularColorMap) {
  16119. uvScaleMap = material.specularColorMap;
  16120. } else if (material.transmissionMap) {
  16121. uvScaleMap = material.transmissionMap;
  16122. } else if (material.thicknessMap) {
  16123. uvScaleMap = material.thicknessMap;
  16124. } else if (material.sheenColorMap) {
  16125. uvScaleMap = material.sheenColorMap;
  16126. } else if (material.sheenRoughnessMap) {
  16127. uvScaleMap = material.sheenRoughnessMap;
  16128. }
  16129. if (uvScaleMap !== undefined) {
  16130. // backwards compatibility
  16131. if (uvScaleMap.isWebGLRenderTarget) {
  16132. uvScaleMap = uvScaleMap.texture;
  16133. }
  16134. if (uvScaleMap.matrixAutoUpdate === true) {
  16135. uvScaleMap.updateMatrix();
  16136. }
  16137. uniforms.uvTransform.value.copy(uvScaleMap.matrix);
  16138. } // uv repeat and offset setting priorities for uv2
  16139. // 1. ao map
  16140. // 2. light map
  16141. let uv2ScaleMap;
  16142. if (material.aoMap) {
  16143. uv2ScaleMap = material.aoMap;
  16144. } else if (material.lightMap) {
  16145. uv2ScaleMap = material.lightMap;
  16146. }
  16147. if (uv2ScaleMap !== undefined) {
  16148. // backwards compatibility
  16149. if (uv2ScaleMap.isWebGLRenderTarget) {
  16150. uv2ScaleMap = uv2ScaleMap.texture;
  16151. }
  16152. if (uv2ScaleMap.matrixAutoUpdate === true) {
  16153. uv2ScaleMap.updateMatrix();
  16154. }
  16155. uniforms.uv2Transform.value.copy(uv2ScaleMap.matrix);
  16156. }
  16157. }
  16158. function refreshUniformsLine(uniforms, material) {
  16159. uniforms.diffuse.value.copy(material.color);
  16160. uniforms.opacity.value = material.opacity;
  16161. }
  16162. function refreshUniformsDash(uniforms, material) {
  16163. uniforms.dashSize.value = material.dashSize;
  16164. uniforms.totalSize.value = material.dashSize + material.gapSize;
  16165. uniforms.scale.value = material.scale;
  16166. }
  16167. function refreshUniformsPoints(uniforms, material, pixelRatio, height) {
  16168. uniforms.diffuse.value.copy(material.color);
  16169. uniforms.opacity.value = material.opacity;
  16170. uniforms.size.value = material.size * pixelRatio;
  16171. uniforms.scale.value = height * 0.5;
  16172. if (material.map) {
  16173. uniforms.map.value = material.map;
  16174. }
  16175. if (material.alphaMap) {
  16176. uniforms.alphaMap.value = material.alphaMap;
  16177. }
  16178. if (material.alphaTest > 0) {
  16179. uniforms.alphaTest.value = material.alphaTest;
  16180. } // uv repeat and offset setting priorities
  16181. // 1. color map
  16182. // 2. alpha map
  16183. let uvScaleMap;
  16184. if (material.map) {
  16185. uvScaleMap = material.map;
  16186. } else if (material.alphaMap) {
  16187. uvScaleMap = material.alphaMap;
  16188. }
  16189. if (uvScaleMap !== undefined) {
  16190. if (uvScaleMap.matrixAutoUpdate === true) {
  16191. uvScaleMap.updateMatrix();
  16192. }
  16193. uniforms.uvTransform.value.copy(uvScaleMap.matrix);
  16194. }
  16195. }
  16196. function refreshUniformsSprites(uniforms, material) {
  16197. uniforms.diffuse.value.copy(material.color);
  16198. uniforms.opacity.value = material.opacity;
  16199. uniforms.rotation.value = material.rotation;
  16200. if (material.map) {
  16201. uniforms.map.value = material.map;
  16202. }
  16203. if (material.alphaMap) {
  16204. uniforms.alphaMap.value = material.alphaMap;
  16205. }
  16206. if (material.alphaTest > 0) {
  16207. uniforms.alphaTest.value = material.alphaTest;
  16208. } // uv repeat and offset setting priorities
  16209. // 1. color map
  16210. // 2. alpha map
  16211. let uvScaleMap;
  16212. if (material.map) {
  16213. uvScaleMap = material.map;
  16214. } else if (material.alphaMap) {
  16215. uvScaleMap = material.alphaMap;
  16216. }
  16217. if (uvScaleMap !== undefined) {
  16218. if (uvScaleMap.matrixAutoUpdate === true) {
  16219. uvScaleMap.updateMatrix();
  16220. }
  16221. uniforms.uvTransform.value.copy(uvScaleMap.matrix);
  16222. }
  16223. }
  16224. function refreshUniformsPhong(uniforms, material) {
  16225. uniforms.specular.value.copy(material.specular);
  16226. uniforms.shininess.value = Math.max(material.shininess, 1e-4); // to prevent pow( 0.0, 0.0 )
  16227. }
  16228. function refreshUniformsToon(uniforms, material) {
  16229. if (material.gradientMap) {
  16230. uniforms.gradientMap.value = material.gradientMap;
  16231. }
  16232. }
  16233. function refreshUniformsStandard(uniforms, material) {
  16234. uniforms.roughness.value = material.roughness;
  16235. uniforms.metalness.value = material.metalness;
  16236. if (material.roughnessMap) {
  16237. uniforms.roughnessMap.value = material.roughnessMap;
  16238. }
  16239. if (material.metalnessMap) {
  16240. uniforms.metalnessMap.value = material.metalnessMap;
  16241. }
  16242. const envMap = properties.get(material).envMap;
  16243. if (envMap) {
  16244. //uniforms.envMap.value = material.envMap; // part of uniforms common
  16245. uniforms.envMapIntensity.value = material.envMapIntensity;
  16246. }
  16247. }
  16248. function refreshUniformsPhysical(uniforms, material, transmissionRenderTarget) {
  16249. uniforms.ior.value = material.ior; // also part of uniforms common
  16250. if (material.sheen > 0) {
  16251. uniforms.sheenColor.value.copy(material.sheenColor).multiplyScalar(material.sheen);
  16252. uniforms.sheenRoughness.value = material.sheenRoughness;
  16253. if (material.sheenColorMap) {
  16254. uniforms.sheenColorMap.value = material.sheenColorMap;
  16255. }
  16256. if (material.sheenRoughnessMap) {
  16257. uniforms.sheenRoughnessMap.value = material.sheenRoughnessMap;
  16258. }
  16259. }
  16260. if (material.clearcoat > 0) {
  16261. uniforms.clearcoat.value = material.clearcoat;
  16262. uniforms.clearcoatRoughness.value = material.clearcoatRoughness;
  16263. if (material.clearcoatMap) {
  16264. uniforms.clearcoatMap.value = material.clearcoatMap;
  16265. }
  16266. if (material.clearcoatRoughnessMap) {
  16267. uniforms.clearcoatRoughnessMap.value = material.clearcoatRoughnessMap;
  16268. }
  16269. if (material.clearcoatNormalMap) {
  16270. uniforms.clearcoatNormalScale.value.copy(material.clearcoatNormalScale);
  16271. uniforms.clearcoatNormalMap.value = material.clearcoatNormalMap;
  16272. if (material.side === BackSide) {
  16273. uniforms.clearcoatNormalScale.value.negate();
  16274. }
  16275. }
  16276. }
  16277. if (material.iridescence > 0) {
  16278. uniforms.iridescence.value = material.iridescence;
  16279. uniforms.iridescenceIOR.value = material.iridescenceIOR;
  16280. uniforms.iridescenceThicknessMinimum.value = material.iridescenceThicknessRange[0];
  16281. uniforms.iridescenceThicknessMaximum.value = material.iridescenceThicknessRange[1];
  16282. if (material.iridescenceMap) {
  16283. uniforms.iridescenceMap.value = material.iridescenceMap;
  16284. }
  16285. if (material.iridescenceThicknessMap) {
  16286. uniforms.iridescenceThicknessMap.value = material.iridescenceThicknessMap;
  16287. }
  16288. }
  16289. if (material.transmission > 0) {
  16290. uniforms.transmission.value = material.transmission;
  16291. uniforms.transmissionSamplerMap.value = transmissionRenderTarget.texture;
  16292. uniforms.transmissionSamplerSize.value.set(transmissionRenderTarget.width, transmissionRenderTarget.height);
  16293. if (material.transmissionMap) {
  16294. uniforms.transmissionMap.value = material.transmissionMap;
  16295. }
  16296. uniforms.thickness.value = material.thickness;
  16297. if (material.thicknessMap) {
  16298. uniforms.thicknessMap.value = material.thicknessMap;
  16299. }
  16300. uniforms.attenuationDistance.value = material.attenuationDistance;
  16301. uniforms.attenuationColor.value.copy(material.attenuationColor);
  16302. }
  16303. uniforms.specularIntensity.value = material.specularIntensity;
  16304. uniforms.specularColor.value.copy(material.specularColor);
  16305. if (material.specularIntensityMap) {
  16306. uniforms.specularIntensityMap.value = material.specularIntensityMap;
  16307. }
  16308. if (material.specularColorMap) {
  16309. uniforms.specularColorMap.value = material.specularColorMap;
  16310. }
  16311. }
  16312. function refreshUniformsMatcap(uniforms, material) {
  16313. if (material.matcap) {
  16314. uniforms.matcap.value = material.matcap;
  16315. }
  16316. }
  16317. function refreshUniformsDistance(uniforms, material) {
  16318. uniforms.referencePosition.value.copy(material.referencePosition);
  16319. uniforms.nearDistance.value = material.nearDistance;
  16320. uniforms.farDistance.value = material.farDistance;
  16321. }
  16322. return {
  16323. refreshFogUniforms: refreshFogUniforms,
  16324. refreshMaterialUniforms: refreshMaterialUniforms
  16325. };
  16326. }
  16327. function WebGLUniformsGroups(gl, info, capabilities, state) {
  16328. let buffers = {};
  16329. let updateList = {};
  16330. let allocatedBindingPoints = [];
  16331. const maxBindingPoints = capabilities.isWebGL2 ? gl.getParameter(gl.MAX_UNIFORM_BUFFER_BINDINGS) : 0; // binding points are global whereas block indices are per shader program
  16332. function bind(uniformsGroup, program) {
  16333. const webglProgram = program.program;
  16334. state.uniformBlockBinding(uniformsGroup, webglProgram);
  16335. }
  16336. function update(uniformsGroup, program) {
  16337. let buffer = buffers[uniformsGroup.id];
  16338. if (buffer === undefined) {
  16339. prepareUniformsGroup(uniformsGroup);
  16340. buffer = createBuffer(uniformsGroup);
  16341. buffers[uniformsGroup.id] = buffer;
  16342. uniformsGroup.addEventListener('dispose', onUniformsGroupsDispose);
  16343. } // ensure to update the binding points/block indices mapping for this program
  16344. const webglProgram = program.program;
  16345. state.updateUBOMapping(uniformsGroup, webglProgram); // update UBO once per frame
  16346. const frame = info.render.frame;
  16347. if (updateList[uniformsGroup.id] !== frame) {
  16348. updateBufferData(uniformsGroup);
  16349. updateList[uniformsGroup.id] = frame;
  16350. }
  16351. }
  16352. function createBuffer(uniformsGroup) {
  16353. // the setup of an UBO is independent of a particular shader program but global
  16354. const bindingPointIndex = allocateBindingPointIndex();
  16355. uniformsGroup.__bindingPointIndex = bindingPointIndex;
  16356. const buffer = gl.createBuffer();
  16357. const size = uniformsGroup.__size;
  16358. const usage = uniformsGroup.usage;
  16359. gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
  16360. gl.bufferData(gl.UNIFORM_BUFFER, size, usage);
  16361. gl.bindBuffer(gl.UNIFORM_BUFFER, null);
  16362. gl.bindBufferBase(gl.UNIFORM_BUFFER, bindingPointIndex, buffer);
  16363. return buffer;
  16364. }
  16365. function allocateBindingPointIndex() {
  16366. for (let i = 0; i < maxBindingPoints; i++) {
  16367. if (allocatedBindingPoints.indexOf(i) === -1) {
  16368. allocatedBindingPoints.push(i);
  16369. return i;
  16370. }
  16371. }
  16372. console.error('THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.');
  16373. return 0;
  16374. }
  16375. function updateBufferData(uniformsGroup) {
  16376. const buffer = buffers[uniformsGroup.id];
  16377. const uniforms = uniformsGroup.uniforms;
  16378. const cache = uniformsGroup.__cache;
  16379. gl.bindBuffer(gl.UNIFORM_BUFFER, buffer);
  16380. for (let i = 0, il = uniforms.length; i < il; i++) {
  16381. const uniform = uniforms[i]; // partly update the buffer if necessary
  16382. if (hasUniformChanged(uniform, i, cache) === true) {
  16383. const value = uniform.value;
  16384. const offset = uniform.__offset;
  16385. if (typeof value === 'number') {
  16386. uniform.__data[0] = value;
  16387. gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data);
  16388. } else {
  16389. if (uniform.value.isMatrix3) {
  16390. // manually converting 3x3 to 3x4
  16391. uniform.__data[0] = uniform.value.elements[0];
  16392. uniform.__data[1] = uniform.value.elements[1];
  16393. uniform.__data[2] = uniform.value.elements[2];
  16394. uniform.__data[3] = uniform.value.elements[0];
  16395. uniform.__data[4] = uniform.value.elements[3];
  16396. uniform.__data[5] = uniform.value.elements[4];
  16397. uniform.__data[6] = uniform.value.elements[5];
  16398. uniform.__data[7] = uniform.value.elements[0];
  16399. uniform.__data[8] = uniform.value.elements[6];
  16400. uniform.__data[9] = uniform.value.elements[7];
  16401. uniform.__data[10] = uniform.value.elements[8];
  16402. uniform.__data[11] = uniform.value.elements[0];
  16403. } else {
  16404. value.toArray(uniform.__data);
  16405. }
  16406. gl.bufferSubData(gl.UNIFORM_BUFFER, offset, uniform.__data);
  16407. }
  16408. }
  16409. }
  16410. gl.bindBuffer(gl.UNIFORM_BUFFER, null);
  16411. }
  16412. function hasUniformChanged(uniform, index, cache) {
  16413. const value = uniform.value;
  16414. if (cache[index] === undefined) {
  16415. // cache entry does not exist so far
  16416. if (typeof value === 'number') {
  16417. cache[index] = value;
  16418. } else {
  16419. cache[index] = value.clone();
  16420. }
  16421. return true;
  16422. } else {
  16423. // compare current value with cached entry
  16424. if (typeof value === 'number') {
  16425. if (cache[index] !== value) {
  16426. cache[index] = value;
  16427. return true;
  16428. }
  16429. } else {
  16430. const cachedObject = cache[index];
  16431. if (cachedObject.equals(value) === false) {
  16432. cachedObject.copy(value);
  16433. return true;
  16434. }
  16435. }
  16436. }
  16437. return false;
  16438. }
  16439. function prepareUniformsGroup(uniformsGroup) {
  16440. // determine total buffer size according to the STD140 layout
  16441. // Hint: STD140 is the only supported layout in WebGL 2
  16442. const uniforms = uniformsGroup.uniforms;
  16443. let offset = 0; // global buffer offset in bytes
  16444. const chunkSize = 16; // size of a chunk in bytes
  16445. let chunkOffset = 0; // offset within a single chunk in bytes
  16446. for (let i = 0, l = uniforms.length; i < l; i++) {
  16447. const uniform = uniforms[i];
  16448. const info = getUniformSize(uniform); // the following two properties will be used for partial buffer updates
  16449. uniform.__data = new Float32Array(info.storage / Float32Array.BYTES_PER_ELEMENT);
  16450. uniform.__offset = offset; //
  16451. if (i > 0) {
  16452. chunkOffset = offset % chunkSize;
  16453. const remainingSizeInChunk = chunkSize - chunkOffset; // check for chunk overflow
  16454. if (chunkOffset !== 0 && remainingSizeInChunk - info.boundary < 0) {
  16455. // add padding and adjust offset
  16456. offset += chunkSize - chunkOffset;
  16457. uniform.__offset = offset;
  16458. }
  16459. }
  16460. offset += info.storage;
  16461. } // ensure correct final padding
  16462. chunkOffset = offset % chunkSize;
  16463. if (chunkOffset > 0) offset += chunkSize - chunkOffset; //
  16464. uniformsGroup.__size = offset;
  16465. uniformsGroup.__cache = {};
  16466. return this;
  16467. }
  16468. function getUniformSize(uniform) {
  16469. const value = uniform.value;
  16470. const info = {
  16471. boundary: 0,
  16472. // bytes
  16473. storage: 0 // bytes
  16474. }; // determine sizes according to STD140
  16475. if (typeof value === 'number') {
  16476. // float/int
  16477. info.boundary = 4;
  16478. info.storage = 4;
  16479. } else if (value.isVector2) {
  16480. // vec2
  16481. info.boundary = 8;
  16482. info.storage = 8;
  16483. } else if (value.isVector3 || value.isColor) {
  16484. // vec3
  16485. info.boundary = 16;
  16486. info.storage = 12; // evil: vec3 must start on a 16-byte boundary but it only consumes 12 bytes
  16487. } else if (value.isVector4) {
  16488. // vec4
  16489. info.boundary = 16;
  16490. info.storage = 16;
  16491. } else if (value.isMatrix3) {
  16492. // mat3 (in STD140 a 3x3 matrix is represented as 3x4)
  16493. info.boundary = 48;
  16494. info.storage = 48;
  16495. } else if (value.isMatrix4) {
  16496. // mat4
  16497. info.boundary = 64;
  16498. info.storage = 64;
  16499. } else if (value.isTexture) {
  16500. console.warn('THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.');
  16501. } else {
  16502. console.warn('THREE.WebGLRenderer: Unsupported uniform value type.', value);
  16503. }
  16504. return info;
  16505. }
  16506. function onUniformsGroupsDispose(event) {
  16507. const uniformsGroup = event.target;
  16508. uniformsGroup.removeEventListener('dispose', onUniformsGroupsDispose);
  16509. const index = allocatedBindingPoints.indexOf(uniformsGroup.__bindingPointIndex);
  16510. allocatedBindingPoints.splice(index, 1);
  16511. gl.deleteBuffer(buffers[uniformsGroup.id]);
  16512. delete buffers[uniformsGroup.id];
  16513. delete updateList[uniformsGroup.id];
  16514. }
  16515. function dispose() {
  16516. for (const id in buffers) {
  16517. gl.deleteBuffer(buffers[id]);
  16518. }
  16519. allocatedBindingPoints = [];
  16520. buffers = {};
  16521. updateList = {};
  16522. }
  16523. return {
  16524. bind: bind,
  16525. update: update,
  16526. dispose: dispose
  16527. };
  16528. }
  16529. function createCanvasElement() {
  16530. const canvas = createElementNS('canvas');
  16531. canvas.style.display = 'block';
  16532. return canvas;
  16533. }
  16534. function WebGLRenderer(parameters = {}) {
  16535. this.isWebGLRenderer = true;
  16536. const _canvas = parameters.canvas !== undefined ? parameters.canvas : createCanvasElement(),
  16537. _context = parameters.context !== undefined ? parameters.context : null,
  16538. _depth = parameters.depth !== undefined ? parameters.depth : true,
  16539. _stencil = parameters.stencil !== undefined ? parameters.stencil : true,
  16540. _antialias = parameters.antialias !== undefined ? parameters.antialias : false,
  16541. _premultipliedAlpha = parameters.premultipliedAlpha !== undefined ? parameters.premultipliedAlpha : true,
  16542. _preserveDrawingBuffer = parameters.preserveDrawingBuffer !== undefined ? parameters.preserveDrawingBuffer : false,
  16543. _powerPreference = parameters.powerPreference !== undefined ? parameters.powerPreference : 'default',
  16544. _failIfMajorPerformanceCaveat = parameters.failIfMajorPerformanceCaveat !== undefined ? parameters.failIfMajorPerformanceCaveat : false;
  16545. let _alpha;
  16546. if (_context !== null) {
  16547. _alpha = _context.getContextAttributes().alpha;
  16548. } else {
  16549. _alpha = parameters.alpha !== undefined ? parameters.alpha : false;
  16550. }
  16551. let currentRenderList = null;
  16552. let currentRenderState = null; // render() can be called from within a callback triggered by another render.
  16553. // We track this so that the nested render call gets its list and state isolated from the parent render call.
  16554. const renderListStack = [];
  16555. const renderStateStack = []; // public properties
  16556. this.domElement = _canvas; // Debug configuration container
  16557. this.debug = {
  16558. /**
  16559. * Enables error checking and reporting when shader programs are being compiled
  16560. * @type {boolean}
  16561. */
  16562. checkShaderErrors: true
  16563. }; // clearing
  16564. this.autoClear = true;
  16565. this.autoClearColor = true;
  16566. this.autoClearDepth = true;
  16567. this.autoClearStencil = true; // scene graph
  16568. this.sortObjects = true; // user-defined clipping
  16569. this.clippingPlanes = [];
  16570. this.localClippingEnabled = false; // physically based shading
  16571. this.outputEncoding = LinearEncoding; // physical lights
  16572. this.physicallyCorrectLights = false; // tone mapping
  16573. this.toneMapping = NoToneMapping;
  16574. this.toneMappingExposure = 1.0; //
  16575. Object.defineProperties(this, {
  16576. // @deprecated since r136, 0e21088102b4de7e0a0a33140620b7a3424b9e6d
  16577. gammaFactor: {
  16578. get: function () {
  16579. console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.');
  16580. return 2;
  16581. },
  16582. set: function () {
  16583. console.warn('THREE.WebGLRenderer: .gammaFactor has been removed.');
  16584. }
  16585. }
  16586. }); // internal properties
  16587. const _this = this;
  16588. let _isContextLost = false; // internal state cache
  16589. let _currentActiveCubeFace = 0;
  16590. let _currentActiveMipmapLevel = 0;
  16591. let _currentRenderTarget = null;
  16592. let _currentMaterialId = -1;
  16593. let _currentCamera = null;
  16594. const _currentViewport = new Vector4();
  16595. const _currentScissor = new Vector4();
  16596. let _currentScissorTest = null; //
  16597. let _width = _canvas.width;
  16598. let _height = _canvas.height;
  16599. let _pixelRatio = 1;
  16600. let _opaqueSort = null;
  16601. let _transparentSort = null;
  16602. const _viewport = new Vector4(0, 0, _width, _height);
  16603. const _scissor = new Vector4(0, 0, _width, _height);
  16604. let _scissorTest = false; // frustum
  16605. const _frustum = new Frustum(); // clipping
  16606. let _clippingEnabled = false;
  16607. let _localClippingEnabled = false; // transmission
  16608. let _transmissionRenderTarget = null; // camera matrices cache
  16609. const _projScreenMatrix = new Matrix4();
  16610. const _vector2 = new Vector2();
  16611. const _vector3 = new Vector3();
  16612. const _emptyScene = {
  16613. background: null,
  16614. fog: null,
  16615. environment: null,
  16616. overrideMaterial: null,
  16617. isScene: true
  16618. };
  16619. function getTargetPixelRatio() {
  16620. return _currentRenderTarget === null ? _pixelRatio : 1;
  16621. } // initialize
  16622. let _gl = _context;
  16623. function getContext(contextNames, contextAttributes) {
  16624. for (let i = 0; i < contextNames.length; i++) {
  16625. const contextName = contextNames[i];
  16626. const context = _canvas.getContext(contextName, contextAttributes);
  16627. if (context !== null) return context;
  16628. }
  16629. return null;
  16630. }
  16631. try {
  16632. const contextAttributes = {
  16633. alpha: true,
  16634. depth: _depth,
  16635. stencil: _stencil,
  16636. antialias: _antialias,
  16637. premultipliedAlpha: _premultipliedAlpha,
  16638. preserveDrawingBuffer: _preserveDrawingBuffer,
  16639. powerPreference: _powerPreference,
  16640. failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat
  16641. }; // OffscreenCanvas does not have setAttribute, see #22811
  16642. if ('setAttribute' in _canvas) _canvas.setAttribute('data-engine', `three.js r${REVISION}`); // event listeners must be registered before WebGL context is created, see #12753
  16643. _canvas.addEventListener('webglcontextlost', onContextLost, false);
  16644. _canvas.addEventListener('webglcontextrestored', onContextRestore, false);
  16645. _canvas.addEventListener('webglcontextcreationerror', onContextCreationError, false);
  16646. if (_gl === null) {
  16647. const contextNames = ['webgl2', 'webgl', 'experimental-webgl'];
  16648. if (_this.isWebGL1Renderer === true) {
  16649. contextNames.shift();
  16650. }
  16651. _gl = getContext(contextNames, contextAttributes);
  16652. if (_gl === null) {
  16653. if (getContext(contextNames)) {
  16654. throw new Error('Error creating WebGL context with your selected attributes.');
  16655. } else {
  16656. throw new Error('Error creating WebGL context.');
  16657. }
  16658. }
  16659. } // Some experimental-webgl implementations do not have getShaderPrecisionFormat
  16660. if (_gl.getShaderPrecisionFormat === undefined) {
  16661. _gl.getShaderPrecisionFormat = function () {
  16662. return {
  16663. 'rangeMin': 1,
  16664. 'rangeMax': 1,
  16665. 'precision': 1
  16666. };
  16667. };
  16668. }
  16669. } catch (error) {
  16670. console.error('THREE.WebGLRenderer: ' + error.message);
  16671. throw error;
  16672. }
  16673. let extensions, capabilities, state, info;
  16674. let properties, textures, cubemaps, cubeuvmaps, attributes, geometries, objects;
  16675. let programCache, materials, renderLists, renderStates, clipping, shadowMap;
  16676. let background, morphtargets, bufferRenderer, indexedBufferRenderer;
  16677. let utils, bindingStates, uniformsGroups;
  16678. function initGLContext() {
  16679. extensions = new WebGLExtensions(_gl);
  16680. capabilities = new WebGLCapabilities(_gl, extensions, parameters);
  16681. extensions.init(capabilities);
  16682. utils = new WebGLUtils(_gl, extensions, capabilities);
  16683. state = new WebGLState(_gl, extensions, capabilities);
  16684. info = new WebGLInfo(_gl);
  16685. properties = new WebGLProperties();
  16686. textures = new WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info);
  16687. cubemaps = new WebGLCubeMaps(_this);
  16688. cubeuvmaps = new WebGLCubeUVMaps(_this);
  16689. attributes = new WebGLAttributes(_gl, capabilities);
  16690. bindingStates = new WebGLBindingStates(_gl, extensions, attributes, capabilities);
  16691. geometries = new WebGLGeometries(_gl, attributes, info, bindingStates);
  16692. objects = new WebGLObjects(_gl, geometries, attributes, info);
  16693. morphtargets = new WebGLMorphtargets(_gl, capabilities, textures);
  16694. clipping = new WebGLClipping(properties);
  16695. programCache = new WebGLPrograms(_this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping);
  16696. materials = new WebGLMaterials(_this, properties);
  16697. renderLists = new WebGLRenderLists();
  16698. renderStates = new WebGLRenderStates(extensions, capabilities);
  16699. background = new WebGLBackground(_this, cubemaps, state, objects, _alpha, _premultipliedAlpha);
  16700. shadowMap = new WebGLShadowMap(_this, objects, capabilities);
  16701. uniformsGroups = new WebGLUniformsGroups(_gl, info, capabilities, state);
  16702. bufferRenderer = new WebGLBufferRenderer(_gl, extensions, info, capabilities);
  16703. indexedBufferRenderer = new WebGLIndexedBufferRenderer(_gl, extensions, info, capabilities);
  16704. info.programs = programCache.programs;
  16705. _this.capabilities = capabilities;
  16706. _this.extensions = extensions;
  16707. _this.properties = properties;
  16708. _this.renderLists = renderLists;
  16709. _this.shadowMap = shadowMap;
  16710. _this.state = state;
  16711. _this.info = info;
  16712. }
  16713. initGLContext(); // xr
  16714. const xr = new WebXRManager(_this, _gl);
  16715. this.xr = xr; // API
  16716. this.getContext = function () {
  16717. return _gl;
  16718. };
  16719. this.getContextAttributes = function () {
  16720. return _gl.getContextAttributes();
  16721. };
  16722. this.forceContextLoss = function () {
  16723. const extension = extensions.get('WEBGL_lose_context');
  16724. if (extension) extension.loseContext();
  16725. };
  16726. this.forceContextRestore = function () {
  16727. const extension = extensions.get('WEBGL_lose_context');
  16728. if (extension) extension.restoreContext();
  16729. };
  16730. this.getPixelRatio = function () {
  16731. return _pixelRatio;
  16732. };
  16733. this.setPixelRatio = function (value) {
  16734. if (value === undefined) return;
  16735. _pixelRatio = value;
  16736. this.setSize(_width, _height, false);
  16737. };
  16738. this.getSize = function (target) {
  16739. return target.set(_width, _height);
  16740. };
  16741. this.setSize = function (width, height, updateStyle) {
  16742. if (xr.isPresenting) {
  16743. console.warn('THREE.WebGLRenderer: Can\'t change size while VR device is presenting.');
  16744. return;
  16745. }
  16746. _width = width;
  16747. _height = height;
  16748. _canvas.width = Math.floor(width * _pixelRatio);
  16749. _canvas.height = Math.floor(height * _pixelRatio);
  16750. if (updateStyle !== false) {
  16751. _canvas.style.width = width + 'px';
  16752. _canvas.style.height = height + 'px';
  16753. }
  16754. this.setViewport(0, 0, width, height);
  16755. };
  16756. this.getDrawingBufferSize = function (target) {
  16757. return target.set(_width * _pixelRatio, _height * _pixelRatio).floor();
  16758. };
  16759. this.setDrawingBufferSize = function (width, height, pixelRatio) {
  16760. _width = width;
  16761. _height = height;
  16762. _pixelRatio = pixelRatio;
  16763. _canvas.width = Math.floor(width * pixelRatio);
  16764. _canvas.height = Math.floor(height * pixelRatio);
  16765. this.setViewport(0, 0, width, height);
  16766. };
  16767. this.getCurrentViewport = function (target) {
  16768. return target.copy(_currentViewport);
  16769. };
  16770. this.getViewport = function (target) {
  16771. return target.copy(_viewport);
  16772. };
  16773. this.setViewport = function (x, y, width, height) {
  16774. if (x.isVector4) {
  16775. _viewport.set(x.x, x.y, x.z, x.w);
  16776. } else {
  16777. _viewport.set(x, y, width, height);
  16778. }
  16779. state.viewport(_currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor());
  16780. };
  16781. this.getScissor = function (target) {
  16782. return target.copy(_scissor);
  16783. };
  16784. this.setScissor = function (x, y, width, height) {
  16785. if (x.isVector4) {
  16786. _scissor.set(x.x, x.y, x.z, x.w);
  16787. } else {
  16788. _scissor.set(x, y, width, height);
  16789. }
  16790. state.scissor(_currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor());
  16791. };
  16792. this.getScissorTest = function () {
  16793. return _scissorTest;
  16794. };
  16795. this.setScissorTest = function (boolean) {
  16796. state.setScissorTest(_scissorTest = boolean);
  16797. };
  16798. this.setOpaqueSort = function (method) {
  16799. _opaqueSort = method;
  16800. };
  16801. this.setTransparentSort = function (method) {
  16802. _transparentSort = method;
  16803. }; // Clearing
  16804. this.getClearColor = function (target) {
  16805. return target.copy(background.getClearColor());
  16806. };
  16807. this.setClearColor = function () {
  16808. background.setClearColor.apply(background, arguments);
  16809. };
  16810. this.getClearAlpha = function () {
  16811. return background.getClearAlpha();
  16812. };
  16813. this.setClearAlpha = function () {
  16814. background.setClearAlpha.apply(background, arguments);
  16815. };
  16816. this.clear = function (color = true, depth = true, stencil = true) {
  16817. let bits = 0;
  16818. if (color) bits |= _gl.COLOR_BUFFER_BIT;
  16819. if (depth) bits |= _gl.DEPTH_BUFFER_BIT;
  16820. if (stencil) bits |= _gl.STENCIL_BUFFER_BIT;
  16821. _gl.clear(bits);
  16822. };
  16823. this.clearColor = function () {
  16824. this.clear(true, false, false);
  16825. };
  16826. this.clearDepth = function () {
  16827. this.clear(false, true, false);
  16828. };
  16829. this.clearStencil = function () {
  16830. this.clear(false, false, true);
  16831. }; //
  16832. this.dispose = function () {
  16833. _canvas.removeEventListener('webglcontextlost', onContextLost, false);
  16834. _canvas.removeEventListener('webglcontextrestored', onContextRestore, false);
  16835. _canvas.removeEventListener('webglcontextcreationerror', onContextCreationError, false);
  16836. renderLists.dispose();
  16837. renderStates.dispose();
  16838. properties.dispose();
  16839. cubemaps.dispose();
  16840. cubeuvmaps.dispose();
  16841. objects.dispose();
  16842. bindingStates.dispose();
  16843. uniformsGroups.dispose();
  16844. programCache.dispose();
  16845. xr.dispose();
  16846. xr.removeEventListener('sessionstart', onXRSessionStart);
  16847. xr.removeEventListener('sessionend', onXRSessionEnd);
  16848. if (_transmissionRenderTarget) {
  16849. _transmissionRenderTarget.dispose();
  16850. _transmissionRenderTarget = null;
  16851. }
  16852. animation.stop();
  16853. }; // Events
  16854. function onContextLost(event) {
  16855. event.preventDefault();
  16856. console.log('THREE.WebGLRenderer: Context Lost.');
  16857. _isContextLost = true;
  16858. }
  16859. function
  16860. /* event */
  16861. onContextRestore() {
  16862. console.log('THREE.WebGLRenderer: Context Restored.');
  16863. _isContextLost = false;
  16864. const infoAutoReset = info.autoReset;
  16865. const shadowMapEnabled = shadowMap.enabled;
  16866. const shadowMapAutoUpdate = shadowMap.autoUpdate;
  16867. const shadowMapNeedsUpdate = shadowMap.needsUpdate;
  16868. const shadowMapType = shadowMap.type;
  16869. initGLContext();
  16870. info.autoReset = infoAutoReset;
  16871. shadowMap.enabled = shadowMapEnabled;
  16872. shadowMap.autoUpdate = shadowMapAutoUpdate;
  16873. shadowMap.needsUpdate = shadowMapNeedsUpdate;
  16874. shadowMap.type = shadowMapType;
  16875. }
  16876. function onContextCreationError(event) {
  16877. console.error('THREE.WebGLRenderer: A WebGL context could not be created. Reason: ', event.statusMessage);
  16878. }
  16879. function onMaterialDispose(event) {
  16880. const material = event.target;
  16881. material.removeEventListener('dispose', onMaterialDispose);
  16882. deallocateMaterial(material);
  16883. } // Buffer deallocation
  16884. function deallocateMaterial(material) {
  16885. releaseMaterialProgramReferences(material);
  16886. properties.remove(material);
  16887. }
  16888. function releaseMaterialProgramReferences(material) {
  16889. const programs = properties.get(material).programs;
  16890. if (programs !== undefined) {
  16891. programs.forEach(function (program) {
  16892. programCache.releaseProgram(program);
  16893. });
  16894. if (material.isShaderMaterial) {
  16895. programCache.releaseShaderCache(material);
  16896. }
  16897. }
  16898. } // Buffer rendering
  16899. this.renderBufferDirect = function (camera, scene, geometry, material, object, group) {
  16900. if (scene === null) scene = _emptyScene; // renderBufferDirect second parameter used to be fog (could be null)
  16901. const frontFaceCW = object.isMesh && object.matrixWorld.determinant() < 0;
  16902. const program = setProgram(camera, scene, geometry, material, object);
  16903. state.setMaterial(material, frontFaceCW); //
  16904. let index = geometry.index;
  16905. const position = geometry.attributes.position; //
  16906. if (index === null) {
  16907. if (position === undefined || position.count === 0) return;
  16908. } else if (index.count === 0) {
  16909. return;
  16910. } //
  16911. let rangeFactor = 1;
  16912. if (material.wireframe === true) {
  16913. index = geometries.getWireframeAttribute(geometry);
  16914. rangeFactor = 2;
  16915. }
  16916. bindingStates.setup(object, material, program, geometry, index);
  16917. let attribute;
  16918. let renderer = bufferRenderer;
  16919. if (index !== null) {
  16920. attribute = attributes.get(index);
  16921. renderer = indexedBufferRenderer;
  16922. renderer.setIndex(attribute);
  16923. } //
  16924. const dataCount = index !== null ? index.count : position.count;
  16925. const rangeStart = geometry.drawRange.start * rangeFactor;
  16926. const rangeCount = geometry.drawRange.count * rangeFactor;
  16927. const groupStart = group !== null ? group.start * rangeFactor : 0;
  16928. const groupCount = group !== null ? group.count * rangeFactor : Infinity;
  16929. const drawStart = Math.max(rangeStart, groupStart);
  16930. const drawEnd = Math.min(dataCount, rangeStart + rangeCount, groupStart + groupCount) - 1;
  16931. const drawCount = Math.max(0, drawEnd - drawStart + 1);
  16932. if (drawCount === 0) return; //
  16933. if (object.isMesh) {
  16934. if (material.wireframe === true) {
  16935. state.setLineWidth(material.wireframeLinewidth * getTargetPixelRatio());
  16936. renderer.setMode(_gl.LINES);
  16937. } else {
  16938. renderer.setMode(_gl.TRIANGLES);
  16939. }
  16940. } else if (object.isLine) {
  16941. let lineWidth = material.linewidth;
  16942. if (lineWidth === undefined) lineWidth = 1; // Not using Line*Material
  16943. state.setLineWidth(lineWidth * getTargetPixelRatio());
  16944. if (object.isLineSegments) {
  16945. renderer.setMode(_gl.LINES);
  16946. } else if (object.isLineLoop) {
  16947. renderer.setMode(_gl.LINE_LOOP);
  16948. } else {
  16949. renderer.setMode(_gl.LINE_STRIP);
  16950. }
  16951. } else if (object.isPoints) {
  16952. renderer.setMode(_gl.POINTS);
  16953. } else if (object.isSprite) {
  16954. renderer.setMode(_gl.TRIANGLES);
  16955. }
  16956. if (object.isInstancedMesh) {
  16957. renderer.renderInstances(drawStart, drawCount, object.count);
  16958. } else if (geometry.isInstancedBufferGeometry) {
  16959. const instanceCount = Math.min(geometry.instanceCount, geometry._maxInstanceCount);
  16960. renderer.renderInstances(drawStart, drawCount, instanceCount);
  16961. } else {
  16962. renderer.render(drawStart, drawCount);
  16963. }
  16964. }; // Compile
  16965. this.compile = function (scene, camera) {
  16966. currentRenderState = renderStates.get(scene);
  16967. currentRenderState.init();
  16968. renderStateStack.push(currentRenderState);
  16969. scene.traverseVisible(function (object) {
  16970. if (object.isLight && object.layers.test(camera.layers)) {
  16971. currentRenderState.pushLight(object);
  16972. if (object.castShadow) {
  16973. currentRenderState.pushShadow(object);
  16974. }
  16975. }
  16976. });
  16977. currentRenderState.setupLights(_this.physicallyCorrectLights);
  16978. scene.traverse(function (object) {
  16979. const material = object.material;
  16980. if (material) {
  16981. if (Array.isArray(material)) {
  16982. for (let i = 0; i < material.length; i++) {
  16983. const material2 = material[i];
  16984. getProgram(material2, scene, object);
  16985. }
  16986. } else {
  16987. getProgram(material, scene, object);
  16988. }
  16989. }
  16990. });
  16991. renderStateStack.pop();
  16992. currentRenderState = null;
  16993. }; // Animation Loop
  16994. let onAnimationFrameCallback = null;
  16995. function onAnimationFrame(time) {
  16996. if (onAnimationFrameCallback) onAnimationFrameCallback(time);
  16997. }
  16998. function onXRSessionStart() {
  16999. animation.stop();
  17000. }
  17001. function onXRSessionEnd() {
  17002. animation.start();
  17003. }
  17004. const animation = new WebGLAnimation();
  17005. animation.setAnimationLoop(onAnimationFrame);
  17006. if (typeof self !== 'undefined') animation.setContext(self);
  17007. this.setAnimationLoop = function (callback) {
  17008. onAnimationFrameCallback = callback;
  17009. xr.setAnimationLoop(callback);
  17010. callback === null ? animation.stop() : animation.start();
  17011. };
  17012. xr.addEventListener('sessionstart', onXRSessionStart);
  17013. xr.addEventListener('sessionend', onXRSessionEnd); // Rendering
  17014. this.render = function (scene, camera) {
  17015. if (camera !== undefined && camera.isCamera !== true) {
  17016. console.error('THREE.WebGLRenderer.render: camera is not an instance of THREE.Camera.');
  17017. return;
  17018. }
  17019. if (_isContextLost === true) return; // update scene graph
  17020. if (scene.autoUpdate === true) scene.updateMatrixWorld(); // update camera matrices and frustum
  17021. if (camera.parent === null) camera.updateMatrixWorld();
  17022. if (xr.enabled === true && xr.isPresenting === true) {
  17023. if (xr.cameraAutoUpdate === true) xr.updateCamera(camera);
  17024. camera = xr.getCamera(); // use XR camera for rendering
  17025. } //
  17026. if (scene.isScene === true) scene.onBeforeRender(_this, scene, camera, _currentRenderTarget);
  17027. currentRenderState = renderStates.get(scene, renderStateStack.length);
  17028. currentRenderState.init();
  17029. renderStateStack.push(currentRenderState);
  17030. _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
  17031. _frustum.setFromProjectionMatrix(_projScreenMatrix);
  17032. _localClippingEnabled = this.localClippingEnabled;
  17033. _clippingEnabled = clipping.init(this.clippingPlanes, _localClippingEnabled, camera);
  17034. currentRenderList = renderLists.get(scene, renderListStack.length);
  17035. currentRenderList.init();
  17036. renderListStack.push(currentRenderList);
  17037. projectObject(scene, camera, 0, _this.sortObjects);
  17038. currentRenderList.finish();
  17039. if (_this.sortObjects === true) {
  17040. currentRenderList.sort(_opaqueSort, _transparentSort);
  17041. } //
  17042. if (_clippingEnabled === true) clipping.beginShadows();
  17043. const shadowsArray = currentRenderState.state.shadowsArray;
  17044. shadowMap.render(shadowsArray, scene, camera);
  17045. if (_clippingEnabled === true) clipping.endShadows(); //
  17046. if (this.info.autoReset === true) this.info.reset(); //
  17047. background.render(currentRenderList, scene); // render scene
  17048. currentRenderState.setupLights(_this.physicallyCorrectLights);
  17049. if (camera.isArrayCamera) {
  17050. const cameras = camera.cameras;
  17051. for (let i = 0, l = cameras.length; i < l; i++) {
  17052. const camera2 = cameras[i];
  17053. renderScene(currentRenderList, scene, camera2, camera2.viewport);
  17054. }
  17055. } else {
  17056. renderScene(currentRenderList, scene, camera);
  17057. } //
  17058. if (_currentRenderTarget !== null) {
  17059. // resolve multisample renderbuffers to a single-sample texture if necessary
  17060. textures.updateMultisampleRenderTarget(_currentRenderTarget); // Generate mipmap if we're using any kind of mipmap filtering
  17061. textures.updateRenderTargetMipmap(_currentRenderTarget);
  17062. } //
  17063. if (scene.isScene === true) scene.onAfterRender(_this, scene, camera); // _gl.finish();
  17064. bindingStates.resetDefaultState();
  17065. _currentMaterialId = -1;
  17066. _currentCamera = null;
  17067. renderStateStack.pop();
  17068. if (renderStateStack.length > 0) {
  17069. currentRenderState = renderStateStack[renderStateStack.length - 1];
  17070. } else {
  17071. currentRenderState = null;
  17072. }
  17073. renderListStack.pop();
  17074. if (renderListStack.length > 0) {
  17075. currentRenderList = renderListStack[renderListStack.length - 1];
  17076. } else {
  17077. currentRenderList = null;
  17078. }
  17079. };
  17080. function projectObject(object, camera, groupOrder, sortObjects) {
  17081. if (object.visible === false) return;
  17082. const visible = object.layers.test(camera.layers);
  17083. if (visible) {
  17084. if (object.isGroup) {
  17085. groupOrder = object.renderOrder;
  17086. } else if (object.isLOD) {
  17087. if (object.autoUpdate === true) object.update(camera);
  17088. } else if (object.isLight) {
  17089. currentRenderState.pushLight(object);
  17090. if (object.castShadow) {
  17091. currentRenderState.pushShadow(object);
  17092. }
  17093. } else if (object.isSprite) {
  17094. if (!object.frustumCulled || _frustum.intersectsSprite(object)) {
  17095. if (sortObjects) {
  17096. _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix);
  17097. }
  17098. const geometry = objects.update(object);
  17099. const material = object.material;
  17100. if (material.visible) {
  17101. currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null);
  17102. }
  17103. }
  17104. } else if (object.isMesh || object.isLine || object.isPoints) {
  17105. if (object.isSkinnedMesh) {
  17106. // update skeleton only once in a frame
  17107. if (object.skeleton.frame !== info.render.frame) {
  17108. object.skeleton.update();
  17109. object.skeleton.frame = info.render.frame;
  17110. }
  17111. }
  17112. if (!object.frustumCulled || _frustum.intersectsObject(object)) {
  17113. if (sortObjects) {
  17114. _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(_projScreenMatrix);
  17115. }
  17116. const geometry = objects.update(object);
  17117. const material = object.material;
  17118. if (Array.isArray(material)) {
  17119. const groups = geometry.groups;
  17120. for (let i = 0, l = groups.length; i < l; i++) {
  17121. const group = groups[i];
  17122. const groupMaterial = material[group.materialIndex];
  17123. if (groupMaterial && groupMaterial.visible) {
  17124. currentRenderList.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group);
  17125. }
  17126. }
  17127. } else if (material.visible) {
  17128. currentRenderList.push(object, geometry, material, groupOrder, _vector3.z, null);
  17129. }
  17130. }
  17131. }
  17132. }
  17133. const children = object.children;
  17134. for (let i = 0, l = children.length; i < l; i++) {
  17135. projectObject(children[i], camera, groupOrder, sortObjects);
  17136. }
  17137. }
  17138. function renderScene(currentRenderList, scene, camera, viewport) {
  17139. const opaqueObjects = currentRenderList.opaque;
  17140. const transmissiveObjects = currentRenderList.transmissive;
  17141. const transparentObjects = currentRenderList.transparent;
  17142. currentRenderState.setupLightsView(camera);
  17143. if (transmissiveObjects.length > 0) renderTransmissionPass(opaqueObjects, scene, camera);
  17144. if (viewport) state.viewport(_currentViewport.copy(viewport));
  17145. if (opaqueObjects.length > 0) renderObjects(opaqueObjects, scene, camera);
  17146. if (transmissiveObjects.length > 0) renderObjects(transmissiveObjects, scene, camera);
  17147. if (transparentObjects.length > 0) renderObjects(transparentObjects, scene, camera); // Ensure depth buffer writing is enabled so it can be cleared on next render
  17148. state.buffers.depth.setTest(true);
  17149. state.buffers.depth.setMask(true);
  17150. state.buffers.color.setMask(true);
  17151. state.setPolygonOffset(false);
  17152. }
  17153. function renderTransmissionPass(opaqueObjects, scene, camera) {
  17154. const isWebGL2 = capabilities.isWebGL2;
  17155. if (_transmissionRenderTarget === null) {
  17156. _transmissionRenderTarget = new WebGLRenderTarget(1, 1, {
  17157. generateMipmaps: true,
  17158. type: extensions.has('EXT_color_buffer_half_float') ? HalfFloatType : UnsignedByteType,
  17159. minFilter: LinearMipmapLinearFilter,
  17160. samples: isWebGL2 && _antialias === true ? 4 : 0
  17161. });
  17162. }
  17163. _this.getDrawingBufferSize(_vector2);
  17164. if (isWebGL2) {
  17165. _transmissionRenderTarget.setSize(_vector2.x, _vector2.y);
  17166. } else {
  17167. _transmissionRenderTarget.setSize(floorPowerOfTwo(_vector2.x), floorPowerOfTwo(_vector2.y));
  17168. } //
  17169. const currentRenderTarget = _this.getRenderTarget();
  17170. _this.setRenderTarget(_transmissionRenderTarget);
  17171. _this.clear(); // Turn off the features which can affect the frag color for opaque objects pass.
  17172. // Otherwise they are applied twice in opaque objects pass and transmission objects pass.
  17173. const currentToneMapping = _this.toneMapping;
  17174. _this.toneMapping = NoToneMapping;
  17175. renderObjects(opaqueObjects, scene, camera);
  17176. _this.toneMapping = currentToneMapping;
  17177. textures.updateMultisampleRenderTarget(_transmissionRenderTarget);
  17178. textures.updateRenderTargetMipmap(_transmissionRenderTarget);
  17179. _this.setRenderTarget(currentRenderTarget);
  17180. }
  17181. function renderObjects(renderList, scene, camera) {
  17182. const overrideMaterial = scene.isScene === true ? scene.overrideMaterial : null;
  17183. for (let i = 0, l = renderList.length; i < l; i++) {
  17184. const renderItem = renderList[i];
  17185. const object = renderItem.object;
  17186. const geometry = renderItem.geometry;
  17187. const material = overrideMaterial === null ? renderItem.material : overrideMaterial;
  17188. const group = renderItem.group;
  17189. if (object.layers.test(camera.layers)) {
  17190. renderObject(object, scene, camera, geometry, material, group);
  17191. }
  17192. }
  17193. }
  17194. function renderObject(object, scene, camera, geometry, material, group) {
  17195. object.onBeforeRender(_this, scene, camera, geometry, material, group);
  17196. object.modelViewMatrix.multiplyMatrices(camera.matrixWorldInverse, object.matrixWorld);
  17197. object.normalMatrix.getNormalMatrix(object.modelViewMatrix);
  17198. material.onBeforeRender(_this, scene, camera, geometry, object, group);
  17199. if (material.transparent === true && material.side === DoubleSide) {
  17200. material.side = BackSide;
  17201. material.needsUpdate = true;
  17202. _this.renderBufferDirect(camera, scene, geometry, material, object, group);
  17203. material.side = FrontSide;
  17204. material.needsUpdate = true;
  17205. _this.renderBufferDirect(camera, scene, geometry, material, object, group);
  17206. material.side = DoubleSide;
  17207. } else {
  17208. _this.renderBufferDirect(camera, scene, geometry, material, object, group);
  17209. }
  17210. object.onAfterRender(_this, scene, camera, geometry, material, group);
  17211. }
  17212. function getProgram(material, scene, object) {
  17213. if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
  17214. const materialProperties = properties.get(material);
  17215. const lights = currentRenderState.state.lights;
  17216. const shadowsArray = currentRenderState.state.shadowsArray;
  17217. const lightsStateVersion = lights.state.version;
  17218. const parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object);
  17219. const programCacheKey = programCache.getProgramCacheKey(parameters);
  17220. let programs = materialProperties.programs; // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change
  17221. materialProperties.environment = material.isMeshStandardMaterial ? scene.environment : null;
  17222. materialProperties.fog = scene.fog;
  17223. materialProperties.envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || materialProperties.environment);
  17224. if (programs === undefined) {
  17225. // new material
  17226. material.addEventListener('dispose', onMaterialDispose);
  17227. programs = new Map();
  17228. materialProperties.programs = programs;
  17229. }
  17230. let program = programs.get(programCacheKey);
  17231. if (program !== undefined) {
  17232. // early out if program and light state is identical
  17233. if (materialProperties.currentProgram === program && materialProperties.lightsStateVersion === lightsStateVersion) {
  17234. updateCommonMaterialProperties(material, parameters);
  17235. return program;
  17236. }
  17237. } else {
  17238. parameters.uniforms = programCache.getUniforms(material);
  17239. material.onBuild(object, parameters, _this);
  17240. material.onBeforeCompile(parameters, _this);
  17241. program = programCache.acquireProgram(parameters, programCacheKey);
  17242. programs.set(programCacheKey, program);
  17243. materialProperties.uniforms = parameters.uniforms;
  17244. }
  17245. const uniforms = materialProperties.uniforms;
  17246. if (!material.isShaderMaterial && !material.isRawShaderMaterial || material.clipping === true) {
  17247. uniforms.clippingPlanes = clipping.uniform;
  17248. }
  17249. updateCommonMaterialProperties(material, parameters); // store the light setup it was created for
  17250. materialProperties.needsLights = materialNeedsLights(material);
  17251. materialProperties.lightsStateVersion = lightsStateVersion;
  17252. if (materialProperties.needsLights) {
  17253. // wire up the material to this renderer's lighting state
  17254. uniforms.ambientLightColor.value = lights.state.ambient;
  17255. uniforms.lightProbe.value = lights.state.probe;
  17256. uniforms.directionalLights.value = lights.state.directional;
  17257. uniforms.directionalLightShadows.value = lights.state.directionalShadow;
  17258. uniforms.spotLights.value = lights.state.spot;
  17259. uniforms.spotLightShadows.value = lights.state.spotShadow;
  17260. uniforms.rectAreaLights.value = lights.state.rectArea;
  17261. uniforms.ltc_1.value = lights.state.rectAreaLTC1;
  17262. uniforms.ltc_2.value = lights.state.rectAreaLTC2;
  17263. uniforms.pointLights.value = lights.state.point;
  17264. uniforms.pointLightShadows.value = lights.state.pointShadow;
  17265. uniforms.hemisphereLights.value = lights.state.hemi;
  17266. uniforms.directionalShadowMap.value = lights.state.directionalShadowMap;
  17267. uniforms.directionalShadowMatrix.value = lights.state.directionalShadowMatrix;
  17268. uniforms.spotShadowMap.value = lights.state.spotShadowMap;
  17269. uniforms.spotShadowMatrix.value = lights.state.spotShadowMatrix;
  17270. uniforms.pointShadowMap.value = lights.state.pointShadowMap;
  17271. uniforms.pointShadowMatrix.value = lights.state.pointShadowMatrix; // TODO (abelnation): add area lights shadow info to uniforms
  17272. }
  17273. const progUniforms = program.getUniforms();
  17274. const uniformsList = WebGLUniforms.seqWithValue(progUniforms.seq, uniforms);
  17275. materialProperties.currentProgram = program;
  17276. materialProperties.uniformsList = uniformsList;
  17277. return program;
  17278. }
  17279. function updateCommonMaterialProperties(material, parameters) {
  17280. const materialProperties = properties.get(material);
  17281. materialProperties.outputEncoding = parameters.outputEncoding;
  17282. materialProperties.instancing = parameters.instancing;
  17283. materialProperties.skinning = parameters.skinning;
  17284. materialProperties.morphTargets = parameters.morphTargets;
  17285. materialProperties.morphNormals = parameters.morphNormals;
  17286. materialProperties.morphColors = parameters.morphColors;
  17287. materialProperties.morphTargetsCount = parameters.morphTargetsCount;
  17288. materialProperties.numClippingPlanes = parameters.numClippingPlanes;
  17289. materialProperties.numIntersection = parameters.numClipIntersection;
  17290. materialProperties.vertexAlphas = parameters.vertexAlphas;
  17291. materialProperties.vertexTangents = parameters.vertexTangents;
  17292. materialProperties.toneMapping = parameters.toneMapping;
  17293. }
  17294. function setProgram(camera, scene, geometry, material, object) {
  17295. if (scene.isScene !== true) scene = _emptyScene; // scene could be a Mesh, Line, Points, ...
  17296. textures.resetTextureUnits();
  17297. const fog = scene.fog;
  17298. const environment = material.isMeshStandardMaterial ? scene.environment : null;
  17299. const encoding = _currentRenderTarget === null ? _this.outputEncoding : _currentRenderTarget.isXRRenderTarget === true ? _currentRenderTarget.texture.encoding : LinearEncoding;
  17300. const envMap = (material.isMeshStandardMaterial ? cubeuvmaps : cubemaps).get(material.envMap || environment);
  17301. const vertexAlphas = material.vertexColors === true && !!geometry.attributes.color && geometry.attributes.color.itemSize === 4;
  17302. const vertexTangents = !!material.normalMap && !!geometry.attributes.tangent;
  17303. const morphTargets = !!geometry.morphAttributes.position;
  17304. const morphNormals = !!geometry.morphAttributes.normal;
  17305. const morphColors = !!geometry.morphAttributes.color;
  17306. const toneMapping = material.toneMapped ? _this.toneMapping : NoToneMapping;
  17307. const morphAttribute = geometry.morphAttributes.position || geometry.morphAttributes.normal || geometry.morphAttributes.color;
  17308. const morphTargetsCount = morphAttribute !== undefined ? morphAttribute.length : 0;
  17309. const materialProperties = properties.get(material);
  17310. const lights = currentRenderState.state.lights;
  17311. if (_clippingEnabled === true) {
  17312. if (_localClippingEnabled === true || camera !== _currentCamera) {
  17313. const useCache = camera === _currentCamera && material.id === _currentMaterialId; // we might want to call this function with some ClippingGroup
  17314. // object instead of the material, once it becomes feasible
  17315. // (#8465, #8379)
  17316. clipping.setState(material, camera, useCache);
  17317. }
  17318. } //
  17319. let needsProgramChange = false;
  17320. if (material.version === materialProperties.__version) {
  17321. if (materialProperties.needsLights && materialProperties.lightsStateVersion !== lights.state.version) {
  17322. needsProgramChange = true;
  17323. } else if (materialProperties.outputEncoding !== encoding) {
  17324. needsProgramChange = true;
  17325. } else if (object.isInstancedMesh && materialProperties.instancing === false) {
  17326. needsProgramChange = true;
  17327. } else if (!object.isInstancedMesh && materialProperties.instancing === true) {
  17328. needsProgramChange = true;
  17329. } else if (object.isSkinnedMesh && materialProperties.skinning === false) {
  17330. needsProgramChange = true;
  17331. } else if (!object.isSkinnedMesh && materialProperties.skinning === true) {
  17332. needsProgramChange = true;
  17333. } else if (materialProperties.envMap !== envMap) {
  17334. needsProgramChange = true;
  17335. } else if (material.fog === true && materialProperties.fog !== fog) {
  17336. needsProgramChange = true;
  17337. } else if (materialProperties.numClippingPlanes !== undefined && (materialProperties.numClippingPlanes !== clipping.numPlanes || materialProperties.numIntersection !== clipping.numIntersection)) {
  17338. needsProgramChange = true;
  17339. } else if (materialProperties.vertexAlphas !== vertexAlphas) {
  17340. needsProgramChange = true;
  17341. } else if (materialProperties.vertexTangents !== vertexTangents) {
  17342. needsProgramChange = true;
  17343. } else if (materialProperties.morphTargets !== morphTargets) {
  17344. needsProgramChange = true;
  17345. } else if (materialProperties.morphNormals !== morphNormals) {
  17346. needsProgramChange = true;
  17347. } else if (materialProperties.morphColors !== morphColors) {
  17348. needsProgramChange = true;
  17349. } else if (materialProperties.toneMapping !== toneMapping) {
  17350. needsProgramChange = true;
  17351. } else if (capabilities.isWebGL2 === true && materialProperties.morphTargetsCount !== morphTargetsCount) {
  17352. needsProgramChange = true;
  17353. }
  17354. } else {
  17355. needsProgramChange = true;
  17356. materialProperties.__version = material.version;
  17357. } //
  17358. let program = materialProperties.currentProgram;
  17359. if (needsProgramChange === true) {
  17360. program = getProgram(material, scene, object);
  17361. }
  17362. let refreshProgram = false;
  17363. let refreshMaterial = false;
  17364. let refreshLights = false;
  17365. const p_uniforms = program.getUniforms(),
  17366. m_uniforms = materialProperties.uniforms;
  17367. if (state.useProgram(program.program)) {
  17368. refreshProgram = true;
  17369. refreshMaterial = true;
  17370. refreshLights = true;
  17371. }
  17372. if (material.id !== _currentMaterialId) {
  17373. _currentMaterialId = material.id;
  17374. refreshMaterial = true;
  17375. }
  17376. if (refreshProgram || _currentCamera !== camera) {
  17377. p_uniforms.setValue(_gl, 'projectionMatrix', camera.projectionMatrix);
  17378. if (capabilities.logarithmicDepthBuffer) {
  17379. p_uniforms.setValue(_gl, 'logDepthBufFC', 2.0 / (Math.log(camera.far + 1.0) / Math.LN2));
  17380. }
  17381. if (_currentCamera !== camera) {
  17382. _currentCamera = camera; // lighting uniforms depend on the camera so enforce an update
  17383. // now, in case this material supports lights - or later, when
  17384. // the next material that does gets activated:
  17385. refreshMaterial = true; // set to true on material change
  17386. refreshLights = true; // remains set until update done
  17387. } // load material specific uniforms
  17388. // (shader material also gets them for the sake of genericity)
  17389. if (material.isShaderMaterial || material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshStandardMaterial || material.envMap) {
  17390. const uCamPos = p_uniforms.map.cameraPosition;
  17391. if (uCamPos !== undefined) {
  17392. uCamPos.setValue(_gl, _vector3.setFromMatrixPosition(camera.matrixWorld));
  17393. }
  17394. }
  17395. if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial) {
  17396. p_uniforms.setValue(_gl, 'isOrthographic', camera.isOrthographicCamera === true);
  17397. }
  17398. if (material.isMeshPhongMaterial || material.isMeshToonMaterial || material.isMeshLambertMaterial || material.isMeshBasicMaterial || material.isMeshStandardMaterial || material.isShaderMaterial || material.isShadowMaterial || object.isSkinnedMesh) {
  17399. p_uniforms.setValue(_gl, 'viewMatrix', camera.matrixWorldInverse);
  17400. }
  17401. } // skinning and morph target uniforms must be set even if material didn't change
  17402. // auto-setting of texture unit for bone and morph texture must go before other textures
  17403. // otherwise textures used for skinning and morphing can take over texture units reserved for other material textures
  17404. if (object.isSkinnedMesh) {
  17405. p_uniforms.setOptional(_gl, object, 'bindMatrix');
  17406. p_uniforms.setOptional(_gl, object, 'bindMatrixInverse');
  17407. const skeleton = object.skeleton;
  17408. if (skeleton) {
  17409. if (capabilities.floatVertexTextures) {
  17410. if (skeleton.boneTexture === null) skeleton.computeBoneTexture();
  17411. p_uniforms.setValue(_gl, 'boneTexture', skeleton.boneTexture, textures);
  17412. p_uniforms.setValue(_gl, 'boneTextureSize', skeleton.boneTextureSize);
  17413. } else {
  17414. console.warn('THREE.WebGLRenderer: SkinnedMesh can only be used with WebGL 2. With WebGL 1 OES_texture_float and vertex textures support is required.');
  17415. }
  17416. }
  17417. }
  17418. const morphAttributes = geometry.morphAttributes;
  17419. if (morphAttributes.position !== undefined || morphAttributes.normal !== undefined || morphAttributes.color !== undefined && capabilities.isWebGL2 === true) {
  17420. morphtargets.update(object, geometry, material, program);
  17421. }
  17422. if (refreshMaterial || materialProperties.receiveShadow !== object.receiveShadow) {
  17423. materialProperties.receiveShadow = object.receiveShadow;
  17424. p_uniforms.setValue(_gl, 'receiveShadow', object.receiveShadow);
  17425. }
  17426. if (refreshMaterial) {
  17427. p_uniforms.setValue(_gl, 'toneMappingExposure', _this.toneMappingExposure);
  17428. if (materialProperties.needsLights) {
  17429. // the current material requires lighting info
  17430. // note: all lighting uniforms are always set correctly
  17431. // they simply reference the renderer's state for their
  17432. // values
  17433. //
  17434. // use the current material's .needsUpdate flags to set
  17435. // the GL state when required
  17436. markUniformsLightsNeedsUpdate(m_uniforms, refreshLights);
  17437. } // refresh uniforms common to several materials
  17438. if (fog && material.fog === true) {
  17439. materials.refreshFogUniforms(m_uniforms, fog);
  17440. }
  17441. materials.refreshMaterialUniforms(m_uniforms, material, _pixelRatio, _height, _transmissionRenderTarget);
  17442. WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures);
  17443. }
  17444. if (material.isShaderMaterial && material.uniformsNeedUpdate === true) {
  17445. WebGLUniforms.upload(_gl, materialProperties.uniformsList, m_uniforms, textures);
  17446. material.uniformsNeedUpdate = false;
  17447. }
  17448. if (material.isSpriteMaterial) {
  17449. p_uniforms.setValue(_gl, 'center', object.center);
  17450. } // common matrices
  17451. p_uniforms.setValue(_gl, 'modelViewMatrix', object.modelViewMatrix);
  17452. p_uniforms.setValue(_gl, 'normalMatrix', object.normalMatrix);
  17453. p_uniforms.setValue(_gl, 'modelMatrix', object.matrixWorld); // UBOs
  17454. if (material.isShaderMaterial || material.isRawShaderMaterial) {
  17455. const groups = material.uniformsGroups;
  17456. for (let i = 0, l = groups.length; i < l; i++) {
  17457. if (capabilities.isWebGL2) {
  17458. const group = groups[i];
  17459. uniformsGroups.update(group, program);
  17460. uniformsGroups.bind(group, program);
  17461. } else {
  17462. console.warn('THREE.WebGLRenderer: Uniform Buffer Objects can only be used with WebGL 2.');
  17463. }
  17464. }
  17465. }
  17466. return program;
  17467. } // If uniforms are marked as clean, they don't need to be loaded to the GPU.
  17468. function markUniformsLightsNeedsUpdate(uniforms, value) {
  17469. uniforms.ambientLightColor.needsUpdate = value;
  17470. uniforms.lightProbe.needsUpdate = value;
  17471. uniforms.directionalLights.needsUpdate = value;
  17472. uniforms.directionalLightShadows.needsUpdate = value;
  17473. uniforms.pointLights.needsUpdate = value;
  17474. uniforms.pointLightShadows.needsUpdate = value;
  17475. uniforms.spotLights.needsUpdate = value;
  17476. uniforms.spotLightShadows.needsUpdate = value;
  17477. uniforms.rectAreaLights.needsUpdate = value;
  17478. uniforms.hemisphereLights.needsUpdate = value;
  17479. }
  17480. function materialNeedsLights(material) {
  17481. return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true;
  17482. }
  17483. this.getActiveCubeFace = function () {
  17484. return _currentActiveCubeFace;
  17485. };
  17486. this.getActiveMipmapLevel = function () {
  17487. return _currentActiveMipmapLevel;
  17488. };
  17489. this.getRenderTarget = function () {
  17490. return _currentRenderTarget;
  17491. };
  17492. this.setRenderTargetTextures = function (renderTarget, colorTexture, depthTexture) {
  17493. properties.get(renderTarget.texture).__webglTexture = colorTexture;
  17494. properties.get(renderTarget.depthTexture).__webglTexture = depthTexture;
  17495. const renderTargetProperties = properties.get(renderTarget);
  17496. renderTargetProperties.__hasExternalTextures = true;
  17497. if (renderTargetProperties.__hasExternalTextures) {
  17498. renderTargetProperties.__autoAllocateDepthBuffer = depthTexture === undefined;
  17499. if (!renderTargetProperties.__autoAllocateDepthBuffer) {
  17500. // The multisample_render_to_texture extension doesn't work properly if there
  17501. // are midframe flushes and an external depth buffer. Disable use of the extension.
  17502. if (extensions.has('WEBGL_multisampled_render_to_texture') === true) {
  17503. console.warn('THREE.WebGLRenderer: Render-to-texture extension was disabled because an external texture was provided');
  17504. renderTargetProperties.__useRenderToTexture = false;
  17505. }
  17506. }
  17507. }
  17508. };
  17509. this.setRenderTargetFramebuffer = function (renderTarget, defaultFramebuffer) {
  17510. const renderTargetProperties = properties.get(renderTarget);
  17511. renderTargetProperties.__webglFramebuffer = defaultFramebuffer;
  17512. renderTargetProperties.__useDefaultFramebuffer = defaultFramebuffer === undefined;
  17513. };
  17514. this.setRenderTarget = function (renderTarget, activeCubeFace = 0, activeMipmapLevel = 0) {
  17515. _currentRenderTarget = renderTarget;
  17516. _currentActiveCubeFace = activeCubeFace;
  17517. _currentActiveMipmapLevel = activeMipmapLevel;
  17518. let useDefaultFramebuffer = true;
  17519. if (renderTarget) {
  17520. const renderTargetProperties = properties.get(renderTarget);
  17521. if (renderTargetProperties.__useDefaultFramebuffer !== undefined) {
  17522. // We need to make sure to rebind the framebuffer.
  17523. state.bindFramebuffer(_gl.FRAMEBUFFER, null);
  17524. useDefaultFramebuffer = false;
  17525. } else if (renderTargetProperties.__webglFramebuffer === undefined) {
  17526. textures.setupRenderTarget(renderTarget);
  17527. } else if (renderTargetProperties.__hasExternalTextures) {
  17528. // Color and depth texture must be rebound in order for the swapchain to update.
  17529. textures.rebindTextures(renderTarget, properties.get(renderTarget.texture).__webglTexture, properties.get(renderTarget.depthTexture).__webglTexture);
  17530. }
  17531. }
  17532. let framebuffer = null;
  17533. let isCube = false;
  17534. let isRenderTarget3D = false;
  17535. if (renderTarget) {
  17536. const texture = renderTarget.texture;
  17537. if (texture.isData3DTexture || texture.isDataArrayTexture) {
  17538. isRenderTarget3D = true;
  17539. }
  17540. const __webglFramebuffer = properties.get(renderTarget).__webglFramebuffer;
  17541. if (renderTarget.isWebGLCubeRenderTarget) {
  17542. framebuffer = __webglFramebuffer[activeCubeFace];
  17543. isCube = true;
  17544. } else if (capabilities.isWebGL2 && renderTarget.samples > 0 && textures.useMultisampledRTT(renderTarget) === false) {
  17545. framebuffer = properties.get(renderTarget).__webglMultisampledFramebuffer;
  17546. } else {
  17547. framebuffer = __webglFramebuffer;
  17548. }
  17549. _currentViewport.copy(renderTarget.viewport);
  17550. _currentScissor.copy(renderTarget.scissor);
  17551. _currentScissorTest = renderTarget.scissorTest;
  17552. } else {
  17553. _currentViewport.copy(_viewport).multiplyScalar(_pixelRatio).floor();
  17554. _currentScissor.copy(_scissor).multiplyScalar(_pixelRatio).floor();
  17555. _currentScissorTest = _scissorTest;
  17556. }
  17557. const framebufferBound = state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
  17558. if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) {
  17559. state.drawBuffers(renderTarget, framebuffer);
  17560. }
  17561. state.viewport(_currentViewport);
  17562. state.scissor(_currentScissor);
  17563. state.setScissorTest(_currentScissorTest);
  17564. if (isCube) {
  17565. const textureProperties = properties.get(renderTarget.texture);
  17566. _gl.framebufferTexture2D(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties.__webglTexture, activeMipmapLevel);
  17567. } else if (isRenderTarget3D) {
  17568. const textureProperties = properties.get(renderTarget.texture);
  17569. const layer = activeCubeFace || 0;
  17570. _gl.framebufferTextureLayer(_gl.FRAMEBUFFER, _gl.COLOR_ATTACHMENT0, textureProperties.__webglTexture, activeMipmapLevel || 0, layer);
  17571. }
  17572. _currentMaterialId = -1; // reset current material to ensure correct uniform bindings
  17573. };
  17574. this.readRenderTargetPixels = function (renderTarget, x, y, width, height, buffer, activeCubeFaceIndex) {
  17575. if (!(renderTarget && renderTarget.isWebGLRenderTarget)) {
  17576. console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.');
  17577. return;
  17578. }
  17579. let framebuffer = properties.get(renderTarget).__webglFramebuffer;
  17580. if (renderTarget.isWebGLCubeRenderTarget && activeCubeFaceIndex !== undefined) {
  17581. framebuffer = framebuffer[activeCubeFaceIndex];
  17582. }
  17583. if (framebuffer) {
  17584. state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
  17585. try {
  17586. const texture = renderTarget.texture;
  17587. const textureFormat = texture.format;
  17588. const textureType = texture.type;
  17589. if (textureFormat !== RGBAFormat && utils.convert(textureFormat) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_FORMAT)) {
  17590. console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.');
  17591. return;
  17592. }
  17593. const halfFloatSupportedByExt = textureType === HalfFloatType && (extensions.has('EXT_color_buffer_half_float') || capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float'));
  17594. if (textureType !== UnsignedByteType && utils.convert(textureType) !== _gl.getParameter(_gl.IMPLEMENTATION_COLOR_READ_TYPE) && // Edge and Chrome Mac < 52 (#9513)
  17595. !(textureType === FloatType && (capabilities.isWebGL2 || extensions.has('OES_texture_float') || extensions.has('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox
  17596. !halfFloatSupportedByExt) {
  17597. console.error('THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.');
  17598. return;
  17599. } // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604)
  17600. if (x >= 0 && x <= renderTarget.width - width && y >= 0 && y <= renderTarget.height - height) {
  17601. _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer);
  17602. }
  17603. } finally {
  17604. // restore framebuffer of current render target if necessary
  17605. const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null;
  17606. state.bindFramebuffer(_gl.FRAMEBUFFER, framebuffer);
  17607. }
  17608. }
  17609. };
  17610. this.copyFramebufferToTexture = function (position, texture, level = 0) {
  17611. const levelScale = Math.pow(2, -level);
  17612. const width = Math.floor(texture.image.width * levelScale);
  17613. const height = Math.floor(texture.image.height * levelScale);
  17614. textures.setTexture2D(texture, 0);
  17615. _gl.copyTexSubImage2D(_gl.TEXTURE_2D, level, 0, 0, position.x, position.y, width, height);
  17616. state.unbindTexture();
  17617. };
  17618. this.copyTextureToTexture = function (position, srcTexture, dstTexture, level = 0) {
  17619. const width = srcTexture.image.width;
  17620. const height = srcTexture.image.height;
  17621. const glFormat = utils.convert(dstTexture.format);
  17622. const glType = utils.convert(dstTexture.type);
  17623. textures.setTexture2D(dstTexture, 0); // As another texture upload may have changed pixelStorei
  17624. // parameters, make sure they are correct for the dstTexture
  17625. _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY);
  17626. _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha);
  17627. _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment);
  17628. if (srcTexture.isDataTexture) {
  17629. _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, width, height, glFormat, glType, srcTexture.image.data);
  17630. } else {
  17631. if (srcTexture.isCompressedTexture) {
  17632. _gl.compressedTexSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, srcTexture.mipmaps[0].width, srcTexture.mipmaps[0].height, glFormat, srcTexture.mipmaps[0].data);
  17633. } else {
  17634. _gl.texSubImage2D(_gl.TEXTURE_2D, level, position.x, position.y, glFormat, glType, srcTexture.image);
  17635. }
  17636. } // Generate mipmaps only when copying level 0
  17637. if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(_gl.TEXTURE_2D);
  17638. state.unbindTexture();
  17639. };
  17640. this.copyTextureToTexture3D = function (sourceBox, position, srcTexture, dstTexture, level = 0) {
  17641. if (_this.isWebGL1Renderer) {
  17642. console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: can only be used with WebGL2.');
  17643. return;
  17644. }
  17645. const width = sourceBox.max.x - sourceBox.min.x + 1;
  17646. const height = sourceBox.max.y - sourceBox.min.y + 1;
  17647. const depth = sourceBox.max.z - sourceBox.min.z + 1;
  17648. const glFormat = utils.convert(dstTexture.format);
  17649. const glType = utils.convert(dstTexture.type);
  17650. let glTarget;
  17651. if (dstTexture.isData3DTexture) {
  17652. textures.setTexture3D(dstTexture, 0);
  17653. glTarget = _gl.TEXTURE_3D;
  17654. } else if (dstTexture.isDataArrayTexture) {
  17655. textures.setTexture2DArray(dstTexture, 0);
  17656. glTarget = _gl.TEXTURE_2D_ARRAY;
  17657. } else {
  17658. console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: only supports THREE.DataTexture3D and THREE.DataTexture2DArray.');
  17659. return;
  17660. }
  17661. _gl.pixelStorei(_gl.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY);
  17662. _gl.pixelStorei(_gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha);
  17663. _gl.pixelStorei(_gl.UNPACK_ALIGNMENT, dstTexture.unpackAlignment);
  17664. const unpackRowLen = _gl.getParameter(_gl.UNPACK_ROW_LENGTH);
  17665. const unpackImageHeight = _gl.getParameter(_gl.UNPACK_IMAGE_HEIGHT);
  17666. const unpackSkipPixels = _gl.getParameter(_gl.UNPACK_SKIP_PIXELS);
  17667. const unpackSkipRows = _gl.getParameter(_gl.UNPACK_SKIP_ROWS);
  17668. const unpackSkipImages = _gl.getParameter(_gl.UNPACK_SKIP_IMAGES);
  17669. const image = srcTexture.isCompressedTexture ? srcTexture.mipmaps[0] : srcTexture.image;
  17670. _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, image.width);
  17671. _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, image.height);
  17672. _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, sourceBox.min.x);
  17673. _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, sourceBox.min.y);
  17674. _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, sourceBox.min.z);
  17675. if (srcTexture.isDataTexture || srcTexture.isData3DTexture) {
  17676. _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image.data);
  17677. } else {
  17678. if (srcTexture.isCompressedTexture) {
  17679. console.warn('THREE.WebGLRenderer.copyTextureToTexture3D: untested support for compressed srcTexture.');
  17680. _gl.compressedTexSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, image.data);
  17681. } else {
  17682. _gl.texSubImage3D(glTarget, level, position.x, position.y, position.z, width, height, depth, glFormat, glType, image);
  17683. }
  17684. }
  17685. _gl.pixelStorei(_gl.UNPACK_ROW_LENGTH, unpackRowLen);
  17686. _gl.pixelStorei(_gl.UNPACK_IMAGE_HEIGHT, unpackImageHeight);
  17687. _gl.pixelStorei(_gl.UNPACK_SKIP_PIXELS, unpackSkipPixels);
  17688. _gl.pixelStorei(_gl.UNPACK_SKIP_ROWS, unpackSkipRows);
  17689. _gl.pixelStorei(_gl.UNPACK_SKIP_IMAGES, unpackSkipImages); // Generate mipmaps only when copying level 0
  17690. if (level === 0 && dstTexture.generateMipmaps) _gl.generateMipmap(glTarget);
  17691. state.unbindTexture();
  17692. };
  17693. this.initTexture = function (texture) {
  17694. if (texture.isCubeTexture) {
  17695. textures.setTextureCube(texture, 0);
  17696. } else if (texture.isData3DTexture) {
  17697. textures.setTexture3D(texture, 0);
  17698. } else if (texture.isDataArrayTexture) {
  17699. textures.setTexture2DArray(texture, 0);
  17700. } else {
  17701. textures.setTexture2D(texture, 0);
  17702. }
  17703. state.unbindTexture();
  17704. };
  17705. this.resetState = function () {
  17706. _currentActiveCubeFace = 0;
  17707. _currentActiveMipmapLevel = 0;
  17708. _currentRenderTarget = null;
  17709. state.reset();
  17710. bindingStates.reset();
  17711. };
  17712. if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
  17713. __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', {
  17714. detail: this
  17715. }));
  17716. }
  17717. }
  17718. class WebGL1Renderer extends WebGLRenderer {}
  17719. WebGL1Renderer.prototype.isWebGL1Renderer = true;
  17720. class FogExp2 {
  17721. constructor(color, density = 0.00025) {
  17722. this.isFogExp2 = true;
  17723. this.name = '';
  17724. this.color = new Color(color);
  17725. this.density = density;
  17726. }
  17727. clone() {
  17728. return new FogExp2(this.color, this.density);
  17729. }
  17730. toJSON() {
  17731. return {
  17732. type: 'FogExp2',
  17733. color: this.color.getHex(),
  17734. density: this.density
  17735. };
  17736. }
  17737. }
  17738. class Fog {
  17739. constructor(color, near = 1, far = 1000) {
  17740. this.isFog = true;
  17741. this.name = '';
  17742. this.color = new Color(color);
  17743. this.near = near;
  17744. this.far = far;
  17745. }
  17746. clone() {
  17747. return new Fog(this.color, this.near, this.far);
  17748. }
  17749. toJSON() {
  17750. return {
  17751. type: 'Fog',
  17752. color: this.color.getHex(),
  17753. near: this.near,
  17754. far: this.far
  17755. };
  17756. }
  17757. }
  17758. class Scene extends Object3D {
  17759. constructor() {
  17760. super();
  17761. this.isScene = true;
  17762. this.type = 'Scene';
  17763. this.background = null;
  17764. this.environment = null;
  17765. this.fog = null;
  17766. this.overrideMaterial = null;
  17767. this.autoUpdate = true; // checked by the renderer
  17768. if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
  17769. __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('observe', {
  17770. detail: this
  17771. }));
  17772. }
  17773. }
  17774. copy(source, recursive) {
  17775. super.copy(source, recursive);
  17776. if (source.background !== null) this.background = source.background.clone();
  17777. if (source.environment !== null) this.environment = source.environment.clone();
  17778. if (source.fog !== null) this.fog = source.fog.clone();
  17779. if (source.overrideMaterial !== null) this.overrideMaterial = source.overrideMaterial.clone();
  17780. this.autoUpdate = source.autoUpdate;
  17781. this.matrixAutoUpdate = source.matrixAutoUpdate;
  17782. return this;
  17783. }
  17784. toJSON(meta) {
  17785. const data = super.toJSON(meta);
  17786. if (this.fog !== null) data.object.fog = this.fog.toJSON();
  17787. return data;
  17788. }
  17789. }
  17790. class InterleavedBuffer {
  17791. constructor(array, stride) {
  17792. this.isInterleavedBuffer = true;
  17793. this.array = array;
  17794. this.stride = stride;
  17795. this.count = array !== undefined ? array.length / stride : 0;
  17796. this.usage = StaticDrawUsage;
  17797. this.updateRange = {
  17798. offset: 0,
  17799. count: -1
  17800. };
  17801. this.version = 0;
  17802. this.uuid = generateUUID();
  17803. }
  17804. onUploadCallback() {}
  17805. set needsUpdate(value) {
  17806. if (value === true) this.version++;
  17807. }
  17808. setUsage(value) {
  17809. this.usage = value;
  17810. return this;
  17811. }
  17812. copy(source) {
  17813. this.array = new source.array.constructor(source.array);
  17814. this.count = source.count;
  17815. this.stride = source.stride;
  17816. this.usage = source.usage;
  17817. return this;
  17818. }
  17819. copyAt(index1, attribute, index2) {
  17820. index1 *= this.stride;
  17821. index2 *= attribute.stride;
  17822. for (let i = 0, l = this.stride; i < l; i++) {
  17823. this.array[index1 + i] = attribute.array[index2 + i];
  17824. }
  17825. return this;
  17826. }
  17827. set(value, offset = 0) {
  17828. this.array.set(value, offset);
  17829. return this;
  17830. }
  17831. clone(data) {
  17832. if (data.arrayBuffers === undefined) {
  17833. data.arrayBuffers = {};
  17834. }
  17835. if (this.array.buffer._uuid === undefined) {
  17836. this.array.buffer._uuid = generateUUID();
  17837. }
  17838. if (data.arrayBuffers[this.array.buffer._uuid] === undefined) {
  17839. data.arrayBuffers[this.array.buffer._uuid] = this.array.slice(0).buffer;
  17840. }
  17841. const array = new this.array.constructor(data.arrayBuffers[this.array.buffer._uuid]);
  17842. const ib = new this.constructor(array, this.stride);
  17843. ib.setUsage(this.usage);
  17844. return ib;
  17845. }
  17846. onUpload(callback) {
  17847. this.onUploadCallback = callback;
  17848. return this;
  17849. }
  17850. toJSON(data) {
  17851. if (data.arrayBuffers === undefined) {
  17852. data.arrayBuffers = {};
  17853. } // generate UUID for array buffer if necessary
  17854. if (this.array.buffer._uuid === undefined) {
  17855. this.array.buffer._uuid = generateUUID();
  17856. }
  17857. if (data.arrayBuffers[this.array.buffer._uuid] === undefined) {
  17858. data.arrayBuffers[this.array.buffer._uuid] = Array.from(new Uint32Array(this.array.buffer));
  17859. } //
  17860. return {
  17861. uuid: this.uuid,
  17862. buffer: this.array.buffer._uuid,
  17863. type: this.array.constructor.name,
  17864. stride: this.stride
  17865. };
  17866. }
  17867. }
  17868. const _vector$6 = /*@__PURE__*/new Vector3();
  17869. class InterleavedBufferAttribute {
  17870. constructor(interleavedBuffer, itemSize, offset, normalized = false) {
  17871. this.isInterleavedBufferAttribute = true;
  17872. this.name = '';
  17873. this.data = interleavedBuffer;
  17874. this.itemSize = itemSize;
  17875. this.offset = offset;
  17876. this.normalized = normalized === true;
  17877. }
  17878. get count() {
  17879. return this.data.count;
  17880. }
  17881. get array() {
  17882. return this.data.array;
  17883. }
  17884. set needsUpdate(value) {
  17885. this.data.needsUpdate = value;
  17886. }
  17887. applyMatrix4(m) {
  17888. for (let i = 0, l = this.data.count; i < l; i++) {
  17889. _vector$6.fromBufferAttribute(this, i);
  17890. _vector$6.applyMatrix4(m);
  17891. this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z);
  17892. }
  17893. return this;
  17894. }
  17895. applyNormalMatrix(m) {
  17896. for (let i = 0, l = this.count; i < l; i++) {
  17897. _vector$6.fromBufferAttribute(this, i);
  17898. _vector$6.applyNormalMatrix(m);
  17899. this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z);
  17900. }
  17901. return this;
  17902. }
  17903. transformDirection(m) {
  17904. for (let i = 0, l = this.count; i < l; i++) {
  17905. _vector$6.fromBufferAttribute(this, i);
  17906. _vector$6.transformDirection(m);
  17907. this.setXYZ(i, _vector$6.x, _vector$6.y, _vector$6.z);
  17908. }
  17909. return this;
  17910. }
  17911. setX(index, x) {
  17912. this.data.array[index * this.data.stride + this.offset] = x;
  17913. return this;
  17914. }
  17915. setY(index, y) {
  17916. this.data.array[index * this.data.stride + this.offset + 1] = y;
  17917. return this;
  17918. }
  17919. setZ(index, z) {
  17920. this.data.array[index * this.data.stride + this.offset + 2] = z;
  17921. return this;
  17922. }
  17923. setW(index, w) {
  17924. this.data.array[index * this.data.stride + this.offset + 3] = w;
  17925. return this;
  17926. }
  17927. getX(index) {
  17928. return this.data.array[index * this.data.stride + this.offset];
  17929. }
  17930. getY(index) {
  17931. return this.data.array[index * this.data.stride + this.offset + 1];
  17932. }
  17933. getZ(index) {
  17934. return this.data.array[index * this.data.stride + this.offset + 2];
  17935. }
  17936. getW(index) {
  17937. return this.data.array[index * this.data.stride + this.offset + 3];
  17938. }
  17939. setXY(index, x, y) {
  17940. index = index * this.data.stride + this.offset;
  17941. this.data.array[index + 0] = x;
  17942. this.data.array[index + 1] = y;
  17943. return this;
  17944. }
  17945. setXYZ(index, x, y, z) {
  17946. index = index * this.data.stride + this.offset;
  17947. this.data.array[index + 0] = x;
  17948. this.data.array[index + 1] = y;
  17949. this.data.array[index + 2] = z;
  17950. return this;
  17951. }
  17952. setXYZW(index, x, y, z, w) {
  17953. index = index * this.data.stride + this.offset;
  17954. this.data.array[index + 0] = x;
  17955. this.data.array[index + 1] = y;
  17956. this.data.array[index + 2] = z;
  17957. this.data.array[index + 3] = w;
  17958. return this;
  17959. }
  17960. clone(data) {
  17961. if (data === undefined) {
  17962. console.log('THREE.InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will deinterleave buffer data.');
  17963. const array = [];
  17964. for (let i = 0; i < this.count; i++) {
  17965. const index = i * this.data.stride + this.offset;
  17966. for (let j = 0; j < this.itemSize; j++) {
  17967. array.push(this.data.array[index + j]);
  17968. }
  17969. }
  17970. return new BufferAttribute(new this.array.constructor(array), this.itemSize, this.normalized);
  17971. } else {
  17972. if (data.interleavedBuffers === undefined) {
  17973. data.interleavedBuffers = {};
  17974. }
  17975. if (data.interleavedBuffers[this.data.uuid] === undefined) {
  17976. data.interleavedBuffers[this.data.uuid] = this.data.clone(data);
  17977. }
  17978. return new InterleavedBufferAttribute(data.interleavedBuffers[this.data.uuid], this.itemSize, this.offset, this.normalized);
  17979. }
  17980. }
  17981. toJSON(data) {
  17982. if (data === undefined) {
  17983. console.log('THREE.InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will deinterleave buffer data.');
  17984. const array = [];
  17985. for (let i = 0; i < this.count; i++) {
  17986. const index = i * this.data.stride + this.offset;
  17987. for (let j = 0; j < this.itemSize; j++) {
  17988. array.push(this.data.array[index + j]);
  17989. }
  17990. } // deinterleave data and save it as an ordinary buffer attribute for now
  17991. return {
  17992. itemSize: this.itemSize,
  17993. type: this.array.constructor.name,
  17994. array: array,
  17995. normalized: this.normalized
  17996. };
  17997. } else {
  17998. // save as true interleaved attribtue
  17999. if (data.interleavedBuffers === undefined) {
  18000. data.interleavedBuffers = {};
  18001. }
  18002. if (data.interleavedBuffers[this.data.uuid] === undefined) {
  18003. data.interleavedBuffers[this.data.uuid] = this.data.toJSON(data);
  18004. }
  18005. return {
  18006. isInterleavedBufferAttribute: true,
  18007. itemSize: this.itemSize,
  18008. data: this.data.uuid,
  18009. offset: this.offset,
  18010. normalized: this.normalized
  18011. };
  18012. }
  18013. }
  18014. }
  18015. class SpriteMaterial extends Material {
  18016. constructor(parameters) {
  18017. super();
  18018. this.isSpriteMaterial = true;
  18019. this.type = 'SpriteMaterial';
  18020. this.color = new Color(0xffffff);
  18021. this.map = null;
  18022. this.alphaMap = null;
  18023. this.rotation = 0;
  18024. this.sizeAttenuation = true;
  18025. this.transparent = true;
  18026. this.fog = true;
  18027. this.setValues(parameters);
  18028. }
  18029. copy(source) {
  18030. super.copy(source);
  18031. this.color.copy(source.color);
  18032. this.map = source.map;
  18033. this.alphaMap = source.alphaMap;
  18034. this.rotation = source.rotation;
  18035. this.sizeAttenuation = source.sizeAttenuation;
  18036. this.fog = source.fog;
  18037. return this;
  18038. }
  18039. }
  18040. let _geometry;
  18041. const _intersectPoint = /*@__PURE__*/new Vector3();
  18042. const _worldScale = /*@__PURE__*/new Vector3();
  18043. const _mvPosition = /*@__PURE__*/new Vector3();
  18044. const _alignedPosition = /*@__PURE__*/new Vector2();
  18045. const _rotatedPosition = /*@__PURE__*/new Vector2();
  18046. const _viewWorldMatrix = /*@__PURE__*/new Matrix4();
  18047. const _vA = /*@__PURE__*/new Vector3();
  18048. const _vB = /*@__PURE__*/new Vector3();
  18049. const _vC = /*@__PURE__*/new Vector3();
  18050. const _uvA = /*@__PURE__*/new Vector2();
  18051. const _uvB = /*@__PURE__*/new Vector2();
  18052. const _uvC = /*@__PURE__*/new Vector2();
  18053. class Sprite extends Object3D {
  18054. constructor(material) {
  18055. super();
  18056. this.isSprite = true;
  18057. this.type = 'Sprite';
  18058. if (_geometry === undefined) {
  18059. _geometry = new BufferGeometry();
  18060. const float32Array = new Float32Array([-0.5, -0.5, 0, 0, 0, 0.5, -0.5, 0, 1, 0, 0.5, 0.5, 0, 1, 1, -0.5, 0.5, 0, 0, 1]);
  18061. const interleavedBuffer = new InterleavedBuffer(float32Array, 5);
  18062. _geometry.setIndex([0, 1, 2, 0, 2, 3]);
  18063. _geometry.setAttribute('position', new InterleavedBufferAttribute(interleavedBuffer, 3, 0, false));
  18064. _geometry.setAttribute('uv', new InterleavedBufferAttribute(interleavedBuffer, 2, 3, false));
  18065. }
  18066. this.geometry = _geometry;
  18067. this.material = material !== undefined ? material : new SpriteMaterial();
  18068. this.center = new Vector2(0.5, 0.5);
  18069. }
  18070. raycast(raycaster, intersects) {
  18071. if (raycaster.camera === null) {
  18072. console.error('THREE.Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.');
  18073. }
  18074. _worldScale.setFromMatrixScale(this.matrixWorld);
  18075. _viewWorldMatrix.copy(raycaster.camera.matrixWorld);
  18076. this.modelViewMatrix.multiplyMatrices(raycaster.camera.matrixWorldInverse, this.matrixWorld);
  18077. _mvPosition.setFromMatrixPosition(this.modelViewMatrix);
  18078. if (raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false) {
  18079. _worldScale.multiplyScalar(-_mvPosition.z);
  18080. }
  18081. const rotation = this.material.rotation;
  18082. let sin, cos;
  18083. if (rotation !== 0) {
  18084. cos = Math.cos(rotation);
  18085. sin = Math.sin(rotation);
  18086. }
  18087. const center = this.center;
  18088. transformVertex(_vA.set(-0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos);
  18089. transformVertex(_vB.set(0.5, -0.5, 0), _mvPosition, center, _worldScale, sin, cos);
  18090. transformVertex(_vC.set(0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos);
  18091. _uvA.set(0, 0);
  18092. _uvB.set(1, 0);
  18093. _uvC.set(1, 1); // check first triangle
  18094. let intersect = raycaster.ray.intersectTriangle(_vA, _vB, _vC, false, _intersectPoint);
  18095. if (intersect === null) {
  18096. // check second triangle
  18097. transformVertex(_vB.set(-0.5, 0.5, 0), _mvPosition, center, _worldScale, sin, cos);
  18098. _uvB.set(0, 1);
  18099. intersect = raycaster.ray.intersectTriangle(_vA, _vC, _vB, false, _intersectPoint);
  18100. if (intersect === null) {
  18101. return;
  18102. }
  18103. }
  18104. const distance = raycaster.ray.origin.distanceTo(_intersectPoint);
  18105. if (distance < raycaster.near || distance > raycaster.far) return;
  18106. intersects.push({
  18107. distance: distance,
  18108. point: _intersectPoint.clone(),
  18109. uv: Triangle.getUV(_intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2()),
  18110. face: null,
  18111. object: this
  18112. });
  18113. }
  18114. copy(source, recursive) {
  18115. super.copy(source, recursive);
  18116. if (source.center !== undefined) this.center.copy(source.center);
  18117. this.material = source.material;
  18118. return this;
  18119. }
  18120. }
  18121. function transformVertex(vertexPosition, mvPosition, center, scale, sin, cos) {
  18122. // compute position in camera space
  18123. _alignedPosition.subVectors(vertexPosition, center).addScalar(0.5).multiply(scale); // to check if rotation is not zero
  18124. if (sin !== undefined) {
  18125. _rotatedPosition.x = cos * _alignedPosition.x - sin * _alignedPosition.y;
  18126. _rotatedPosition.y = sin * _alignedPosition.x + cos * _alignedPosition.y;
  18127. } else {
  18128. _rotatedPosition.copy(_alignedPosition);
  18129. }
  18130. vertexPosition.copy(mvPosition);
  18131. vertexPosition.x += _rotatedPosition.x;
  18132. vertexPosition.y += _rotatedPosition.y; // transform to world space
  18133. vertexPosition.applyMatrix4(_viewWorldMatrix);
  18134. }
  18135. const _v1$2 = /*@__PURE__*/new Vector3();
  18136. const _v2$1 = /*@__PURE__*/new Vector3();
  18137. class LOD extends Object3D {
  18138. constructor() {
  18139. super();
  18140. this._currentLevel = 0;
  18141. this.type = 'LOD';
  18142. Object.defineProperties(this, {
  18143. levels: {
  18144. enumerable: true,
  18145. value: []
  18146. },
  18147. isLOD: {
  18148. value: true
  18149. }
  18150. });
  18151. this.autoUpdate = true;
  18152. }
  18153. copy(source) {
  18154. super.copy(source, false);
  18155. const levels = source.levels;
  18156. for (let i = 0, l = levels.length; i < l; i++) {
  18157. const level = levels[i];
  18158. this.addLevel(level.object.clone(), level.distance);
  18159. }
  18160. this.autoUpdate = source.autoUpdate;
  18161. return this;
  18162. }
  18163. addLevel(object, distance = 0) {
  18164. distance = Math.abs(distance);
  18165. const levels = this.levels;
  18166. let l;
  18167. for (l = 0; l < levels.length; l++) {
  18168. if (distance < levels[l].distance) {
  18169. break;
  18170. }
  18171. }
  18172. levels.splice(l, 0, {
  18173. distance: distance,
  18174. object: object
  18175. });
  18176. this.add(object);
  18177. return this;
  18178. }
  18179. getCurrentLevel() {
  18180. return this._currentLevel;
  18181. }
  18182. getObjectForDistance(distance) {
  18183. const levels = this.levels;
  18184. if (levels.length > 0) {
  18185. let i, l;
  18186. for (i = 1, l = levels.length; i < l; i++) {
  18187. if (distance < levels[i].distance) {
  18188. break;
  18189. }
  18190. }
  18191. return levels[i - 1].object;
  18192. }
  18193. return null;
  18194. }
  18195. raycast(raycaster, intersects) {
  18196. const levels = this.levels;
  18197. if (levels.length > 0) {
  18198. _v1$2.setFromMatrixPosition(this.matrixWorld);
  18199. const distance = raycaster.ray.origin.distanceTo(_v1$2);
  18200. this.getObjectForDistance(distance).raycast(raycaster, intersects);
  18201. }
  18202. }
  18203. update(camera) {
  18204. const levels = this.levels;
  18205. if (levels.length > 1) {
  18206. _v1$2.setFromMatrixPosition(camera.matrixWorld);
  18207. _v2$1.setFromMatrixPosition(this.matrixWorld);
  18208. const distance = _v1$2.distanceTo(_v2$1) / camera.zoom;
  18209. levels[0].object.visible = true;
  18210. let i, l;
  18211. for (i = 1, l = levels.length; i < l; i++) {
  18212. if (distance >= levels[i].distance) {
  18213. levels[i - 1].object.visible = false;
  18214. levels[i].object.visible = true;
  18215. } else {
  18216. break;
  18217. }
  18218. }
  18219. this._currentLevel = i - 1;
  18220. for (; i < l; i++) {
  18221. levels[i].object.visible = false;
  18222. }
  18223. }
  18224. }
  18225. toJSON(meta) {
  18226. const data = super.toJSON(meta);
  18227. if (this.autoUpdate === false) data.object.autoUpdate = false;
  18228. data.object.levels = [];
  18229. const levels = this.levels;
  18230. for (let i = 0, l = levels.length; i < l; i++) {
  18231. const level = levels[i];
  18232. data.object.levels.push({
  18233. object: level.object.uuid,
  18234. distance: level.distance
  18235. });
  18236. }
  18237. return data;
  18238. }
  18239. }
  18240. const _basePosition = /*@__PURE__*/new Vector3();
  18241. const _skinIndex = /*@__PURE__*/new Vector4();
  18242. const _skinWeight = /*@__PURE__*/new Vector4();
  18243. const _vector$5 = /*@__PURE__*/new Vector3();
  18244. const _matrix = /*@__PURE__*/new Matrix4();
  18245. class SkinnedMesh extends Mesh {
  18246. constructor(geometry, material) {
  18247. super(geometry, material);
  18248. this.isSkinnedMesh = true;
  18249. this.type = 'SkinnedMesh';
  18250. this.bindMode = 'attached';
  18251. this.bindMatrix = new Matrix4();
  18252. this.bindMatrixInverse = new Matrix4();
  18253. }
  18254. copy(source, recursive) {
  18255. super.copy(source, recursive);
  18256. this.bindMode = source.bindMode;
  18257. this.bindMatrix.copy(source.bindMatrix);
  18258. this.bindMatrixInverse.copy(source.bindMatrixInverse);
  18259. this.skeleton = source.skeleton;
  18260. return this;
  18261. }
  18262. bind(skeleton, bindMatrix) {
  18263. this.skeleton = skeleton;
  18264. if (bindMatrix === undefined) {
  18265. this.updateMatrixWorld(true);
  18266. this.skeleton.calculateInverses();
  18267. bindMatrix = this.matrixWorld;
  18268. }
  18269. this.bindMatrix.copy(bindMatrix);
  18270. this.bindMatrixInverse.copy(bindMatrix).invert();
  18271. }
  18272. pose() {
  18273. this.skeleton.pose();
  18274. }
  18275. normalizeSkinWeights() {
  18276. const vector = new Vector4();
  18277. const skinWeight = this.geometry.attributes.skinWeight;
  18278. for (let i = 0, l = skinWeight.count; i < l; i++) {
  18279. vector.fromBufferAttribute(skinWeight, i);
  18280. const scale = 1.0 / vector.manhattanLength();
  18281. if (scale !== Infinity) {
  18282. vector.multiplyScalar(scale);
  18283. } else {
  18284. vector.set(1, 0, 0, 0); // do something reasonable
  18285. }
  18286. skinWeight.setXYZW(i, vector.x, vector.y, vector.z, vector.w);
  18287. }
  18288. }
  18289. updateMatrixWorld(force) {
  18290. super.updateMatrixWorld(force);
  18291. if (this.bindMode === 'attached') {
  18292. this.bindMatrixInverse.copy(this.matrixWorld).invert();
  18293. } else if (this.bindMode === 'detached') {
  18294. this.bindMatrixInverse.copy(this.bindMatrix).invert();
  18295. } else {
  18296. console.warn('THREE.SkinnedMesh: Unrecognized bindMode: ' + this.bindMode);
  18297. }
  18298. }
  18299. boneTransform(index, target) {
  18300. const skeleton = this.skeleton;
  18301. const geometry = this.geometry;
  18302. _skinIndex.fromBufferAttribute(geometry.attributes.skinIndex, index);
  18303. _skinWeight.fromBufferAttribute(geometry.attributes.skinWeight, index);
  18304. _basePosition.copy(target).applyMatrix4(this.bindMatrix);
  18305. target.set(0, 0, 0);
  18306. for (let i = 0; i < 4; i++) {
  18307. const weight = _skinWeight.getComponent(i);
  18308. if (weight !== 0) {
  18309. const boneIndex = _skinIndex.getComponent(i);
  18310. _matrix.multiplyMatrices(skeleton.bones[boneIndex].matrixWorld, skeleton.boneInverses[boneIndex]);
  18311. target.addScaledVector(_vector$5.copy(_basePosition).applyMatrix4(_matrix), weight);
  18312. }
  18313. }
  18314. return target.applyMatrix4(this.bindMatrixInverse);
  18315. }
  18316. }
  18317. class Bone extends Object3D {
  18318. constructor() {
  18319. super();
  18320. this.isBone = true;
  18321. this.type = 'Bone';
  18322. }
  18323. }
  18324. class DataTexture extends Texture {
  18325. constructor(data = null, width = 1, height = 1, format, type, mapping, wrapS, wrapT, magFilter = NearestFilter, minFilter = NearestFilter, anisotropy, encoding) {
  18326. super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
  18327. this.isDataTexture = true;
  18328. this.image = {
  18329. data: data,
  18330. width: width,
  18331. height: height
  18332. };
  18333. this.generateMipmaps = false;
  18334. this.flipY = false;
  18335. this.unpackAlignment = 1;
  18336. }
  18337. }
  18338. const _offsetMatrix = /*@__PURE__*/new Matrix4();
  18339. const _identityMatrix = /*@__PURE__*/new Matrix4();
  18340. class Skeleton {
  18341. constructor(bones = [], boneInverses = []) {
  18342. this.uuid = generateUUID();
  18343. this.bones = bones.slice(0);
  18344. this.boneInverses = boneInverses;
  18345. this.boneMatrices = null;
  18346. this.boneTexture = null;
  18347. this.boneTextureSize = 0;
  18348. this.frame = -1;
  18349. this.init();
  18350. }
  18351. init() {
  18352. const bones = this.bones;
  18353. const boneInverses = this.boneInverses;
  18354. this.boneMatrices = new Float32Array(bones.length * 16); // calculate inverse bone matrices if necessary
  18355. if (boneInverses.length === 0) {
  18356. this.calculateInverses();
  18357. } else {
  18358. // handle special case
  18359. if (bones.length !== boneInverses.length) {
  18360. console.warn('THREE.Skeleton: Number of inverse bone matrices does not match amount of bones.');
  18361. this.boneInverses = [];
  18362. for (let i = 0, il = this.bones.length; i < il; i++) {
  18363. this.boneInverses.push(new Matrix4());
  18364. }
  18365. }
  18366. }
  18367. }
  18368. calculateInverses() {
  18369. this.boneInverses.length = 0;
  18370. for (let i = 0, il = this.bones.length; i < il; i++) {
  18371. const inverse = new Matrix4();
  18372. if (this.bones[i]) {
  18373. inverse.copy(this.bones[i].matrixWorld).invert();
  18374. }
  18375. this.boneInverses.push(inverse);
  18376. }
  18377. }
  18378. pose() {
  18379. // recover the bind-time world matrices
  18380. for (let i = 0, il = this.bones.length; i < il; i++) {
  18381. const bone = this.bones[i];
  18382. if (bone) {
  18383. bone.matrixWorld.copy(this.boneInverses[i]).invert();
  18384. }
  18385. } // compute the local matrices, positions, rotations and scales
  18386. for (let i = 0, il = this.bones.length; i < il; i++) {
  18387. const bone = this.bones[i];
  18388. if (bone) {
  18389. if (bone.parent && bone.parent.isBone) {
  18390. bone.matrix.copy(bone.parent.matrixWorld).invert();
  18391. bone.matrix.multiply(bone.matrixWorld);
  18392. } else {
  18393. bone.matrix.copy(bone.matrixWorld);
  18394. }
  18395. bone.matrix.decompose(bone.position, bone.quaternion, bone.scale);
  18396. }
  18397. }
  18398. }
  18399. update() {
  18400. const bones = this.bones;
  18401. const boneInverses = this.boneInverses;
  18402. const boneMatrices = this.boneMatrices;
  18403. const boneTexture = this.boneTexture; // flatten bone matrices to array
  18404. for (let i = 0, il = bones.length; i < il; i++) {
  18405. // compute the offset between the current and the original transform
  18406. const matrix = bones[i] ? bones[i].matrixWorld : _identityMatrix;
  18407. _offsetMatrix.multiplyMatrices(matrix, boneInverses[i]);
  18408. _offsetMatrix.toArray(boneMatrices, i * 16);
  18409. }
  18410. if (boneTexture !== null) {
  18411. boneTexture.needsUpdate = true;
  18412. }
  18413. }
  18414. clone() {
  18415. return new Skeleton(this.bones, this.boneInverses);
  18416. }
  18417. computeBoneTexture() {
  18418. // layout (1 matrix = 4 pixels)
  18419. // RGBA RGBA RGBA RGBA (=> column1, column2, column3, column4)
  18420. // with 8x8 pixel texture max 16 bones * 4 pixels = (8 * 8)
  18421. // 16x16 pixel texture max 64 bones * 4 pixels = (16 * 16)
  18422. // 32x32 pixel texture max 256 bones * 4 pixels = (32 * 32)
  18423. // 64x64 pixel texture max 1024 bones * 4 pixels = (64 * 64)
  18424. let size = Math.sqrt(this.bones.length * 4); // 4 pixels needed for 1 matrix
  18425. size = ceilPowerOfTwo(size);
  18426. size = Math.max(size, 4);
  18427. const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
  18428. boneMatrices.set(this.boneMatrices); // copy current values
  18429. const boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType);
  18430. boneTexture.needsUpdate = true;
  18431. this.boneMatrices = boneMatrices;
  18432. this.boneTexture = boneTexture;
  18433. this.boneTextureSize = size;
  18434. return this;
  18435. }
  18436. getBoneByName(name) {
  18437. for (let i = 0, il = this.bones.length; i < il; i++) {
  18438. const bone = this.bones[i];
  18439. if (bone.name === name) {
  18440. return bone;
  18441. }
  18442. }
  18443. return undefined;
  18444. }
  18445. dispose() {
  18446. if (this.boneTexture !== null) {
  18447. this.boneTexture.dispose();
  18448. this.boneTexture = null;
  18449. }
  18450. }
  18451. fromJSON(json, bones) {
  18452. this.uuid = json.uuid;
  18453. for (let i = 0, l = json.bones.length; i < l; i++) {
  18454. const uuid = json.bones[i];
  18455. let bone = bones[uuid];
  18456. if (bone === undefined) {
  18457. console.warn('THREE.Skeleton: No bone found with UUID:', uuid);
  18458. bone = new Bone();
  18459. }
  18460. this.bones.push(bone);
  18461. this.boneInverses.push(new Matrix4().fromArray(json.boneInverses[i]));
  18462. }
  18463. this.init();
  18464. return this;
  18465. }
  18466. toJSON() {
  18467. const data = {
  18468. metadata: {
  18469. version: 4.5,
  18470. type: 'Skeleton',
  18471. generator: 'Skeleton.toJSON'
  18472. },
  18473. bones: [],
  18474. boneInverses: []
  18475. };
  18476. data.uuid = this.uuid;
  18477. const bones = this.bones;
  18478. const boneInverses = this.boneInverses;
  18479. for (let i = 0, l = bones.length; i < l; i++) {
  18480. const bone = bones[i];
  18481. data.bones.push(bone.uuid);
  18482. const boneInverse = boneInverses[i];
  18483. data.boneInverses.push(boneInverse.toArray());
  18484. }
  18485. return data;
  18486. }
  18487. }
  18488. class InstancedBufferAttribute extends BufferAttribute {
  18489. constructor(array, itemSize, normalized, meshPerAttribute = 1) {
  18490. if (typeof normalized === 'number') {
  18491. meshPerAttribute = normalized;
  18492. normalized = false;
  18493. console.error('THREE.InstancedBufferAttribute: The constructor now expects normalized as the third argument.');
  18494. }
  18495. super(array, itemSize, normalized);
  18496. this.isInstancedBufferAttribute = true;
  18497. this.meshPerAttribute = meshPerAttribute;
  18498. }
  18499. copy(source) {
  18500. super.copy(source);
  18501. this.meshPerAttribute = source.meshPerAttribute;
  18502. return this;
  18503. }
  18504. toJSON() {
  18505. const data = super.toJSON();
  18506. data.meshPerAttribute = this.meshPerAttribute;
  18507. data.isInstancedBufferAttribute = true;
  18508. return data;
  18509. }
  18510. }
  18511. const _instanceLocalMatrix = /*@__PURE__*/new Matrix4();
  18512. const _instanceWorldMatrix = /*@__PURE__*/new Matrix4();
  18513. const _instanceIntersects = [];
  18514. const _mesh = /*@__PURE__*/new Mesh();
  18515. class InstancedMesh extends Mesh {
  18516. constructor(geometry, material, count) {
  18517. super(geometry, material);
  18518. this.isInstancedMesh = true;
  18519. this.instanceMatrix = new InstancedBufferAttribute(new Float32Array(count * 16), 16);
  18520. this.instanceColor = null;
  18521. this.count = count;
  18522. this.frustumCulled = false;
  18523. }
  18524. copy(source, recursive) {
  18525. super.copy(source, recursive);
  18526. this.instanceMatrix.copy(source.instanceMatrix);
  18527. if (source.instanceColor !== null) this.instanceColor = source.instanceColor.clone();
  18528. this.count = source.count;
  18529. return this;
  18530. }
  18531. getColorAt(index, color) {
  18532. color.fromArray(this.instanceColor.array, index * 3);
  18533. }
  18534. getMatrixAt(index, matrix) {
  18535. matrix.fromArray(this.instanceMatrix.array, index * 16);
  18536. }
  18537. raycast(raycaster, intersects) {
  18538. const matrixWorld = this.matrixWorld;
  18539. const raycastTimes = this.count;
  18540. _mesh.geometry = this.geometry;
  18541. _mesh.material = this.material;
  18542. if (_mesh.material === undefined) return;
  18543. for (let instanceId = 0; instanceId < raycastTimes; instanceId++) {
  18544. // calculate the world matrix for each instance
  18545. this.getMatrixAt(instanceId, _instanceLocalMatrix);
  18546. _instanceWorldMatrix.multiplyMatrices(matrixWorld, _instanceLocalMatrix); // the mesh represents this single instance
  18547. _mesh.matrixWorld = _instanceWorldMatrix;
  18548. _mesh.raycast(raycaster, _instanceIntersects); // process the result of raycast
  18549. for (let i = 0, l = _instanceIntersects.length; i < l; i++) {
  18550. const intersect = _instanceIntersects[i];
  18551. intersect.instanceId = instanceId;
  18552. intersect.object = this;
  18553. intersects.push(intersect);
  18554. }
  18555. _instanceIntersects.length = 0;
  18556. }
  18557. }
  18558. setColorAt(index, color) {
  18559. if (this.instanceColor === null) {
  18560. this.instanceColor = new InstancedBufferAttribute(new Float32Array(this.instanceMatrix.count * 3), 3);
  18561. }
  18562. color.toArray(this.instanceColor.array, index * 3);
  18563. }
  18564. setMatrixAt(index, matrix) {
  18565. matrix.toArray(this.instanceMatrix.array, index * 16);
  18566. }
  18567. updateMorphTargets() {}
  18568. dispose() {
  18569. this.dispatchEvent({
  18570. type: 'dispose'
  18571. });
  18572. }
  18573. }
  18574. class LineBasicMaterial extends Material {
  18575. constructor(parameters) {
  18576. super();
  18577. this.isLineBasicMaterial = true;
  18578. this.type = 'LineBasicMaterial';
  18579. this.color = new Color(0xffffff);
  18580. this.linewidth = 1;
  18581. this.linecap = 'round';
  18582. this.linejoin = 'round';
  18583. this.fog = true;
  18584. this.setValues(parameters);
  18585. }
  18586. copy(source) {
  18587. super.copy(source);
  18588. this.color.copy(source.color);
  18589. this.linewidth = source.linewidth;
  18590. this.linecap = source.linecap;
  18591. this.linejoin = source.linejoin;
  18592. this.fog = source.fog;
  18593. return this;
  18594. }
  18595. }
  18596. const _start$1 = /*@__PURE__*/new Vector3();
  18597. const _end$1 = /*@__PURE__*/new Vector3();
  18598. const _inverseMatrix$1 = /*@__PURE__*/new Matrix4();
  18599. const _ray$1 = /*@__PURE__*/new Ray();
  18600. const _sphere$1 = /*@__PURE__*/new Sphere();
  18601. class Line extends Object3D {
  18602. constructor(geometry = new BufferGeometry(), material = new LineBasicMaterial()) {
  18603. super();
  18604. this.isLine = true;
  18605. this.type = 'Line';
  18606. this.geometry = geometry;
  18607. this.material = material;
  18608. this.updateMorphTargets();
  18609. }
  18610. copy(source, recursive) {
  18611. super.copy(source, recursive);
  18612. this.material = source.material;
  18613. this.geometry = source.geometry;
  18614. return this;
  18615. }
  18616. computeLineDistances() {
  18617. const geometry = this.geometry; // we assume non-indexed geometry
  18618. if (geometry.index === null) {
  18619. const positionAttribute = geometry.attributes.position;
  18620. const lineDistances = [0];
  18621. for (let i = 1, l = positionAttribute.count; i < l; i++) {
  18622. _start$1.fromBufferAttribute(positionAttribute, i - 1);
  18623. _end$1.fromBufferAttribute(positionAttribute, i);
  18624. lineDistances[i] = lineDistances[i - 1];
  18625. lineDistances[i] += _start$1.distanceTo(_end$1);
  18626. }
  18627. geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1));
  18628. } else {
  18629. console.warn('THREE.Line.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.');
  18630. }
  18631. return this;
  18632. }
  18633. raycast(raycaster, intersects) {
  18634. const geometry = this.geometry;
  18635. const matrixWorld = this.matrixWorld;
  18636. const threshold = raycaster.params.Line.threshold;
  18637. const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray
  18638. if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
  18639. _sphere$1.copy(geometry.boundingSphere);
  18640. _sphere$1.applyMatrix4(matrixWorld);
  18641. _sphere$1.radius += threshold;
  18642. if (raycaster.ray.intersectsSphere(_sphere$1) === false) return; //
  18643. _inverseMatrix$1.copy(matrixWorld).invert();
  18644. _ray$1.copy(raycaster.ray).applyMatrix4(_inverseMatrix$1);
  18645. const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3);
  18646. const localThresholdSq = localThreshold * localThreshold;
  18647. const vStart = new Vector3();
  18648. const vEnd = new Vector3();
  18649. const interSegment = new Vector3();
  18650. const interRay = new Vector3();
  18651. const step = this.isLineSegments ? 2 : 1;
  18652. const index = geometry.index;
  18653. const attributes = geometry.attributes;
  18654. const positionAttribute = attributes.position;
  18655. if (index !== null) {
  18656. const start = Math.max(0, drawRange.start);
  18657. const end = Math.min(index.count, drawRange.start + drawRange.count);
  18658. for (let i = start, l = end - 1; i < l; i += step) {
  18659. const a = index.getX(i);
  18660. const b = index.getX(i + 1);
  18661. vStart.fromBufferAttribute(positionAttribute, a);
  18662. vEnd.fromBufferAttribute(positionAttribute, b);
  18663. const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment);
  18664. if (distSq > localThresholdSq) continue;
  18665. interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation
  18666. const distance = raycaster.ray.origin.distanceTo(interRay);
  18667. if (distance < raycaster.near || distance > raycaster.far) continue;
  18668. intersects.push({
  18669. distance: distance,
  18670. // What do we want? intersection point on the ray or on the segment??
  18671. // point: raycaster.ray.at( distance ),
  18672. point: interSegment.clone().applyMatrix4(this.matrixWorld),
  18673. index: i,
  18674. face: null,
  18675. faceIndex: null,
  18676. object: this
  18677. });
  18678. }
  18679. } else {
  18680. const start = Math.max(0, drawRange.start);
  18681. const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count);
  18682. for (let i = start, l = end - 1; i < l; i += step) {
  18683. vStart.fromBufferAttribute(positionAttribute, i);
  18684. vEnd.fromBufferAttribute(positionAttribute, i + 1);
  18685. const distSq = _ray$1.distanceSqToSegment(vStart, vEnd, interRay, interSegment);
  18686. if (distSq > localThresholdSq) continue;
  18687. interRay.applyMatrix4(this.matrixWorld); //Move back to world space for distance calculation
  18688. const distance = raycaster.ray.origin.distanceTo(interRay);
  18689. if (distance < raycaster.near || distance > raycaster.far) continue;
  18690. intersects.push({
  18691. distance: distance,
  18692. // What do we want? intersection point on the ray or on the segment??
  18693. // point: raycaster.ray.at( distance ),
  18694. point: interSegment.clone().applyMatrix4(this.matrixWorld),
  18695. index: i,
  18696. face: null,
  18697. faceIndex: null,
  18698. object: this
  18699. });
  18700. }
  18701. }
  18702. }
  18703. updateMorphTargets() {
  18704. const geometry = this.geometry;
  18705. const morphAttributes = geometry.morphAttributes;
  18706. const keys = Object.keys(morphAttributes);
  18707. if (keys.length > 0) {
  18708. const morphAttribute = morphAttributes[keys[0]];
  18709. if (morphAttribute !== undefined) {
  18710. this.morphTargetInfluences = [];
  18711. this.morphTargetDictionary = {};
  18712. for (let m = 0, ml = morphAttribute.length; m < ml; m++) {
  18713. const name = morphAttribute[m].name || String(m);
  18714. this.morphTargetInfluences.push(0);
  18715. this.morphTargetDictionary[name] = m;
  18716. }
  18717. }
  18718. }
  18719. }
  18720. }
  18721. const _start = /*@__PURE__*/new Vector3();
  18722. const _end = /*@__PURE__*/new Vector3();
  18723. class LineSegments extends Line {
  18724. constructor(geometry, material) {
  18725. super(geometry, material);
  18726. this.isLineSegments = true;
  18727. this.type = 'LineSegments';
  18728. }
  18729. computeLineDistances() {
  18730. const geometry = this.geometry; // we assume non-indexed geometry
  18731. if (geometry.index === null) {
  18732. const positionAttribute = geometry.attributes.position;
  18733. const lineDistances = [];
  18734. for (let i = 0, l = positionAttribute.count; i < l; i += 2) {
  18735. _start.fromBufferAttribute(positionAttribute, i);
  18736. _end.fromBufferAttribute(positionAttribute, i + 1);
  18737. lineDistances[i] = i === 0 ? 0 : lineDistances[i - 1];
  18738. lineDistances[i + 1] = lineDistances[i] + _start.distanceTo(_end);
  18739. }
  18740. geometry.setAttribute('lineDistance', new Float32BufferAttribute(lineDistances, 1));
  18741. } else {
  18742. console.warn('THREE.LineSegments.computeLineDistances(): Computation only possible with non-indexed BufferGeometry.');
  18743. }
  18744. return this;
  18745. }
  18746. }
  18747. class LineLoop extends Line {
  18748. constructor(geometry, material) {
  18749. super(geometry, material);
  18750. this.isLineLoop = true;
  18751. this.type = 'LineLoop';
  18752. }
  18753. }
  18754. class PointsMaterial extends Material {
  18755. constructor(parameters) {
  18756. super();
  18757. this.isPointsMaterial = true;
  18758. this.type = 'PointsMaterial';
  18759. this.color = new Color(0xffffff);
  18760. this.map = null;
  18761. this.alphaMap = null;
  18762. this.size = 1;
  18763. this.sizeAttenuation = true;
  18764. this.fog = true;
  18765. this.setValues(parameters);
  18766. }
  18767. copy(source) {
  18768. super.copy(source);
  18769. this.color.copy(source.color);
  18770. this.map = source.map;
  18771. this.alphaMap = source.alphaMap;
  18772. this.size = source.size;
  18773. this.sizeAttenuation = source.sizeAttenuation;
  18774. this.fog = source.fog;
  18775. return this;
  18776. }
  18777. }
  18778. const _inverseMatrix = /*@__PURE__*/new Matrix4();
  18779. const _ray = /*@__PURE__*/new Ray();
  18780. const _sphere = /*@__PURE__*/new Sphere();
  18781. const _position$2 = /*@__PURE__*/new Vector3();
  18782. class Points extends Object3D {
  18783. constructor(geometry = new BufferGeometry(), material = new PointsMaterial()) {
  18784. super();
  18785. this.isPoints = true;
  18786. this.type = 'Points';
  18787. this.geometry = geometry;
  18788. this.material = material;
  18789. this.updateMorphTargets();
  18790. }
  18791. copy(source, recursive) {
  18792. super.copy(source, recursive);
  18793. this.material = source.material;
  18794. this.geometry = source.geometry;
  18795. return this;
  18796. }
  18797. raycast(raycaster, intersects) {
  18798. const geometry = this.geometry;
  18799. const matrixWorld = this.matrixWorld;
  18800. const threshold = raycaster.params.Points.threshold;
  18801. const drawRange = geometry.drawRange; // Checking boundingSphere distance to ray
  18802. if (geometry.boundingSphere === null) geometry.computeBoundingSphere();
  18803. _sphere.copy(geometry.boundingSphere);
  18804. _sphere.applyMatrix4(matrixWorld);
  18805. _sphere.radius += threshold;
  18806. if (raycaster.ray.intersectsSphere(_sphere) === false) return; //
  18807. _inverseMatrix.copy(matrixWorld).invert();
  18808. _ray.copy(raycaster.ray).applyMatrix4(_inverseMatrix);
  18809. const localThreshold = threshold / ((this.scale.x + this.scale.y + this.scale.z) / 3);
  18810. const localThresholdSq = localThreshold * localThreshold;
  18811. const index = geometry.index;
  18812. const attributes = geometry.attributes;
  18813. const positionAttribute = attributes.position;
  18814. if (index !== null) {
  18815. const start = Math.max(0, drawRange.start);
  18816. const end = Math.min(index.count, drawRange.start + drawRange.count);
  18817. for (let i = start, il = end; i < il; i++) {
  18818. const a = index.getX(i);
  18819. _position$2.fromBufferAttribute(positionAttribute, a);
  18820. testPoint(_position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this);
  18821. }
  18822. } else {
  18823. const start = Math.max(0, drawRange.start);
  18824. const end = Math.min(positionAttribute.count, drawRange.start + drawRange.count);
  18825. for (let i = start, l = end; i < l; i++) {
  18826. _position$2.fromBufferAttribute(positionAttribute, i);
  18827. testPoint(_position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this);
  18828. }
  18829. }
  18830. }
  18831. updateMorphTargets() {
  18832. const geometry = this.geometry;
  18833. const morphAttributes = geometry.morphAttributes;
  18834. const keys = Object.keys(morphAttributes);
  18835. if (keys.length > 0) {
  18836. const morphAttribute = morphAttributes[keys[0]];
  18837. if (morphAttribute !== undefined) {
  18838. this.morphTargetInfluences = [];
  18839. this.morphTargetDictionary = {};
  18840. for (let m = 0, ml = morphAttribute.length; m < ml; m++) {
  18841. const name = morphAttribute[m].name || String(m);
  18842. this.morphTargetInfluences.push(0);
  18843. this.morphTargetDictionary[name] = m;
  18844. }
  18845. }
  18846. }
  18847. }
  18848. }
  18849. function testPoint(point, index, localThresholdSq, matrixWorld, raycaster, intersects, object) {
  18850. const rayPointDistanceSq = _ray.distanceSqToPoint(point);
  18851. if (rayPointDistanceSq < localThresholdSq) {
  18852. const intersectPoint = new Vector3();
  18853. _ray.closestPointToPoint(point, intersectPoint);
  18854. intersectPoint.applyMatrix4(matrixWorld);
  18855. const distance = raycaster.ray.origin.distanceTo(intersectPoint);
  18856. if (distance < raycaster.near || distance > raycaster.far) return;
  18857. intersects.push({
  18858. distance: distance,
  18859. distanceToRay: Math.sqrt(rayPointDistanceSq),
  18860. point: intersectPoint,
  18861. index: index,
  18862. face: null,
  18863. object: object
  18864. });
  18865. }
  18866. }
  18867. class VideoTexture extends Texture {
  18868. constructor(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) {
  18869. super(video, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
  18870. this.isVideoTexture = true;
  18871. this.minFilter = minFilter !== undefined ? minFilter : LinearFilter;
  18872. this.magFilter = magFilter !== undefined ? magFilter : LinearFilter;
  18873. this.generateMipmaps = false;
  18874. const scope = this;
  18875. function updateVideo() {
  18876. scope.needsUpdate = true;
  18877. video.requestVideoFrameCallback(updateVideo);
  18878. }
  18879. if ('requestVideoFrameCallback' in video) {
  18880. video.requestVideoFrameCallback(updateVideo);
  18881. }
  18882. }
  18883. clone() {
  18884. return new this.constructor(this.image).copy(this);
  18885. }
  18886. update() {
  18887. const video = this.image;
  18888. const hasVideoFrameCallback = ('requestVideoFrameCallback' in video);
  18889. if (hasVideoFrameCallback === false && video.readyState >= video.HAVE_CURRENT_DATA) {
  18890. this.needsUpdate = true;
  18891. }
  18892. }
  18893. }
  18894. class FramebufferTexture extends Texture {
  18895. constructor(width, height, format) {
  18896. super({
  18897. width,
  18898. height
  18899. });
  18900. this.isFramebufferTexture = true;
  18901. this.format = format;
  18902. this.magFilter = NearestFilter;
  18903. this.minFilter = NearestFilter;
  18904. this.generateMipmaps = false;
  18905. this.needsUpdate = true;
  18906. }
  18907. }
  18908. class CompressedTexture extends Texture {
  18909. constructor(mipmaps, width, height, format, type, mapping, wrapS, wrapT, magFilter, minFilter, anisotropy, encoding) {
  18910. super(null, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, encoding);
  18911. this.isCompressedTexture = true;
  18912. this.image = {
  18913. width: width,
  18914. height: height
  18915. };
  18916. this.mipmaps = mipmaps; // no flipping for cube textures
  18917. // (also flipping doesn't work for compressed textures )
  18918. this.flipY = false; // can't generate mipmaps for compressed textures
  18919. // mips must be embedded in DDS files
  18920. this.generateMipmaps = false;
  18921. }
  18922. }
  18923. class CanvasTexture extends Texture {
  18924. constructor(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy) {
  18925. super(canvas, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy);
  18926. this.isCanvasTexture = true;
  18927. this.needsUpdate = true;
  18928. }
  18929. }
  18930. /**
  18931. * Extensible curve object.
  18932. *
  18933. * Some common of curve methods:
  18934. * .getPoint( t, optionalTarget ), .getTangent( t, optionalTarget )
  18935. * .getPointAt( u, optionalTarget ), .getTangentAt( u, optionalTarget )
  18936. * .getPoints(), .getSpacedPoints()
  18937. * .getLength()
  18938. * .updateArcLengths()
  18939. *
  18940. * This following curves inherit from THREE.Curve:
  18941. *
  18942. * -- 2D curves --
  18943. * THREE.ArcCurve
  18944. * THREE.CubicBezierCurve
  18945. * THREE.EllipseCurve
  18946. * THREE.LineCurve
  18947. * THREE.QuadraticBezierCurve
  18948. * THREE.SplineCurve
  18949. *
  18950. * -- 3D curves --
  18951. * THREE.CatmullRomCurve3
  18952. * THREE.CubicBezierCurve3
  18953. * THREE.LineCurve3
  18954. * THREE.QuadraticBezierCurve3
  18955. *
  18956. * A series of curves can be represented as a THREE.CurvePath.
  18957. *
  18958. **/
  18959. class Curve {
  18960. constructor() {
  18961. this.type = 'Curve';
  18962. this.arcLengthDivisions = 200;
  18963. } // Virtual base class method to overwrite and implement in subclasses
  18964. // - t [0 .. 1]
  18965. getPoint() {
  18966. console.warn('THREE.Curve: .getPoint() not implemented.');
  18967. return null;
  18968. } // Get point at relative position in curve according to arc length
  18969. // - u [0 .. 1]
  18970. getPointAt(u, optionalTarget) {
  18971. const t = this.getUtoTmapping(u);
  18972. return this.getPoint(t, optionalTarget);
  18973. } // Get sequence of points using getPoint( t )
  18974. getPoints(divisions = 5) {
  18975. const points = [];
  18976. for (let d = 0; d <= divisions; d++) {
  18977. points.push(this.getPoint(d / divisions));
  18978. }
  18979. return points;
  18980. } // Get sequence of points using getPointAt( u )
  18981. getSpacedPoints(divisions = 5) {
  18982. const points = [];
  18983. for (let d = 0; d <= divisions; d++) {
  18984. points.push(this.getPointAt(d / divisions));
  18985. }
  18986. return points;
  18987. } // Get total curve arc length
  18988. getLength() {
  18989. const lengths = this.getLengths();
  18990. return lengths[lengths.length - 1];
  18991. } // Get list of cumulative segment lengths
  18992. getLengths(divisions = this.arcLengthDivisions) {
  18993. if (this.cacheArcLengths && this.cacheArcLengths.length === divisions + 1 && !this.needsUpdate) {
  18994. return this.cacheArcLengths;
  18995. }
  18996. this.needsUpdate = false;
  18997. const cache = [];
  18998. let current,
  18999. last = this.getPoint(0);
  19000. let sum = 0;
  19001. cache.push(0);
  19002. for (let p = 1; p <= divisions; p++) {
  19003. current = this.getPoint(p / divisions);
  19004. sum += current.distanceTo(last);
  19005. cache.push(sum);
  19006. last = current;
  19007. }
  19008. this.cacheArcLengths = cache;
  19009. return cache; // { sums: cache, sum: sum }; Sum is in the last element.
  19010. }
  19011. updateArcLengths() {
  19012. this.needsUpdate = true;
  19013. this.getLengths();
  19014. } // Given u ( 0 .. 1 ), get a t to find p. This gives you points which are equidistant
  19015. getUtoTmapping(u, distance) {
  19016. const arcLengths = this.getLengths();
  19017. let i = 0;
  19018. const il = arcLengths.length;
  19019. let targetArcLength; // The targeted u distance value to get
  19020. if (distance) {
  19021. targetArcLength = distance;
  19022. } else {
  19023. targetArcLength = u * arcLengths[il - 1];
  19024. } // binary search for the index with largest value smaller than target u distance
  19025. let low = 0,
  19026. high = il - 1,
  19027. comparison;
  19028. while (low <= high) {
  19029. i = Math.floor(low + (high - low) / 2); // less likely to overflow, though probably not issue here, JS doesn't really have integers, all numbers are floats
  19030. comparison = arcLengths[i] - targetArcLength;
  19031. if (comparison < 0) {
  19032. low = i + 1;
  19033. } else if (comparison > 0) {
  19034. high = i - 1;
  19035. } else {
  19036. high = i;
  19037. break; // DONE
  19038. }
  19039. }
  19040. i = high;
  19041. if (arcLengths[i] === targetArcLength) {
  19042. return i / (il - 1);
  19043. } // we could get finer grain at lengths, or use simple interpolation between two points
  19044. const lengthBefore = arcLengths[i];
  19045. const lengthAfter = arcLengths[i + 1];
  19046. const segmentLength = lengthAfter - lengthBefore; // determine where we are between the 'before' and 'after' points
  19047. const segmentFraction = (targetArcLength - lengthBefore) / segmentLength; // add that fractional amount to t
  19048. const t = (i + segmentFraction) / (il - 1);
  19049. return t;
  19050. } // Returns a unit vector tangent at t
  19051. // In case any sub curve does not implement its tangent derivation,
  19052. // 2 points a small delta apart will be used to find its gradient
  19053. // which seems to give a reasonable approximation
  19054. getTangent(t, optionalTarget) {
  19055. const delta = 0.0001;
  19056. let t1 = t - delta;
  19057. let t2 = t + delta; // Capping in case of danger
  19058. if (t1 < 0) t1 = 0;
  19059. if (t2 > 1) t2 = 1;
  19060. const pt1 = this.getPoint(t1);
  19061. const pt2 = this.getPoint(t2);
  19062. const tangent = optionalTarget || (pt1.isVector2 ? new Vector2() : new Vector3());
  19063. tangent.copy(pt2).sub(pt1).normalize();
  19064. return tangent;
  19065. }
  19066. getTangentAt(u, optionalTarget) {
  19067. const t = this.getUtoTmapping(u);
  19068. return this.getTangent(t, optionalTarget);
  19069. }
  19070. computeFrenetFrames(segments, closed) {
  19071. // see http://www.cs.indiana.edu/pub/techreports/TR425.pdf
  19072. const normal = new Vector3();
  19073. const tangents = [];
  19074. const normals = [];
  19075. const binormals = [];
  19076. const vec = new Vector3();
  19077. const mat = new Matrix4(); // compute the tangent vectors for each segment on the curve
  19078. for (let i = 0; i <= segments; i++) {
  19079. const u = i / segments;
  19080. tangents[i] = this.getTangentAt(u, new Vector3());
  19081. } // select an initial normal vector perpendicular to the first tangent vector,
  19082. // and in the direction of the minimum tangent xyz component
  19083. normals[0] = new Vector3();
  19084. binormals[0] = new Vector3();
  19085. let min = Number.MAX_VALUE;
  19086. const tx = Math.abs(tangents[0].x);
  19087. const ty = Math.abs(tangents[0].y);
  19088. const tz = Math.abs(tangents[0].z);
  19089. if (tx <= min) {
  19090. min = tx;
  19091. normal.set(1, 0, 0);
  19092. }
  19093. if (ty <= min) {
  19094. min = ty;
  19095. normal.set(0, 1, 0);
  19096. }
  19097. if (tz <= min) {
  19098. normal.set(0, 0, 1);
  19099. }
  19100. vec.crossVectors(tangents[0], normal).normalize();
  19101. normals[0].crossVectors(tangents[0], vec);
  19102. binormals[0].crossVectors(tangents[0], normals[0]); // compute the slowly-varying normal and binormal vectors for each segment on the curve
  19103. for (let i = 1; i <= segments; i++) {
  19104. normals[i] = normals[i - 1].clone();
  19105. binormals[i] = binormals[i - 1].clone();
  19106. vec.crossVectors(tangents[i - 1], tangents[i]);
  19107. if (vec.length() > Number.EPSILON) {
  19108. vec.normalize();
  19109. const theta = Math.acos(clamp(tangents[i - 1].dot(tangents[i]), -1, 1)); // clamp for floating pt errors
  19110. normals[i].applyMatrix4(mat.makeRotationAxis(vec, theta));
  19111. }
  19112. binormals[i].crossVectors(tangents[i], normals[i]);
  19113. } // if the curve is closed, postprocess the vectors so the first and last normal vectors are the same
  19114. if (closed === true) {
  19115. let theta = Math.acos(clamp(normals[0].dot(normals[segments]), -1, 1));
  19116. theta /= segments;
  19117. if (tangents[0].dot(vec.crossVectors(normals[0], normals[segments])) > 0) {
  19118. theta = -theta;
  19119. }
  19120. for (let i = 1; i <= segments; i++) {
  19121. // twist a little...
  19122. normals[i].applyMatrix4(mat.makeRotationAxis(tangents[i], theta * i));
  19123. binormals[i].crossVectors(tangents[i], normals[i]);
  19124. }
  19125. }
  19126. return {
  19127. tangents: tangents,
  19128. normals: normals,
  19129. binormals: binormals
  19130. };
  19131. }
  19132. clone() {
  19133. return new this.constructor().copy(this);
  19134. }
  19135. copy(source) {
  19136. this.arcLengthDivisions = source.arcLengthDivisions;
  19137. return this;
  19138. }
  19139. toJSON() {
  19140. const data = {
  19141. metadata: {
  19142. version: 4.5,
  19143. type: 'Curve',
  19144. generator: 'Curve.toJSON'
  19145. }
  19146. };
  19147. data.arcLengthDivisions = this.arcLengthDivisions;
  19148. data.type = this.type;
  19149. return data;
  19150. }
  19151. fromJSON(json) {
  19152. this.arcLengthDivisions = json.arcLengthDivisions;
  19153. return this;
  19154. }
  19155. }
  19156. class EllipseCurve extends Curve {
  19157. constructor(aX = 0, aY = 0, xRadius = 1, yRadius = 1, aStartAngle = 0, aEndAngle = Math.PI * 2, aClockwise = false, aRotation = 0) {
  19158. super();
  19159. this.isEllipseCurve = true;
  19160. this.type = 'EllipseCurve';
  19161. this.aX = aX;
  19162. this.aY = aY;
  19163. this.xRadius = xRadius;
  19164. this.yRadius = yRadius;
  19165. this.aStartAngle = aStartAngle;
  19166. this.aEndAngle = aEndAngle;
  19167. this.aClockwise = aClockwise;
  19168. this.aRotation = aRotation;
  19169. }
  19170. getPoint(t, optionalTarget) {
  19171. const point = optionalTarget || new Vector2();
  19172. const twoPi = Math.PI * 2;
  19173. let deltaAngle = this.aEndAngle - this.aStartAngle;
  19174. const samePoints = Math.abs(deltaAngle) < Number.EPSILON; // ensures that deltaAngle is 0 .. 2 PI
  19175. while (deltaAngle < 0) deltaAngle += twoPi;
  19176. while (deltaAngle > twoPi) deltaAngle -= twoPi;
  19177. if (deltaAngle < Number.EPSILON) {
  19178. if (samePoints) {
  19179. deltaAngle = 0;
  19180. } else {
  19181. deltaAngle = twoPi;
  19182. }
  19183. }
  19184. if (this.aClockwise === true && !samePoints) {
  19185. if (deltaAngle === twoPi) {
  19186. deltaAngle = -twoPi;
  19187. } else {
  19188. deltaAngle = deltaAngle - twoPi;
  19189. }
  19190. }
  19191. const angle = this.aStartAngle + t * deltaAngle;
  19192. let x = this.aX + this.xRadius * Math.cos(angle);
  19193. let y = this.aY + this.yRadius * Math.sin(angle);
  19194. if (this.aRotation !== 0) {
  19195. const cos = Math.cos(this.aRotation);
  19196. const sin = Math.sin(this.aRotation);
  19197. const tx = x - this.aX;
  19198. const ty = y - this.aY; // Rotate the point about the center of the ellipse.
  19199. x = tx * cos - ty * sin + this.aX;
  19200. y = tx * sin + ty * cos + this.aY;
  19201. }
  19202. return point.set(x, y);
  19203. }
  19204. copy(source) {
  19205. super.copy(source);
  19206. this.aX = source.aX;
  19207. this.aY = source.aY;
  19208. this.xRadius = source.xRadius;
  19209. this.yRadius = source.yRadius;
  19210. this.aStartAngle = source.aStartAngle;
  19211. this.aEndAngle = source.aEndAngle;
  19212. this.aClockwise = source.aClockwise;
  19213. this.aRotation = source.aRotation;
  19214. return this;
  19215. }
  19216. toJSON() {
  19217. const data = super.toJSON();
  19218. data.aX = this.aX;
  19219. data.aY = this.aY;
  19220. data.xRadius = this.xRadius;
  19221. data.yRadius = this.yRadius;
  19222. data.aStartAngle = this.aStartAngle;
  19223. data.aEndAngle = this.aEndAngle;
  19224. data.aClockwise = this.aClockwise;
  19225. data.aRotation = this.aRotation;
  19226. return data;
  19227. }
  19228. fromJSON(json) {
  19229. super.fromJSON(json);
  19230. this.aX = json.aX;
  19231. this.aY = json.aY;
  19232. this.xRadius = json.xRadius;
  19233. this.yRadius = json.yRadius;
  19234. this.aStartAngle = json.aStartAngle;
  19235. this.aEndAngle = json.aEndAngle;
  19236. this.aClockwise = json.aClockwise;
  19237. this.aRotation = json.aRotation;
  19238. return this;
  19239. }
  19240. }
  19241. class ArcCurve extends EllipseCurve {
  19242. constructor(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {
  19243. super(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise);
  19244. this.isArcCurve = true;
  19245. this.type = 'ArcCurve';
  19246. }
  19247. }
  19248. /**
  19249. * Centripetal CatmullRom Curve - which is useful for avoiding
  19250. * cusps and self-intersections in non-uniform catmull rom curves.
  19251. * http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf
  19252. *
  19253. * curve.type accepts centripetal(default), chordal and catmullrom
  19254. * curve.tension is used for catmullrom which defaults to 0.5
  19255. */
  19256. /*
  19257. Based on an optimized c++ solution in
  19258. - http://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections/
  19259. - http://ideone.com/NoEbVM
  19260. This CubicPoly class could be used for reusing some variables and calculations,
  19261. but for three.js curve use, it could be possible inlined and flatten into a single function call
  19262. which can be placed in CurveUtils.
  19263. */
  19264. function CubicPoly() {
  19265. let c0 = 0,
  19266. c1 = 0,
  19267. c2 = 0,
  19268. c3 = 0;
  19269. /*
  19270. * Compute coefficients for a cubic polynomial
  19271. * p(s) = c0 + c1*s + c2*s^2 + c3*s^3
  19272. * such that
  19273. * p(0) = x0, p(1) = x1
  19274. * and
  19275. * p'(0) = t0, p'(1) = t1.
  19276. */
  19277. function init(x0, x1, t0, t1) {
  19278. c0 = x0;
  19279. c1 = t0;
  19280. c2 = -3 * x0 + 3 * x1 - 2 * t0 - t1;
  19281. c3 = 2 * x0 - 2 * x1 + t0 + t1;
  19282. }
  19283. return {
  19284. initCatmullRom: function (x0, x1, x2, x3, tension) {
  19285. init(x1, x2, tension * (x2 - x0), tension * (x3 - x1));
  19286. },
  19287. initNonuniformCatmullRom: function (x0, x1, x2, x3, dt0, dt1, dt2) {
  19288. // compute tangents when parameterized in [t1,t2]
  19289. let t1 = (x1 - x0) / dt0 - (x2 - x0) / (dt0 + dt1) + (x2 - x1) / dt1;
  19290. let t2 = (x2 - x1) / dt1 - (x3 - x1) / (dt1 + dt2) + (x3 - x2) / dt2; // rescale tangents for parametrization in [0,1]
  19291. t1 *= dt1;
  19292. t2 *= dt1;
  19293. init(x1, x2, t1, t2);
  19294. },
  19295. calc: function (t) {
  19296. const t2 = t * t;
  19297. const t3 = t2 * t;
  19298. return c0 + c1 * t + c2 * t2 + c3 * t3;
  19299. }
  19300. };
  19301. } //
  19302. const tmp = /*@__PURE__*/new Vector3();
  19303. const px = /*@__PURE__*/new CubicPoly();
  19304. const py = /*@__PURE__*/new CubicPoly();
  19305. const pz = /*@__PURE__*/new CubicPoly();
  19306. class CatmullRomCurve3 extends Curve {
  19307. constructor(points = [], closed = false, curveType = 'centripetal', tension = 0.5) {
  19308. super();
  19309. this.isCatmullRomCurve3 = true;
  19310. this.type = 'CatmullRomCurve3';
  19311. this.points = points;
  19312. this.closed = closed;
  19313. this.curveType = curveType;
  19314. this.tension = tension;
  19315. }
  19316. getPoint(t, optionalTarget = new Vector3()) {
  19317. const point = optionalTarget;
  19318. const points = this.points;
  19319. const l = points.length;
  19320. const p = (l - (this.closed ? 0 : 1)) * t;
  19321. let intPoint = Math.floor(p);
  19322. let weight = p - intPoint;
  19323. if (this.closed) {
  19324. intPoint += intPoint > 0 ? 0 : (Math.floor(Math.abs(intPoint) / l) + 1) * l;
  19325. } else if (weight === 0 && intPoint === l - 1) {
  19326. intPoint = l - 2;
  19327. weight = 1;
  19328. }
  19329. let p0, p3; // 4 points (p1 & p2 defined below)
  19330. if (this.closed || intPoint > 0) {
  19331. p0 = points[(intPoint - 1) % l];
  19332. } else {
  19333. // extrapolate first point
  19334. tmp.subVectors(points[0], points[1]).add(points[0]);
  19335. p0 = tmp;
  19336. }
  19337. const p1 = points[intPoint % l];
  19338. const p2 = points[(intPoint + 1) % l];
  19339. if (this.closed || intPoint + 2 < l) {
  19340. p3 = points[(intPoint + 2) % l];
  19341. } else {
  19342. // extrapolate last point
  19343. tmp.subVectors(points[l - 1], points[l - 2]).add(points[l - 1]);
  19344. p3 = tmp;
  19345. }
  19346. if (this.curveType === 'centripetal' || this.curveType === 'chordal') {
  19347. // init Centripetal / Chordal Catmull-Rom
  19348. const pow = this.curveType === 'chordal' ? 0.5 : 0.25;
  19349. let dt0 = Math.pow(p0.distanceToSquared(p1), pow);
  19350. let dt1 = Math.pow(p1.distanceToSquared(p2), pow);
  19351. let dt2 = Math.pow(p2.distanceToSquared(p3), pow); // safety check for repeated points
  19352. if (dt1 < 1e-4) dt1 = 1.0;
  19353. if (dt0 < 1e-4) dt0 = dt1;
  19354. if (dt2 < 1e-4) dt2 = dt1;
  19355. px.initNonuniformCatmullRom(p0.x, p1.x, p2.x, p3.x, dt0, dt1, dt2);
  19356. py.initNonuniformCatmullRom(p0.y, p1.y, p2.y, p3.y, dt0, dt1, dt2);
  19357. pz.initNonuniformCatmullRom(p0.z, p1.z, p2.z, p3.z, dt0, dt1, dt2);
  19358. } else if (this.curveType === 'catmullrom') {
  19359. px.initCatmullRom(p0.x, p1.x, p2.x, p3.x, this.tension);
  19360. py.initCatmullRom(p0.y, p1.y, p2.y, p3.y, this.tension);
  19361. pz.initCatmullRom(p0.z, p1.z, p2.z, p3.z, this.tension);
  19362. }
  19363. point.set(px.calc(weight), py.calc(weight), pz.calc(weight));
  19364. return point;
  19365. }
  19366. copy(source) {
  19367. super.copy(source);
  19368. this.points = [];
  19369. for (let i = 0, l = source.points.length; i < l; i++) {
  19370. const point = source.points[i];
  19371. this.points.push(point.clone());
  19372. }
  19373. this.closed = source.closed;
  19374. this.curveType = source.curveType;
  19375. this.tension = source.tension;
  19376. return this;
  19377. }
  19378. toJSON() {
  19379. const data = super.toJSON();
  19380. data.points = [];
  19381. for (let i = 0, l = this.points.length; i < l; i++) {
  19382. const point = this.points[i];
  19383. data.points.push(point.toArray());
  19384. }
  19385. data.closed = this.closed;
  19386. data.curveType = this.curveType;
  19387. data.tension = this.tension;
  19388. return data;
  19389. }
  19390. fromJSON(json) {
  19391. super.fromJSON(json);
  19392. this.points = [];
  19393. for (let i = 0, l = json.points.length; i < l; i++) {
  19394. const point = json.points[i];
  19395. this.points.push(new Vector3().fromArray(point));
  19396. }
  19397. this.closed = json.closed;
  19398. this.curveType = json.curveType;
  19399. this.tension = json.tension;
  19400. return this;
  19401. }
  19402. }
  19403. /**
  19404. * Bezier Curves formulas obtained from
  19405. * https://en.wikipedia.org/wiki/B%C3%A9zier_curve
  19406. */
  19407. function CatmullRom(t, p0, p1, p2, p3) {
  19408. const v0 = (p2 - p0) * 0.5;
  19409. const v1 = (p3 - p1) * 0.5;
  19410. const t2 = t * t;
  19411. const t3 = t * t2;
  19412. return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (-3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
  19413. } //
  19414. function QuadraticBezierP0(t, p) {
  19415. const k = 1 - t;
  19416. return k * k * p;
  19417. }
  19418. function QuadraticBezierP1(t, p) {
  19419. return 2 * (1 - t) * t * p;
  19420. }
  19421. function QuadraticBezierP2(t, p) {
  19422. return t * t * p;
  19423. }
  19424. function QuadraticBezier(t, p0, p1, p2) {
  19425. return QuadraticBezierP0(t, p0) + QuadraticBezierP1(t, p1) + QuadraticBezierP2(t, p2);
  19426. } //
  19427. function CubicBezierP0(t, p) {
  19428. const k = 1 - t;
  19429. return k * k * k * p;
  19430. }
  19431. function CubicBezierP1(t, p) {
  19432. const k = 1 - t;
  19433. return 3 * k * k * t * p;
  19434. }
  19435. function CubicBezierP2(t, p) {
  19436. return 3 * (1 - t) * t * t * p;
  19437. }
  19438. function CubicBezierP3(t, p) {
  19439. return t * t * t * p;
  19440. }
  19441. function CubicBezier(t, p0, p1, p2, p3) {
  19442. return CubicBezierP0(t, p0) + CubicBezierP1(t, p1) + CubicBezierP2(t, p2) + CubicBezierP3(t, p3);
  19443. }
  19444. class CubicBezierCurve extends Curve {
  19445. constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2(), v3 = new Vector2()) {
  19446. super();
  19447. this.isCubicBezierCurve = true;
  19448. this.type = 'CubicBezierCurve';
  19449. this.v0 = v0;
  19450. this.v1 = v1;
  19451. this.v2 = v2;
  19452. this.v3 = v3;
  19453. }
  19454. getPoint(t, optionalTarget = new Vector2()) {
  19455. const point = optionalTarget;
  19456. const v0 = this.v0,
  19457. v1 = this.v1,
  19458. v2 = this.v2,
  19459. v3 = this.v3;
  19460. point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y));
  19461. return point;
  19462. }
  19463. copy(source) {
  19464. super.copy(source);
  19465. this.v0.copy(source.v0);
  19466. this.v1.copy(source.v1);
  19467. this.v2.copy(source.v2);
  19468. this.v3.copy(source.v3);
  19469. return this;
  19470. }
  19471. toJSON() {
  19472. const data = super.toJSON();
  19473. data.v0 = this.v0.toArray();
  19474. data.v1 = this.v1.toArray();
  19475. data.v2 = this.v2.toArray();
  19476. data.v3 = this.v3.toArray();
  19477. return data;
  19478. }
  19479. fromJSON(json) {
  19480. super.fromJSON(json);
  19481. this.v0.fromArray(json.v0);
  19482. this.v1.fromArray(json.v1);
  19483. this.v2.fromArray(json.v2);
  19484. this.v3.fromArray(json.v3);
  19485. return this;
  19486. }
  19487. }
  19488. class CubicBezierCurve3 extends Curve {
  19489. constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3(), v3 = new Vector3()) {
  19490. super();
  19491. this.isCubicBezierCurve3 = true;
  19492. this.type = 'CubicBezierCurve3';
  19493. this.v0 = v0;
  19494. this.v1 = v1;
  19495. this.v2 = v2;
  19496. this.v3 = v3;
  19497. }
  19498. getPoint(t, optionalTarget = new Vector3()) {
  19499. const point = optionalTarget;
  19500. const v0 = this.v0,
  19501. v1 = this.v1,
  19502. v2 = this.v2,
  19503. v3 = this.v3;
  19504. point.set(CubicBezier(t, v0.x, v1.x, v2.x, v3.x), CubicBezier(t, v0.y, v1.y, v2.y, v3.y), CubicBezier(t, v0.z, v1.z, v2.z, v3.z));
  19505. return point;
  19506. }
  19507. copy(source) {
  19508. super.copy(source);
  19509. this.v0.copy(source.v0);
  19510. this.v1.copy(source.v1);
  19511. this.v2.copy(source.v2);
  19512. this.v3.copy(source.v3);
  19513. return this;
  19514. }
  19515. toJSON() {
  19516. const data = super.toJSON();
  19517. data.v0 = this.v0.toArray();
  19518. data.v1 = this.v1.toArray();
  19519. data.v2 = this.v2.toArray();
  19520. data.v3 = this.v3.toArray();
  19521. return data;
  19522. }
  19523. fromJSON(json) {
  19524. super.fromJSON(json);
  19525. this.v0.fromArray(json.v0);
  19526. this.v1.fromArray(json.v1);
  19527. this.v2.fromArray(json.v2);
  19528. this.v3.fromArray(json.v3);
  19529. return this;
  19530. }
  19531. }
  19532. class LineCurve extends Curve {
  19533. constructor(v1 = new Vector2(), v2 = new Vector2()) {
  19534. super();
  19535. this.isLineCurve = true;
  19536. this.type = 'LineCurve';
  19537. this.v1 = v1;
  19538. this.v2 = v2;
  19539. }
  19540. getPoint(t, optionalTarget = new Vector2()) {
  19541. const point = optionalTarget;
  19542. if (t === 1) {
  19543. point.copy(this.v2);
  19544. } else {
  19545. point.copy(this.v2).sub(this.v1);
  19546. point.multiplyScalar(t).add(this.v1);
  19547. }
  19548. return point;
  19549. } // Line curve is linear, so we can overwrite default getPointAt
  19550. getPointAt(u, optionalTarget) {
  19551. return this.getPoint(u, optionalTarget);
  19552. }
  19553. getTangent(t, optionalTarget) {
  19554. const tangent = optionalTarget || new Vector2();
  19555. tangent.copy(this.v2).sub(this.v1).normalize();
  19556. return tangent;
  19557. }
  19558. copy(source) {
  19559. super.copy(source);
  19560. this.v1.copy(source.v1);
  19561. this.v2.copy(source.v2);
  19562. return this;
  19563. }
  19564. toJSON() {
  19565. const data = super.toJSON();
  19566. data.v1 = this.v1.toArray();
  19567. data.v2 = this.v2.toArray();
  19568. return data;
  19569. }
  19570. fromJSON(json) {
  19571. super.fromJSON(json);
  19572. this.v1.fromArray(json.v1);
  19573. this.v2.fromArray(json.v2);
  19574. return this;
  19575. }
  19576. }
  19577. class LineCurve3 extends Curve {
  19578. constructor(v1 = new Vector3(), v2 = new Vector3()) {
  19579. super();
  19580. this.isLineCurve3 = true;
  19581. this.type = 'LineCurve3';
  19582. this.v1 = v1;
  19583. this.v2 = v2;
  19584. }
  19585. getPoint(t, optionalTarget = new Vector3()) {
  19586. const point = optionalTarget;
  19587. if (t === 1) {
  19588. point.copy(this.v2);
  19589. } else {
  19590. point.copy(this.v2).sub(this.v1);
  19591. point.multiplyScalar(t).add(this.v1);
  19592. }
  19593. return point;
  19594. } // Line curve is linear, so we can overwrite default getPointAt
  19595. getPointAt(u, optionalTarget) {
  19596. return this.getPoint(u, optionalTarget);
  19597. }
  19598. copy(source) {
  19599. super.copy(source);
  19600. this.v1.copy(source.v1);
  19601. this.v2.copy(source.v2);
  19602. return this;
  19603. }
  19604. toJSON() {
  19605. const data = super.toJSON();
  19606. data.v1 = this.v1.toArray();
  19607. data.v2 = this.v2.toArray();
  19608. return data;
  19609. }
  19610. fromJSON(json) {
  19611. super.fromJSON(json);
  19612. this.v1.fromArray(json.v1);
  19613. this.v2.fromArray(json.v2);
  19614. return this;
  19615. }
  19616. }
  19617. class QuadraticBezierCurve extends Curve {
  19618. constructor(v0 = new Vector2(), v1 = new Vector2(), v2 = new Vector2()) {
  19619. super();
  19620. this.isQuadraticBezierCurve = true;
  19621. this.type = 'QuadraticBezierCurve';
  19622. this.v0 = v0;
  19623. this.v1 = v1;
  19624. this.v2 = v2;
  19625. }
  19626. getPoint(t, optionalTarget = new Vector2()) {
  19627. const point = optionalTarget;
  19628. const v0 = this.v0,
  19629. v1 = this.v1,
  19630. v2 = this.v2;
  19631. point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y));
  19632. return point;
  19633. }
  19634. copy(source) {
  19635. super.copy(source);
  19636. this.v0.copy(source.v0);
  19637. this.v1.copy(source.v1);
  19638. this.v2.copy(source.v2);
  19639. return this;
  19640. }
  19641. toJSON() {
  19642. const data = super.toJSON();
  19643. data.v0 = this.v0.toArray();
  19644. data.v1 = this.v1.toArray();
  19645. data.v2 = this.v2.toArray();
  19646. return data;
  19647. }
  19648. fromJSON(json) {
  19649. super.fromJSON(json);
  19650. this.v0.fromArray(json.v0);
  19651. this.v1.fromArray(json.v1);
  19652. this.v2.fromArray(json.v2);
  19653. return this;
  19654. }
  19655. }
  19656. class QuadraticBezierCurve3 extends Curve {
  19657. constructor(v0 = new Vector3(), v1 = new Vector3(), v2 = new Vector3()) {
  19658. super();
  19659. this.isQuadraticBezierCurve3 = true;
  19660. this.type = 'QuadraticBezierCurve3';
  19661. this.v0 = v0;
  19662. this.v1 = v1;
  19663. this.v2 = v2;
  19664. }
  19665. getPoint(t, optionalTarget = new Vector3()) {
  19666. const point = optionalTarget;
  19667. const v0 = this.v0,
  19668. v1 = this.v1,
  19669. v2 = this.v2;
  19670. point.set(QuadraticBezier(t, v0.x, v1.x, v2.x), QuadraticBezier(t, v0.y, v1.y, v2.y), QuadraticBezier(t, v0.z, v1.z, v2.z));
  19671. return point;
  19672. }
  19673. copy(source) {
  19674. super.copy(source);
  19675. this.v0.copy(source.v0);
  19676. this.v1.copy(source.v1);
  19677. this.v2.copy(source.v2);
  19678. return this;
  19679. }
  19680. toJSON() {
  19681. const data = super.toJSON();
  19682. data.v0 = this.v0.toArray();
  19683. data.v1 = this.v1.toArray();
  19684. data.v2 = this.v2.toArray();
  19685. return data;
  19686. }
  19687. fromJSON(json) {
  19688. super.fromJSON(json);
  19689. this.v0.fromArray(json.v0);
  19690. this.v1.fromArray(json.v1);
  19691. this.v2.fromArray(json.v2);
  19692. return this;
  19693. }
  19694. }
  19695. class SplineCurve extends Curve {
  19696. constructor(points = []) {
  19697. super();
  19698. this.isSplineCurve = true;
  19699. this.type = 'SplineCurve';
  19700. this.points = points;
  19701. }
  19702. getPoint(t, optionalTarget = new Vector2()) {
  19703. const point = optionalTarget;
  19704. const points = this.points;
  19705. const p = (points.length - 1) * t;
  19706. const intPoint = Math.floor(p);
  19707. const weight = p - intPoint;
  19708. const p0 = points[intPoint === 0 ? intPoint : intPoint - 1];
  19709. const p1 = points[intPoint];
  19710. const p2 = points[intPoint > points.length - 2 ? points.length - 1 : intPoint + 1];
  19711. const p3 = points[intPoint > points.length - 3 ? points.length - 1 : intPoint + 2];
  19712. point.set(CatmullRom(weight, p0.x, p1.x, p2.x, p3.x), CatmullRom(weight, p0.y, p1.y, p2.y, p3.y));
  19713. return point;
  19714. }
  19715. copy(source) {
  19716. super.copy(source);
  19717. this.points = [];
  19718. for (let i = 0, l = source.points.length; i < l; i++) {
  19719. const point = source.points[i];
  19720. this.points.push(point.clone());
  19721. }
  19722. return this;
  19723. }
  19724. toJSON() {
  19725. const data = super.toJSON();
  19726. data.points = [];
  19727. for (let i = 0, l = this.points.length; i < l; i++) {
  19728. const point = this.points[i];
  19729. data.points.push(point.toArray());
  19730. }
  19731. return data;
  19732. }
  19733. fromJSON(json) {
  19734. super.fromJSON(json);
  19735. this.points = [];
  19736. for (let i = 0, l = json.points.length; i < l; i++) {
  19737. const point = json.points[i];
  19738. this.points.push(new Vector2().fromArray(point));
  19739. }
  19740. return this;
  19741. }
  19742. }
  19743. var Curves = /*#__PURE__*/Object.freeze({
  19744. __proto__: null,
  19745. ArcCurve: ArcCurve,
  19746. CatmullRomCurve3: CatmullRomCurve3,
  19747. CubicBezierCurve: CubicBezierCurve,
  19748. CubicBezierCurve3: CubicBezierCurve3,
  19749. EllipseCurve: EllipseCurve,
  19750. LineCurve: LineCurve,
  19751. LineCurve3: LineCurve3,
  19752. QuadraticBezierCurve: QuadraticBezierCurve,
  19753. QuadraticBezierCurve3: QuadraticBezierCurve3,
  19754. SplineCurve: SplineCurve
  19755. });
  19756. /**************************************************************
  19757. * Curved Path - a curve path is simply a array of connected
  19758. * curves, but retains the api of a curve
  19759. **************************************************************/
  19760. class CurvePath extends Curve {
  19761. constructor() {
  19762. super();
  19763. this.type = 'CurvePath';
  19764. this.curves = [];
  19765. this.autoClose = false; // Automatically closes the path
  19766. }
  19767. add(curve) {
  19768. this.curves.push(curve);
  19769. }
  19770. closePath() {
  19771. // Add a line curve if start and end of lines are not connected
  19772. const startPoint = this.curves[0].getPoint(0);
  19773. const endPoint = this.curves[this.curves.length - 1].getPoint(1);
  19774. if (!startPoint.equals(endPoint)) {
  19775. this.curves.push(new LineCurve(endPoint, startPoint));
  19776. }
  19777. } // To get accurate point with reference to
  19778. // entire path distance at time t,
  19779. // following has to be done:
  19780. // 1. Length of each sub path have to be known
  19781. // 2. Locate and identify type of curve
  19782. // 3. Get t for the curve
  19783. // 4. Return curve.getPointAt(t')
  19784. getPoint(t, optionalTarget) {
  19785. const d = t * this.getLength();
  19786. const curveLengths = this.getCurveLengths();
  19787. let i = 0; // To think about boundaries points.
  19788. while (i < curveLengths.length) {
  19789. if (curveLengths[i] >= d) {
  19790. const diff = curveLengths[i] - d;
  19791. const curve = this.curves[i];
  19792. const segmentLength = curve.getLength();
  19793. const u = segmentLength === 0 ? 0 : 1 - diff / segmentLength;
  19794. return curve.getPointAt(u, optionalTarget);
  19795. }
  19796. i++;
  19797. }
  19798. return null; // loop where sum != 0, sum > d , sum+1 <d
  19799. } // We cannot use the default THREE.Curve getPoint() with getLength() because in
  19800. // THREE.Curve, getLength() depends on getPoint() but in THREE.CurvePath
  19801. // getPoint() depends on getLength
  19802. getLength() {
  19803. const lens = this.getCurveLengths();
  19804. return lens[lens.length - 1];
  19805. } // cacheLengths must be recalculated.
  19806. updateArcLengths() {
  19807. this.needsUpdate = true;
  19808. this.cacheLengths = null;
  19809. this.getCurveLengths();
  19810. } // Compute lengths and cache them
  19811. // We cannot overwrite getLengths() because UtoT mapping uses it.
  19812. getCurveLengths() {
  19813. // We use cache values if curves and cache array are same length
  19814. if (this.cacheLengths && this.cacheLengths.length === this.curves.length) {
  19815. return this.cacheLengths;
  19816. } // Get length of sub-curve
  19817. // Push sums into cached array
  19818. const lengths = [];
  19819. let sums = 0;
  19820. for (let i = 0, l = this.curves.length; i < l; i++) {
  19821. sums += this.curves[i].getLength();
  19822. lengths.push(sums);
  19823. }
  19824. this.cacheLengths = lengths;
  19825. return lengths;
  19826. }
  19827. getSpacedPoints(divisions = 40) {
  19828. const points = [];
  19829. for (let i = 0; i <= divisions; i++) {
  19830. points.push(this.getPoint(i / divisions));
  19831. }
  19832. if (this.autoClose) {
  19833. points.push(points[0]);
  19834. }
  19835. return points;
  19836. }
  19837. getPoints(divisions = 12) {
  19838. const points = [];
  19839. let last;
  19840. for (let i = 0, curves = this.curves; i < curves.length; i++) {
  19841. const curve = curves[i];
  19842. const resolution = curve.isEllipseCurve ? divisions * 2 : curve.isLineCurve || curve.isLineCurve3 ? 1 : curve.isSplineCurve ? divisions * curve.points.length : divisions;
  19843. const pts = curve.getPoints(resolution);
  19844. for (let j = 0; j < pts.length; j++) {
  19845. const point = pts[j];
  19846. if (last && last.equals(point)) continue; // ensures no consecutive points are duplicates
  19847. points.push(point);
  19848. last = point;
  19849. }
  19850. }
  19851. if (this.autoClose && points.length > 1 && !points[points.length - 1].equals(points[0])) {
  19852. points.push(points[0]);
  19853. }
  19854. return points;
  19855. }
  19856. copy(source) {
  19857. super.copy(source);
  19858. this.curves = [];
  19859. for (let i = 0, l = source.curves.length; i < l; i++) {
  19860. const curve = source.curves[i];
  19861. this.curves.push(curve.clone());
  19862. }
  19863. this.autoClose = source.autoClose;
  19864. return this;
  19865. }
  19866. toJSON() {
  19867. const data = super.toJSON();
  19868. data.autoClose = this.autoClose;
  19869. data.curves = [];
  19870. for (let i = 0, l = this.curves.length; i < l; i++) {
  19871. const curve = this.curves[i];
  19872. data.curves.push(curve.toJSON());
  19873. }
  19874. return data;
  19875. }
  19876. fromJSON(json) {
  19877. super.fromJSON(json);
  19878. this.autoClose = json.autoClose;
  19879. this.curves = [];
  19880. for (let i = 0, l = json.curves.length; i < l; i++) {
  19881. const curve = json.curves[i];
  19882. this.curves.push(new Curves[curve.type]().fromJSON(curve));
  19883. }
  19884. return this;
  19885. }
  19886. }
  19887. class Path extends CurvePath {
  19888. constructor(points) {
  19889. super();
  19890. this.type = 'Path';
  19891. this.currentPoint = new Vector2();
  19892. if (points) {
  19893. this.setFromPoints(points);
  19894. }
  19895. }
  19896. setFromPoints(points) {
  19897. this.moveTo(points[0].x, points[0].y);
  19898. for (let i = 1, l = points.length; i < l; i++) {
  19899. this.lineTo(points[i].x, points[i].y);
  19900. }
  19901. return this;
  19902. }
  19903. moveTo(x, y) {
  19904. this.currentPoint.set(x, y); // TODO consider referencing vectors instead of copying?
  19905. return this;
  19906. }
  19907. lineTo(x, y) {
  19908. const curve = new LineCurve(this.currentPoint.clone(), new Vector2(x, y));
  19909. this.curves.push(curve);
  19910. this.currentPoint.set(x, y);
  19911. return this;
  19912. }
  19913. quadraticCurveTo(aCPx, aCPy, aX, aY) {
  19914. const curve = new QuadraticBezierCurve(this.currentPoint.clone(), new Vector2(aCPx, aCPy), new Vector2(aX, aY));
  19915. this.curves.push(curve);
  19916. this.currentPoint.set(aX, aY);
  19917. return this;
  19918. }
  19919. bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) {
  19920. const curve = new CubicBezierCurve(this.currentPoint.clone(), new Vector2(aCP1x, aCP1y), new Vector2(aCP2x, aCP2y), new Vector2(aX, aY));
  19921. this.curves.push(curve);
  19922. this.currentPoint.set(aX, aY);
  19923. return this;
  19924. }
  19925. splineThru(pts
  19926. /*Array of Vector*/
  19927. ) {
  19928. const npts = [this.currentPoint.clone()].concat(pts);
  19929. const curve = new SplineCurve(npts);
  19930. this.curves.push(curve);
  19931. this.currentPoint.copy(pts[pts.length - 1]);
  19932. return this;
  19933. }
  19934. arc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {
  19935. const x0 = this.currentPoint.x;
  19936. const y0 = this.currentPoint.y;
  19937. this.absarc(aX + x0, aY + y0, aRadius, aStartAngle, aEndAngle, aClockwise);
  19938. return this;
  19939. }
  19940. absarc(aX, aY, aRadius, aStartAngle, aEndAngle, aClockwise) {
  19941. this.absellipse(aX, aY, aRadius, aRadius, aStartAngle, aEndAngle, aClockwise);
  19942. return this;
  19943. }
  19944. ellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) {
  19945. const x0 = this.currentPoint.x;
  19946. const y0 = this.currentPoint.y;
  19947. this.absellipse(aX + x0, aY + y0, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation);
  19948. return this;
  19949. }
  19950. absellipse(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation) {
  19951. const curve = new EllipseCurve(aX, aY, xRadius, yRadius, aStartAngle, aEndAngle, aClockwise, aRotation);
  19952. if (this.curves.length > 0) {
  19953. // if a previous curve is present, attempt to join
  19954. const firstPoint = curve.getPoint(0);
  19955. if (!firstPoint.equals(this.currentPoint)) {
  19956. this.lineTo(firstPoint.x, firstPoint.y);
  19957. }
  19958. }
  19959. this.curves.push(curve);
  19960. const lastPoint = curve.getPoint(1);
  19961. this.currentPoint.copy(lastPoint);
  19962. return this;
  19963. }
  19964. copy(source) {
  19965. super.copy(source);
  19966. this.currentPoint.copy(source.currentPoint);
  19967. return this;
  19968. }
  19969. toJSON() {
  19970. const data = super.toJSON();
  19971. data.currentPoint = this.currentPoint.toArray();
  19972. return data;
  19973. }
  19974. fromJSON(json) {
  19975. super.fromJSON(json);
  19976. this.currentPoint.fromArray(json.currentPoint);
  19977. return this;
  19978. }
  19979. }
  19980. class LatheGeometry extends BufferGeometry {
  19981. constructor(points = [new Vector2(0, -0.5), new Vector2(0.5, 0), new Vector2(0, 0.5)], segments = 12, phiStart = 0, phiLength = Math.PI * 2) {
  19982. super();
  19983. this.type = 'LatheGeometry';
  19984. this.parameters = {
  19985. points: points,
  19986. segments: segments,
  19987. phiStart: phiStart,
  19988. phiLength: phiLength
  19989. };
  19990. segments = Math.floor(segments); // clamp phiLength so it's in range of [ 0, 2PI ]
  19991. phiLength = clamp(phiLength, 0, Math.PI * 2); // buffers
  19992. const indices = [];
  19993. const vertices = [];
  19994. const uvs = [];
  19995. const initNormals = [];
  19996. const normals = []; // helper variables
  19997. const inverseSegments = 1.0 / segments;
  19998. const vertex = new Vector3();
  19999. const uv = new Vector2();
  20000. const normal = new Vector3();
  20001. const curNormal = new Vector3();
  20002. const prevNormal = new Vector3();
  20003. let dx = 0;
  20004. let dy = 0; // pre-compute normals for initial "meridian"
  20005. for (let j = 0; j <= points.length - 1; j++) {
  20006. switch (j) {
  20007. case 0:
  20008. // special handling for 1st vertex on path
  20009. dx = points[j + 1].x - points[j].x;
  20010. dy = points[j + 1].y - points[j].y;
  20011. normal.x = dy * 1.0;
  20012. normal.y = -dx;
  20013. normal.z = dy * 0.0;
  20014. prevNormal.copy(normal);
  20015. normal.normalize();
  20016. initNormals.push(normal.x, normal.y, normal.z);
  20017. break;
  20018. case points.length - 1:
  20019. // special handling for last Vertex on path
  20020. initNormals.push(prevNormal.x, prevNormal.y, prevNormal.z);
  20021. break;
  20022. default:
  20023. // default handling for all vertices in between
  20024. dx = points[j + 1].x - points[j].x;
  20025. dy = points[j + 1].y - points[j].y;
  20026. normal.x = dy * 1.0;
  20027. normal.y = -dx;
  20028. normal.z = dy * 0.0;
  20029. curNormal.copy(normal);
  20030. normal.x += prevNormal.x;
  20031. normal.y += prevNormal.y;
  20032. normal.z += prevNormal.z;
  20033. normal.normalize();
  20034. initNormals.push(normal.x, normal.y, normal.z);
  20035. prevNormal.copy(curNormal);
  20036. }
  20037. } // generate vertices, uvs and normals
  20038. for (let i = 0; i <= segments; i++) {
  20039. const phi = phiStart + i * inverseSegments * phiLength;
  20040. const sin = Math.sin(phi);
  20041. const cos = Math.cos(phi);
  20042. for (let j = 0; j <= points.length - 1; j++) {
  20043. // vertex
  20044. vertex.x = points[j].x * sin;
  20045. vertex.y = points[j].y;
  20046. vertex.z = points[j].x * cos;
  20047. vertices.push(vertex.x, vertex.y, vertex.z); // uv
  20048. uv.x = i / segments;
  20049. uv.y = j / (points.length - 1);
  20050. uvs.push(uv.x, uv.y); // normal
  20051. const x = initNormals[3 * j + 0] * sin;
  20052. const y = initNormals[3 * j + 1];
  20053. const z = initNormals[3 * j + 0] * cos;
  20054. normals.push(x, y, z);
  20055. }
  20056. } // indices
  20057. for (let i = 0; i < segments; i++) {
  20058. for (let j = 0; j < points.length - 1; j++) {
  20059. const base = j + i * points.length;
  20060. const a = base;
  20061. const b = base + points.length;
  20062. const c = base + points.length + 1;
  20063. const d = base + 1; // faces
  20064. indices.push(a, b, d);
  20065. indices.push(c, d, b);
  20066. }
  20067. } // build geometry
  20068. this.setIndex(indices);
  20069. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  20070. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  20071. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  20072. }
  20073. static fromJSON(data) {
  20074. return new LatheGeometry(data.points, data.segments, data.phiStart, data.phiLength);
  20075. }
  20076. }
  20077. class CapsuleGeometry extends LatheGeometry {
  20078. constructor(radius = 1, length = 1, capSegments = 4, radialSegments = 8) {
  20079. const path = new Path();
  20080. path.absarc(0, -length / 2, radius, Math.PI * 1.5, 0);
  20081. path.absarc(0, length / 2, radius, 0, Math.PI * 0.5);
  20082. super(path.getPoints(capSegments), radialSegments);
  20083. this.type = 'CapsuleGeometry';
  20084. this.parameters = {
  20085. radius: radius,
  20086. height: length,
  20087. capSegments: capSegments,
  20088. radialSegments: radialSegments
  20089. };
  20090. }
  20091. static fromJSON(data) {
  20092. return new CapsuleGeometry(data.radius, data.length, data.capSegments, data.radialSegments);
  20093. }
  20094. }
  20095. class CircleGeometry extends BufferGeometry {
  20096. constructor(radius = 1, segments = 8, thetaStart = 0, thetaLength = Math.PI * 2) {
  20097. super();
  20098. this.type = 'CircleGeometry';
  20099. this.parameters = {
  20100. radius: radius,
  20101. segments: segments,
  20102. thetaStart: thetaStart,
  20103. thetaLength: thetaLength
  20104. };
  20105. segments = Math.max(3, segments); // buffers
  20106. const indices = [];
  20107. const vertices = [];
  20108. const normals = [];
  20109. const uvs = []; // helper variables
  20110. const vertex = new Vector3();
  20111. const uv = new Vector2(); // center point
  20112. vertices.push(0, 0, 0);
  20113. normals.push(0, 0, 1);
  20114. uvs.push(0.5, 0.5);
  20115. for (let s = 0, i = 3; s <= segments; s++, i += 3) {
  20116. const segment = thetaStart + s / segments * thetaLength; // vertex
  20117. vertex.x = radius * Math.cos(segment);
  20118. vertex.y = radius * Math.sin(segment);
  20119. vertices.push(vertex.x, vertex.y, vertex.z); // normal
  20120. normals.push(0, 0, 1); // uvs
  20121. uv.x = (vertices[i] / radius + 1) / 2;
  20122. uv.y = (vertices[i + 1] / radius + 1) / 2;
  20123. uvs.push(uv.x, uv.y);
  20124. } // indices
  20125. for (let i = 1; i <= segments; i++) {
  20126. indices.push(i, i + 1, 0);
  20127. } // build geometry
  20128. this.setIndex(indices);
  20129. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  20130. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  20131. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  20132. }
  20133. static fromJSON(data) {
  20134. return new CircleGeometry(data.radius, data.segments, data.thetaStart, data.thetaLength);
  20135. }
  20136. }
  20137. class CylinderGeometry extends BufferGeometry {
  20138. constructor(radiusTop = 1, radiusBottom = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
  20139. super();
  20140. this.type = 'CylinderGeometry';
  20141. this.parameters = {
  20142. radiusTop: radiusTop,
  20143. radiusBottom: radiusBottom,
  20144. height: height,
  20145. radialSegments: radialSegments,
  20146. heightSegments: heightSegments,
  20147. openEnded: openEnded,
  20148. thetaStart: thetaStart,
  20149. thetaLength: thetaLength
  20150. };
  20151. const scope = this;
  20152. radialSegments = Math.floor(radialSegments);
  20153. heightSegments = Math.floor(heightSegments); // buffers
  20154. const indices = [];
  20155. const vertices = [];
  20156. const normals = [];
  20157. const uvs = []; // helper variables
  20158. let index = 0;
  20159. const indexArray = [];
  20160. const halfHeight = height / 2;
  20161. let groupStart = 0; // generate geometry
  20162. generateTorso();
  20163. if (openEnded === false) {
  20164. if (radiusTop > 0) generateCap(true);
  20165. if (radiusBottom > 0) generateCap(false);
  20166. } // build geometry
  20167. this.setIndex(indices);
  20168. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  20169. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  20170. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  20171. function generateTorso() {
  20172. const normal = new Vector3();
  20173. const vertex = new Vector3();
  20174. let groupCount = 0; // this will be used to calculate the normal
  20175. const slope = (radiusBottom - radiusTop) / height; // generate vertices, normals and uvs
  20176. for (let y = 0; y <= heightSegments; y++) {
  20177. const indexRow = [];
  20178. const v = y / heightSegments; // calculate the radius of the current row
  20179. const radius = v * (radiusBottom - radiusTop) + radiusTop;
  20180. for (let x = 0; x <= radialSegments; x++) {
  20181. const u = x / radialSegments;
  20182. const theta = u * thetaLength + thetaStart;
  20183. const sinTheta = Math.sin(theta);
  20184. const cosTheta = Math.cos(theta); // vertex
  20185. vertex.x = radius * sinTheta;
  20186. vertex.y = -v * height + halfHeight;
  20187. vertex.z = radius * cosTheta;
  20188. vertices.push(vertex.x, vertex.y, vertex.z); // normal
  20189. normal.set(sinTheta, slope, cosTheta).normalize();
  20190. normals.push(normal.x, normal.y, normal.z); // uv
  20191. uvs.push(u, 1 - v); // save index of vertex in respective row
  20192. indexRow.push(index++);
  20193. } // now save vertices of the row in our index array
  20194. indexArray.push(indexRow);
  20195. } // generate indices
  20196. for (let x = 0; x < radialSegments; x++) {
  20197. for (let y = 0; y < heightSegments; y++) {
  20198. // we use the index array to access the correct indices
  20199. const a = indexArray[y][x];
  20200. const b = indexArray[y + 1][x];
  20201. const c = indexArray[y + 1][x + 1];
  20202. const d = indexArray[y][x + 1]; // faces
  20203. indices.push(a, b, d);
  20204. indices.push(b, c, d); // update group counter
  20205. groupCount += 6;
  20206. }
  20207. } // add a group to the geometry. this will ensure multi material support
  20208. scope.addGroup(groupStart, groupCount, 0); // calculate new start value for groups
  20209. groupStart += groupCount;
  20210. }
  20211. function generateCap(top) {
  20212. // save the index of the first center vertex
  20213. const centerIndexStart = index;
  20214. const uv = new Vector2();
  20215. const vertex = new Vector3();
  20216. let groupCount = 0;
  20217. const radius = top === true ? radiusTop : radiusBottom;
  20218. const sign = top === true ? 1 : -1; // first we generate the center vertex data of the cap.
  20219. // because the geometry needs one set of uvs per face,
  20220. // we must generate a center vertex per face/segment
  20221. for (let x = 1; x <= radialSegments; x++) {
  20222. // vertex
  20223. vertices.push(0, halfHeight * sign, 0); // normal
  20224. normals.push(0, sign, 0); // uv
  20225. uvs.push(0.5, 0.5); // increase index
  20226. index++;
  20227. } // save the index of the last center vertex
  20228. const centerIndexEnd = index; // now we generate the surrounding vertices, normals and uvs
  20229. for (let x = 0; x <= radialSegments; x++) {
  20230. const u = x / radialSegments;
  20231. const theta = u * thetaLength + thetaStart;
  20232. const cosTheta = Math.cos(theta);
  20233. const sinTheta = Math.sin(theta); // vertex
  20234. vertex.x = radius * sinTheta;
  20235. vertex.y = halfHeight * sign;
  20236. vertex.z = radius * cosTheta;
  20237. vertices.push(vertex.x, vertex.y, vertex.z); // normal
  20238. normals.push(0, sign, 0); // uv
  20239. uv.x = cosTheta * 0.5 + 0.5;
  20240. uv.y = sinTheta * 0.5 * sign + 0.5;
  20241. uvs.push(uv.x, uv.y); // increase index
  20242. index++;
  20243. } // generate indices
  20244. for (let x = 0; x < radialSegments; x++) {
  20245. const c = centerIndexStart + x;
  20246. const i = centerIndexEnd + x;
  20247. if (top === true) {
  20248. // face top
  20249. indices.push(i, i + 1, c);
  20250. } else {
  20251. // face bottom
  20252. indices.push(i + 1, i, c);
  20253. }
  20254. groupCount += 3;
  20255. } // add a group to the geometry. this will ensure multi material support
  20256. scope.addGroup(groupStart, groupCount, top === true ? 1 : 2); // calculate new start value for groups
  20257. groupStart += groupCount;
  20258. }
  20259. }
  20260. static fromJSON(data) {
  20261. return new CylinderGeometry(data.radiusTop, data.radiusBottom, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength);
  20262. }
  20263. }
  20264. class ConeGeometry extends CylinderGeometry {
  20265. constructor(radius = 1, height = 1, radialSegments = 8, heightSegments = 1, openEnded = false, thetaStart = 0, thetaLength = Math.PI * 2) {
  20266. super(0, radius, height, radialSegments, heightSegments, openEnded, thetaStart, thetaLength);
  20267. this.type = 'ConeGeometry';
  20268. this.parameters = {
  20269. radius: radius,
  20270. height: height,
  20271. radialSegments: radialSegments,
  20272. heightSegments: heightSegments,
  20273. openEnded: openEnded,
  20274. thetaStart: thetaStart,
  20275. thetaLength: thetaLength
  20276. };
  20277. }
  20278. static fromJSON(data) {
  20279. return new ConeGeometry(data.radius, data.height, data.radialSegments, data.heightSegments, data.openEnded, data.thetaStart, data.thetaLength);
  20280. }
  20281. }
  20282. class PolyhedronGeometry extends BufferGeometry {
  20283. constructor(vertices = [], indices = [], radius = 1, detail = 0) {
  20284. super();
  20285. this.type = 'PolyhedronGeometry';
  20286. this.parameters = {
  20287. vertices: vertices,
  20288. indices: indices,
  20289. radius: radius,
  20290. detail: detail
  20291. }; // default buffer data
  20292. const vertexBuffer = [];
  20293. const uvBuffer = []; // the subdivision creates the vertex buffer data
  20294. subdivide(detail); // all vertices should lie on a conceptual sphere with a given radius
  20295. applyRadius(radius); // finally, create the uv data
  20296. generateUVs(); // build non-indexed geometry
  20297. this.setAttribute('position', new Float32BufferAttribute(vertexBuffer, 3));
  20298. this.setAttribute('normal', new Float32BufferAttribute(vertexBuffer.slice(), 3));
  20299. this.setAttribute('uv', new Float32BufferAttribute(uvBuffer, 2));
  20300. if (detail === 0) {
  20301. this.computeVertexNormals(); // flat normals
  20302. } else {
  20303. this.normalizeNormals(); // smooth normals
  20304. } // helper functions
  20305. function subdivide(detail) {
  20306. const a = new Vector3();
  20307. const b = new Vector3();
  20308. const c = new Vector3(); // iterate over all faces and apply a subdivison with the given detail value
  20309. for (let i = 0; i < indices.length; i += 3) {
  20310. // get the vertices of the face
  20311. getVertexByIndex(indices[i + 0], a);
  20312. getVertexByIndex(indices[i + 1], b);
  20313. getVertexByIndex(indices[i + 2], c); // perform subdivision
  20314. subdivideFace(a, b, c, detail);
  20315. }
  20316. }
  20317. function subdivideFace(a, b, c, detail) {
  20318. const cols = detail + 1; // we use this multidimensional array as a data structure for creating the subdivision
  20319. const v = []; // construct all of the vertices for this subdivision
  20320. for (let i = 0; i <= cols; i++) {
  20321. v[i] = [];
  20322. const aj = a.clone().lerp(c, i / cols);
  20323. const bj = b.clone().lerp(c, i / cols);
  20324. const rows = cols - i;
  20325. for (let j = 0; j <= rows; j++) {
  20326. if (j === 0 && i === cols) {
  20327. v[i][j] = aj;
  20328. } else {
  20329. v[i][j] = aj.clone().lerp(bj, j / rows);
  20330. }
  20331. }
  20332. } // construct all of the faces
  20333. for (let i = 0; i < cols; i++) {
  20334. for (let j = 0; j < 2 * (cols - i) - 1; j++) {
  20335. const k = Math.floor(j / 2);
  20336. if (j % 2 === 0) {
  20337. pushVertex(v[i][k + 1]);
  20338. pushVertex(v[i + 1][k]);
  20339. pushVertex(v[i][k]);
  20340. } else {
  20341. pushVertex(v[i][k + 1]);
  20342. pushVertex(v[i + 1][k + 1]);
  20343. pushVertex(v[i + 1][k]);
  20344. }
  20345. }
  20346. }
  20347. }
  20348. function applyRadius(radius) {
  20349. const vertex = new Vector3(); // iterate over the entire buffer and apply the radius to each vertex
  20350. for (let i = 0; i < vertexBuffer.length; i += 3) {
  20351. vertex.x = vertexBuffer[i + 0];
  20352. vertex.y = vertexBuffer[i + 1];
  20353. vertex.z = vertexBuffer[i + 2];
  20354. vertex.normalize().multiplyScalar(radius);
  20355. vertexBuffer[i + 0] = vertex.x;
  20356. vertexBuffer[i + 1] = vertex.y;
  20357. vertexBuffer[i + 2] = vertex.z;
  20358. }
  20359. }
  20360. function generateUVs() {
  20361. const vertex = new Vector3();
  20362. for (let i = 0; i < vertexBuffer.length; i += 3) {
  20363. vertex.x = vertexBuffer[i + 0];
  20364. vertex.y = vertexBuffer[i + 1];
  20365. vertex.z = vertexBuffer[i + 2];
  20366. const u = azimuth(vertex) / 2 / Math.PI + 0.5;
  20367. const v = inclination(vertex) / Math.PI + 0.5;
  20368. uvBuffer.push(u, 1 - v);
  20369. }
  20370. correctUVs();
  20371. correctSeam();
  20372. }
  20373. function correctSeam() {
  20374. // handle case when face straddles the seam, see #3269
  20375. for (let i = 0; i < uvBuffer.length; i += 6) {
  20376. // uv data of a single face
  20377. const x0 = uvBuffer[i + 0];
  20378. const x1 = uvBuffer[i + 2];
  20379. const x2 = uvBuffer[i + 4];
  20380. const max = Math.max(x0, x1, x2);
  20381. const min = Math.min(x0, x1, x2); // 0.9 is somewhat arbitrary
  20382. if (max > 0.9 && min < 0.1) {
  20383. if (x0 < 0.2) uvBuffer[i + 0] += 1;
  20384. if (x1 < 0.2) uvBuffer[i + 2] += 1;
  20385. if (x2 < 0.2) uvBuffer[i + 4] += 1;
  20386. }
  20387. }
  20388. }
  20389. function pushVertex(vertex) {
  20390. vertexBuffer.push(vertex.x, vertex.y, vertex.z);
  20391. }
  20392. function getVertexByIndex(index, vertex) {
  20393. const stride = index * 3;
  20394. vertex.x = vertices[stride + 0];
  20395. vertex.y = vertices[stride + 1];
  20396. vertex.z = vertices[stride + 2];
  20397. }
  20398. function correctUVs() {
  20399. const a = new Vector3();
  20400. const b = new Vector3();
  20401. const c = new Vector3();
  20402. const centroid = new Vector3();
  20403. const uvA = new Vector2();
  20404. const uvB = new Vector2();
  20405. const uvC = new Vector2();
  20406. for (let i = 0, j = 0; i < vertexBuffer.length; i += 9, j += 6) {
  20407. a.set(vertexBuffer[i + 0], vertexBuffer[i + 1], vertexBuffer[i + 2]);
  20408. b.set(vertexBuffer[i + 3], vertexBuffer[i + 4], vertexBuffer[i + 5]);
  20409. c.set(vertexBuffer[i + 6], vertexBuffer[i + 7], vertexBuffer[i + 8]);
  20410. uvA.set(uvBuffer[j + 0], uvBuffer[j + 1]);
  20411. uvB.set(uvBuffer[j + 2], uvBuffer[j + 3]);
  20412. uvC.set(uvBuffer[j + 4], uvBuffer[j + 5]);
  20413. centroid.copy(a).add(b).add(c).divideScalar(3);
  20414. const azi = azimuth(centroid);
  20415. correctUV(uvA, j + 0, a, azi);
  20416. correctUV(uvB, j + 2, b, azi);
  20417. correctUV(uvC, j + 4, c, azi);
  20418. }
  20419. }
  20420. function correctUV(uv, stride, vector, azimuth) {
  20421. if (azimuth < 0 && uv.x === 1) {
  20422. uvBuffer[stride] = uv.x - 1;
  20423. }
  20424. if (vector.x === 0 && vector.z === 0) {
  20425. uvBuffer[stride] = azimuth / 2 / Math.PI + 0.5;
  20426. }
  20427. } // Angle around the Y axis, counter-clockwise when looking from above.
  20428. function azimuth(vector) {
  20429. return Math.atan2(vector.z, -vector.x);
  20430. } // Angle above the XZ plane.
  20431. function inclination(vector) {
  20432. return Math.atan2(-vector.y, Math.sqrt(vector.x * vector.x + vector.z * vector.z));
  20433. }
  20434. }
  20435. static fromJSON(data) {
  20436. return new PolyhedronGeometry(data.vertices, data.indices, data.radius, data.details);
  20437. }
  20438. }
  20439. class DodecahedronGeometry extends PolyhedronGeometry {
  20440. constructor(radius = 1, detail = 0) {
  20441. const t = (1 + Math.sqrt(5)) / 2;
  20442. const r = 1 / t;
  20443. const vertices = [// (±1, ±1, ±1)
  20444. -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, // (0, ±1/φ, ±φ)
  20445. 0, -r, -t, 0, -r, t, 0, r, -t, 0, r, t, // (±1/φ, ±φ, 0)
  20446. -r, -t, 0, -r, t, 0, r, -t, 0, r, t, 0, // (±φ, 0, ±1/φ)
  20447. -t, 0, -r, t, 0, -r, -t, 0, r, t, 0, r];
  20448. const indices = [3, 11, 7, 3, 7, 15, 3, 15, 13, 7, 19, 17, 7, 17, 6, 7, 6, 15, 17, 4, 8, 17, 8, 10, 17, 10, 6, 8, 0, 16, 8, 16, 2, 8, 2, 10, 0, 12, 1, 0, 1, 18, 0, 18, 16, 6, 10, 2, 6, 2, 13, 6, 13, 15, 2, 16, 18, 2, 18, 3, 2, 3, 13, 18, 1, 9, 18, 9, 11, 18, 11, 3, 4, 14, 12, 4, 12, 0, 4, 0, 8, 11, 9, 5, 11, 5, 19, 11, 19, 7, 19, 5, 14, 19, 14, 4, 19, 4, 17, 1, 12, 14, 1, 14, 5, 1, 5, 9];
  20449. super(vertices, indices, radius, detail);
  20450. this.type = 'DodecahedronGeometry';
  20451. this.parameters = {
  20452. radius: radius,
  20453. detail: detail
  20454. };
  20455. }
  20456. static fromJSON(data) {
  20457. return new DodecahedronGeometry(data.radius, data.detail);
  20458. }
  20459. }
  20460. const _v0 = /*@__PURE__*/new Vector3();
  20461. const _v1$1 = /*@__PURE__*/new Vector3();
  20462. const _normal = /*@__PURE__*/new Vector3();
  20463. const _triangle = /*@__PURE__*/new Triangle();
  20464. class EdgesGeometry extends BufferGeometry {
  20465. constructor(geometry = null, thresholdAngle = 1) {
  20466. super();
  20467. this.type = 'EdgesGeometry';
  20468. this.parameters = {
  20469. geometry: geometry,
  20470. thresholdAngle: thresholdAngle
  20471. };
  20472. if (geometry !== null) {
  20473. const precisionPoints = 4;
  20474. const precision = Math.pow(10, precisionPoints);
  20475. const thresholdDot = Math.cos(DEG2RAD * thresholdAngle);
  20476. const indexAttr = geometry.getIndex();
  20477. const positionAttr = geometry.getAttribute('position');
  20478. const indexCount = indexAttr ? indexAttr.count : positionAttr.count;
  20479. const indexArr = [0, 0, 0];
  20480. const vertKeys = ['a', 'b', 'c'];
  20481. const hashes = new Array(3);
  20482. const edgeData = {};
  20483. const vertices = [];
  20484. for (let i = 0; i < indexCount; i += 3) {
  20485. if (indexAttr) {
  20486. indexArr[0] = indexAttr.getX(i);
  20487. indexArr[1] = indexAttr.getX(i + 1);
  20488. indexArr[2] = indexAttr.getX(i + 2);
  20489. } else {
  20490. indexArr[0] = i;
  20491. indexArr[1] = i + 1;
  20492. indexArr[2] = i + 2;
  20493. }
  20494. const {
  20495. a,
  20496. b,
  20497. c
  20498. } = _triangle;
  20499. a.fromBufferAttribute(positionAttr, indexArr[0]);
  20500. b.fromBufferAttribute(positionAttr, indexArr[1]);
  20501. c.fromBufferAttribute(positionAttr, indexArr[2]);
  20502. _triangle.getNormal(_normal); // create hashes for the edge from the vertices
  20503. hashes[0] = `${Math.round(a.x * precision)},${Math.round(a.y * precision)},${Math.round(a.z * precision)}`;
  20504. hashes[1] = `${Math.round(b.x * precision)},${Math.round(b.y * precision)},${Math.round(b.z * precision)}`;
  20505. hashes[2] = `${Math.round(c.x * precision)},${Math.round(c.y * precision)},${Math.round(c.z * precision)}`; // skip degenerate triangles
  20506. if (hashes[0] === hashes[1] || hashes[1] === hashes[2] || hashes[2] === hashes[0]) {
  20507. continue;
  20508. } // iterate over every edge
  20509. for (let j = 0; j < 3; j++) {
  20510. // get the first and next vertex making up the edge
  20511. const jNext = (j + 1) % 3;
  20512. const vecHash0 = hashes[j];
  20513. const vecHash1 = hashes[jNext];
  20514. const v0 = _triangle[vertKeys[j]];
  20515. const v1 = _triangle[vertKeys[jNext]];
  20516. const hash = `${vecHash0}_${vecHash1}`;
  20517. const reverseHash = `${vecHash1}_${vecHash0}`;
  20518. if (reverseHash in edgeData && edgeData[reverseHash]) {
  20519. // if we found a sibling edge add it into the vertex array if
  20520. // it meets the angle threshold and delete the edge from the map.
  20521. if (_normal.dot(edgeData[reverseHash].normal) <= thresholdDot) {
  20522. vertices.push(v0.x, v0.y, v0.z);
  20523. vertices.push(v1.x, v1.y, v1.z);
  20524. }
  20525. edgeData[reverseHash] = null;
  20526. } else if (!(hash in edgeData)) {
  20527. // if we've already got an edge here then skip adding a new one
  20528. edgeData[hash] = {
  20529. index0: indexArr[j],
  20530. index1: indexArr[jNext],
  20531. normal: _normal.clone()
  20532. };
  20533. }
  20534. }
  20535. } // iterate over all remaining, unmatched edges and add them to the vertex array
  20536. for (const key in edgeData) {
  20537. if (edgeData[key]) {
  20538. const {
  20539. index0,
  20540. index1
  20541. } = edgeData[key];
  20542. _v0.fromBufferAttribute(positionAttr, index0);
  20543. _v1$1.fromBufferAttribute(positionAttr, index1);
  20544. vertices.push(_v0.x, _v0.y, _v0.z);
  20545. vertices.push(_v1$1.x, _v1$1.y, _v1$1.z);
  20546. }
  20547. }
  20548. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  20549. }
  20550. }
  20551. }
  20552. class Shape extends Path {
  20553. constructor(points) {
  20554. super(points);
  20555. this.uuid = generateUUID();
  20556. this.type = 'Shape';
  20557. this.holes = [];
  20558. }
  20559. getPointsHoles(divisions) {
  20560. const holesPts = [];
  20561. for (let i = 0, l = this.holes.length; i < l; i++) {
  20562. holesPts[i] = this.holes[i].getPoints(divisions);
  20563. }
  20564. return holesPts;
  20565. } // get points of shape and holes (keypoints based on segments parameter)
  20566. extractPoints(divisions) {
  20567. return {
  20568. shape: this.getPoints(divisions),
  20569. holes: this.getPointsHoles(divisions)
  20570. };
  20571. }
  20572. copy(source) {
  20573. super.copy(source);
  20574. this.holes = [];
  20575. for (let i = 0, l = source.holes.length; i < l; i++) {
  20576. const hole = source.holes[i];
  20577. this.holes.push(hole.clone());
  20578. }
  20579. return this;
  20580. }
  20581. toJSON() {
  20582. const data = super.toJSON();
  20583. data.uuid = this.uuid;
  20584. data.holes = [];
  20585. for (let i = 0, l = this.holes.length; i < l; i++) {
  20586. const hole = this.holes[i];
  20587. data.holes.push(hole.toJSON());
  20588. }
  20589. return data;
  20590. }
  20591. fromJSON(json) {
  20592. super.fromJSON(json);
  20593. this.uuid = json.uuid;
  20594. this.holes = [];
  20595. for (let i = 0, l = json.holes.length; i < l; i++) {
  20596. const hole = json.holes[i];
  20597. this.holes.push(new Path().fromJSON(hole));
  20598. }
  20599. return this;
  20600. }
  20601. }
  20602. /**
  20603. * Port from https://github.com/mapbox/earcut (v2.2.2)
  20604. */
  20605. const Earcut = {
  20606. triangulate: function (data, holeIndices, dim = 2) {
  20607. const hasHoles = holeIndices && holeIndices.length;
  20608. const outerLen = hasHoles ? holeIndices[0] * dim : data.length;
  20609. let outerNode = linkedList(data, 0, outerLen, dim, true);
  20610. const triangles = [];
  20611. if (!outerNode || outerNode.next === outerNode.prev) return triangles;
  20612. let minX, minY, maxX, maxY, x, y, invSize;
  20613. if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox
  20614. if (data.length > 80 * dim) {
  20615. minX = maxX = data[0];
  20616. minY = maxY = data[1];
  20617. for (let i = dim; i < outerLen; i += dim) {
  20618. x = data[i];
  20619. y = data[i + 1];
  20620. if (x < minX) minX = x;
  20621. if (y < minY) minY = y;
  20622. if (x > maxX) maxX = x;
  20623. if (y > maxY) maxY = y;
  20624. } // minX, minY and invSize are later used to transform coords into integers for z-order calculation
  20625. invSize = Math.max(maxX - minX, maxY - minY);
  20626. invSize = invSize !== 0 ? 1 / invSize : 0;
  20627. }
  20628. earcutLinked(outerNode, triangles, dim, minX, minY, invSize);
  20629. return triangles;
  20630. }
  20631. }; // create a circular doubly linked list from polygon points in the specified winding order
  20632. function linkedList(data, start, end, dim, clockwise) {
  20633. let i, last;
  20634. if (clockwise === signedArea(data, start, end, dim) > 0) {
  20635. for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);
  20636. } else {
  20637. for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);
  20638. }
  20639. if (last && equals(last, last.next)) {
  20640. removeNode(last);
  20641. last = last.next;
  20642. }
  20643. return last;
  20644. } // eliminate colinear or duplicate points
  20645. function filterPoints(start, end) {
  20646. if (!start) return start;
  20647. if (!end) end = start;
  20648. let p = start,
  20649. again;
  20650. do {
  20651. again = false;
  20652. if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {
  20653. removeNode(p);
  20654. p = end = p.prev;
  20655. if (p === p.next) break;
  20656. again = true;
  20657. } else {
  20658. p = p.next;
  20659. }
  20660. } while (again || p !== end);
  20661. return end;
  20662. } // main ear slicing loop which triangulates a polygon (given as a linked list)
  20663. function earcutLinked(ear, triangles, dim, minX, minY, invSize, pass) {
  20664. if (!ear) return; // interlink polygon nodes in z-order
  20665. if (!pass && invSize) indexCurve(ear, minX, minY, invSize);
  20666. let stop = ear,
  20667. prev,
  20668. next; // iterate through ears, slicing them one by one
  20669. while (ear.prev !== ear.next) {
  20670. prev = ear.prev;
  20671. next = ear.next;
  20672. if (invSize ? isEarHashed(ear, minX, minY, invSize) : isEar(ear)) {
  20673. // cut off the triangle
  20674. triangles.push(prev.i / dim);
  20675. triangles.push(ear.i / dim);
  20676. triangles.push(next.i / dim);
  20677. removeNode(ear); // skipping the next vertex leads to less sliver triangles
  20678. ear = next.next;
  20679. stop = next.next;
  20680. continue;
  20681. }
  20682. ear = next; // if we looped through the whole remaining polygon and can't find any more ears
  20683. if (ear === stop) {
  20684. // try filtering points and slicing again
  20685. if (!pass) {
  20686. earcutLinked(filterPoints(ear), triangles, dim, minX, minY, invSize, 1); // if this didn't work, try curing all small self-intersections locally
  20687. } else if (pass === 1) {
  20688. ear = cureLocalIntersections(filterPoints(ear), triangles, dim);
  20689. earcutLinked(ear, triangles, dim, minX, minY, invSize, 2); // as a last resort, try splitting the remaining polygon into two
  20690. } else if (pass === 2) {
  20691. splitEarcut(ear, triangles, dim, minX, minY, invSize);
  20692. }
  20693. break;
  20694. }
  20695. }
  20696. } // check whether a polygon node forms a valid ear with adjacent nodes
  20697. function isEar(ear) {
  20698. const a = ear.prev,
  20699. b = ear,
  20700. c = ear.next;
  20701. if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
  20702. // now make sure we don't have other points inside the potential ear
  20703. let p = ear.next.next;
  20704. while (p !== ear.prev) {
  20705. if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  20706. p = p.next;
  20707. }
  20708. return true;
  20709. }
  20710. function isEarHashed(ear, minX, minY, invSize) {
  20711. const a = ear.prev,
  20712. b = ear,
  20713. c = ear.next;
  20714. if (area(a, b, c) >= 0) return false; // reflex, can't be an ear
  20715. // triangle bbox; min & max are calculated like this for speed
  20716. const minTX = a.x < b.x ? a.x < c.x ? a.x : c.x : b.x < c.x ? b.x : c.x,
  20717. minTY = a.y < b.y ? a.y < c.y ? a.y : c.y : b.y < c.y ? b.y : c.y,
  20718. maxTX = a.x > b.x ? a.x > c.x ? a.x : c.x : b.x > c.x ? b.x : c.x,
  20719. maxTY = a.y > b.y ? a.y > c.y ? a.y : c.y : b.y > c.y ? b.y : c.y; // z-order range for the current triangle bbox;
  20720. const minZ = zOrder(minTX, minTY, minX, minY, invSize),
  20721. maxZ = zOrder(maxTX, maxTY, minX, minY, invSize);
  20722. let p = ear.prevZ,
  20723. n = ear.nextZ; // look for points inside the triangle in both directions
  20724. while (p && p.z >= minZ && n && n.z <= maxZ) {
  20725. if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  20726. p = p.prevZ;
  20727. if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
  20728. n = n.nextZ;
  20729. } // look for remaining points in decreasing z-order
  20730. while (p && p.z >= minZ) {
  20731. if (p !== ear.prev && p !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && area(p.prev, p, p.next) >= 0) return false;
  20732. p = p.prevZ;
  20733. } // look for remaining points in increasing z-order
  20734. while (n && n.z <= maxZ) {
  20735. if (n !== ear.prev && n !== ear.next && pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, n.x, n.y) && area(n.prev, n, n.next) >= 0) return false;
  20736. n = n.nextZ;
  20737. }
  20738. return true;
  20739. } // go through all polygon nodes and cure small local self-intersections
  20740. function cureLocalIntersections(start, triangles, dim) {
  20741. let p = start;
  20742. do {
  20743. const a = p.prev,
  20744. b = p.next.next;
  20745. if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {
  20746. triangles.push(a.i / dim);
  20747. triangles.push(p.i / dim);
  20748. triangles.push(b.i / dim); // remove two nodes involved
  20749. removeNode(p);
  20750. removeNode(p.next);
  20751. p = start = b;
  20752. }
  20753. p = p.next;
  20754. } while (p !== start);
  20755. return filterPoints(p);
  20756. } // try splitting polygon into two and triangulate them independently
  20757. function splitEarcut(start, triangles, dim, minX, minY, invSize) {
  20758. // look for a valid diagonal that divides the polygon into two
  20759. let a = start;
  20760. do {
  20761. let b = a.next.next;
  20762. while (b !== a.prev) {
  20763. if (a.i !== b.i && isValidDiagonal(a, b)) {
  20764. // split the polygon in two by the diagonal
  20765. let c = splitPolygon(a, b); // filter colinear points around the cuts
  20766. a = filterPoints(a, a.next);
  20767. c = filterPoints(c, c.next); // run earcut on each half
  20768. earcutLinked(a, triangles, dim, minX, minY, invSize);
  20769. earcutLinked(c, triangles, dim, minX, minY, invSize);
  20770. return;
  20771. }
  20772. b = b.next;
  20773. }
  20774. a = a.next;
  20775. } while (a !== start);
  20776. } // link every hole into the outer loop, producing a single-ring polygon without holes
  20777. function eliminateHoles(data, holeIndices, outerNode, dim) {
  20778. const queue = [];
  20779. let i, len, start, end, list;
  20780. for (i = 0, len = holeIndices.length; i < len; i++) {
  20781. start = holeIndices[i] * dim;
  20782. end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
  20783. list = linkedList(data, start, end, dim, false);
  20784. if (list === list.next) list.steiner = true;
  20785. queue.push(getLeftmost(list));
  20786. }
  20787. queue.sort(compareX); // process holes from left to right
  20788. for (i = 0; i < queue.length; i++) {
  20789. eliminateHole(queue[i], outerNode);
  20790. outerNode = filterPoints(outerNode, outerNode.next);
  20791. }
  20792. return outerNode;
  20793. }
  20794. function compareX(a, b) {
  20795. return a.x - b.x;
  20796. } // find a bridge between vertices that connects hole with an outer ring and link it
  20797. function eliminateHole(hole, outerNode) {
  20798. outerNode = findHoleBridge(hole, outerNode);
  20799. if (outerNode) {
  20800. const b = splitPolygon(outerNode, hole); // filter collinear points around the cuts
  20801. filterPoints(outerNode, outerNode.next);
  20802. filterPoints(b, b.next);
  20803. }
  20804. } // David Eberly's algorithm for finding a bridge between hole and outer polygon
  20805. function findHoleBridge(hole, outerNode) {
  20806. let p = outerNode;
  20807. const hx = hole.x;
  20808. const hy = hole.y;
  20809. let qx = -Infinity,
  20810. m; // find a segment intersected by a ray from the hole's leftmost point to the left;
  20811. // segment's endpoint with lesser x will be potential connection point
  20812. do {
  20813. if (hy <= p.y && hy >= p.next.y && p.next.y !== p.y) {
  20814. const x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);
  20815. if (x <= hx && x > qx) {
  20816. qx = x;
  20817. if (x === hx) {
  20818. if (hy === p.y) return p;
  20819. if (hy === p.next.y) return p.next;
  20820. }
  20821. m = p.x < p.next.x ? p : p.next;
  20822. }
  20823. }
  20824. p = p.next;
  20825. } while (p !== outerNode);
  20826. if (!m) return null;
  20827. if (hx === qx) return m; // hole touches outer segment; pick leftmost endpoint
  20828. // look for points inside the triangle of hole point, segment intersection and endpoint;
  20829. // if there are no points found, we have a valid connection;
  20830. // otherwise choose the point of the minimum angle with the ray as connection point
  20831. const stop = m,
  20832. mx = m.x,
  20833. my = m.y;
  20834. let tanMin = Infinity,
  20835. tan;
  20836. p = m;
  20837. do {
  20838. if (hx >= p.x && p.x >= mx && hx !== p.x && pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {
  20839. tan = Math.abs(hy - p.y) / (hx - p.x); // tangential
  20840. if (locallyInside(p, hole) && (tan < tanMin || tan === tanMin && (p.x > m.x || p.x === m.x && sectorContainsSector(m, p)))) {
  20841. m = p;
  20842. tanMin = tan;
  20843. }
  20844. }
  20845. p = p.next;
  20846. } while (p !== stop);
  20847. return m;
  20848. } // whether sector in vertex m contains sector in vertex p in the same coordinates
  20849. function sectorContainsSector(m, p) {
  20850. return area(m.prev, m, p.prev) < 0 && area(p.next, m, m.next) < 0;
  20851. } // interlink polygon nodes in z-order
  20852. function indexCurve(start, minX, minY, invSize) {
  20853. let p = start;
  20854. do {
  20855. if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, invSize);
  20856. p.prevZ = p.prev;
  20857. p.nextZ = p.next;
  20858. p = p.next;
  20859. } while (p !== start);
  20860. p.prevZ.nextZ = null;
  20861. p.prevZ = null;
  20862. sortLinked(p);
  20863. } // Simon Tatham's linked list merge sort algorithm
  20864. // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
  20865. function sortLinked(list) {
  20866. let i,
  20867. p,
  20868. q,
  20869. e,
  20870. tail,
  20871. numMerges,
  20872. pSize,
  20873. qSize,
  20874. inSize = 1;
  20875. do {
  20876. p = list;
  20877. list = null;
  20878. tail = null;
  20879. numMerges = 0;
  20880. while (p) {
  20881. numMerges++;
  20882. q = p;
  20883. pSize = 0;
  20884. for (i = 0; i < inSize; i++) {
  20885. pSize++;
  20886. q = q.nextZ;
  20887. if (!q) break;
  20888. }
  20889. qSize = inSize;
  20890. while (pSize > 0 || qSize > 0 && q) {
  20891. if (pSize !== 0 && (qSize === 0 || !q || p.z <= q.z)) {
  20892. e = p;
  20893. p = p.nextZ;
  20894. pSize--;
  20895. } else {
  20896. e = q;
  20897. q = q.nextZ;
  20898. qSize--;
  20899. }
  20900. if (tail) tail.nextZ = e;else list = e;
  20901. e.prevZ = tail;
  20902. tail = e;
  20903. }
  20904. p = q;
  20905. }
  20906. tail.nextZ = null;
  20907. inSize *= 2;
  20908. } while (numMerges > 1);
  20909. return list;
  20910. } // z-order of a point given coords and inverse of the longer side of data bbox
  20911. function zOrder(x, y, minX, minY, invSize) {
  20912. // coords are transformed into non-negative 15-bit integer range
  20913. x = 32767 * (x - minX) * invSize;
  20914. y = 32767 * (y - minY) * invSize;
  20915. x = (x | x << 8) & 0x00FF00FF;
  20916. x = (x | x << 4) & 0x0F0F0F0F;
  20917. x = (x | x << 2) & 0x33333333;
  20918. x = (x | x << 1) & 0x55555555;
  20919. y = (y | y << 8) & 0x00FF00FF;
  20920. y = (y | y << 4) & 0x0F0F0F0F;
  20921. y = (y | y << 2) & 0x33333333;
  20922. y = (y | y << 1) & 0x55555555;
  20923. return x | y << 1;
  20924. } // find the leftmost node of a polygon ring
  20925. function getLeftmost(start) {
  20926. let p = start,
  20927. leftmost = start;
  20928. do {
  20929. if (p.x < leftmost.x || p.x === leftmost.x && p.y < leftmost.y) leftmost = p;
  20930. p = p.next;
  20931. } while (p !== start);
  20932. return leftmost;
  20933. } // check if a point lies within a convex triangle
  20934. function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {
  20935. return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;
  20936. } // check if a diagonal between two polygon nodes is valid (lies in polygon interior)
  20937. function isValidDiagonal(a, b) {
  20938. return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && ( // doesn't intersect other edges
  20939. locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b) && ( // locally visible
  20940. area(a.prev, a, b.prev) || area(a, b.prev, b)) || // does not create opposite-facing sectors
  20941. equals(a, b) && area(a.prev, a, a.next) > 0 && area(b.prev, b, b.next) > 0); // special zero-length case
  20942. } // signed area of a triangle
  20943. function area(p, q, r) {
  20944. return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);
  20945. } // check if two points are equal
  20946. function equals(p1, p2) {
  20947. return p1.x === p2.x && p1.y === p2.y;
  20948. } // check if two segments intersect
  20949. function intersects(p1, q1, p2, q2) {
  20950. const o1 = sign(area(p1, q1, p2));
  20951. const o2 = sign(area(p1, q1, q2));
  20952. const o3 = sign(area(p2, q2, p1));
  20953. const o4 = sign(area(p2, q2, q1));
  20954. if (o1 !== o2 && o3 !== o4) return true; // general case
  20955. if (o1 === 0 && onSegment(p1, p2, q1)) return true; // p1, q1 and p2 are collinear and p2 lies on p1q1
  20956. if (o2 === 0 && onSegment(p1, q2, q1)) return true; // p1, q1 and q2 are collinear and q2 lies on p1q1
  20957. if (o3 === 0 && onSegment(p2, p1, q2)) return true; // p2, q2 and p1 are collinear and p1 lies on p2q2
  20958. if (o4 === 0 && onSegment(p2, q1, q2)) return true; // p2, q2 and q1 are collinear and q1 lies on p2q2
  20959. return false;
  20960. } // for collinear points p, q, r, check if point q lies on segment pr
  20961. function onSegment(p, q, r) {
  20962. return q.x <= Math.max(p.x, r.x) && q.x >= Math.min(p.x, r.x) && q.y <= Math.max(p.y, r.y) && q.y >= Math.min(p.y, r.y);
  20963. }
  20964. function sign(num) {
  20965. return num > 0 ? 1 : num < 0 ? -1 : 0;
  20966. } // check if a polygon diagonal intersects any polygon segments
  20967. function intersectsPolygon(a, b) {
  20968. let p = a;
  20969. do {
  20970. if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && intersects(p, p.next, a, b)) return true;
  20971. p = p.next;
  20972. } while (p !== a);
  20973. return false;
  20974. } // check if a polygon diagonal is locally inside the polygon
  20975. function locallyInside(a, b) {
  20976. return area(a.prev, a, a.next) < 0 ? area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;
  20977. } // check if the middle point of a polygon diagonal is inside the polygon
  20978. function middleInside(a, b) {
  20979. let p = a,
  20980. inside = false;
  20981. const px = (a.x + b.x) / 2,
  20982. py = (a.y + b.y) / 2;
  20983. do {
  20984. if (p.y > py !== p.next.y > py && p.next.y !== p.y && px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x) inside = !inside;
  20985. p = p.next;
  20986. } while (p !== a);
  20987. return inside;
  20988. } // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;
  20989. // if one belongs to the outer ring and another to a hole, it merges it into a single ring
  20990. function splitPolygon(a, b) {
  20991. const a2 = new Node(a.i, a.x, a.y),
  20992. b2 = new Node(b.i, b.x, b.y),
  20993. an = a.next,
  20994. bp = b.prev;
  20995. a.next = b;
  20996. b.prev = a;
  20997. a2.next = an;
  20998. an.prev = a2;
  20999. b2.next = a2;
  21000. a2.prev = b2;
  21001. bp.next = b2;
  21002. b2.prev = bp;
  21003. return b2;
  21004. } // create a node and optionally link it with previous one (in a circular doubly linked list)
  21005. function insertNode(i, x, y, last) {
  21006. const p = new Node(i, x, y);
  21007. if (!last) {
  21008. p.prev = p;
  21009. p.next = p;
  21010. } else {
  21011. p.next = last.next;
  21012. p.prev = last;
  21013. last.next.prev = p;
  21014. last.next = p;
  21015. }
  21016. return p;
  21017. }
  21018. function removeNode(p) {
  21019. p.next.prev = p.prev;
  21020. p.prev.next = p.next;
  21021. if (p.prevZ) p.prevZ.nextZ = p.nextZ;
  21022. if (p.nextZ) p.nextZ.prevZ = p.prevZ;
  21023. }
  21024. function Node(i, x, y) {
  21025. // vertex index in coordinates array
  21026. this.i = i; // vertex coordinates
  21027. this.x = x;
  21028. this.y = y; // previous and next vertex nodes in a polygon ring
  21029. this.prev = null;
  21030. this.next = null; // z-order curve value
  21031. this.z = null; // previous and next nodes in z-order
  21032. this.prevZ = null;
  21033. this.nextZ = null; // indicates whether this is a steiner point
  21034. this.steiner = false;
  21035. }
  21036. function signedArea(data, start, end, dim) {
  21037. let sum = 0;
  21038. for (let i = start, j = end - dim; i < end; i += dim) {
  21039. sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);
  21040. j = i;
  21041. }
  21042. return sum;
  21043. }
  21044. class ShapeUtils {
  21045. // calculate area of the contour polygon
  21046. static area(contour) {
  21047. const n = contour.length;
  21048. let a = 0.0;
  21049. for (let p = n - 1, q = 0; q < n; p = q++) {
  21050. a += contour[p].x * contour[q].y - contour[q].x * contour[p].y;
  21051. }
  21052. return a * 0.5;
  21053. }
  21054. static isClockWise(pts) {
  21055. return ShapeUtils.area(pts) < 0;
  21056. }
  21057. static triangulateShape(contour, holes) {
  21058. const vertices = []; // flat array of vertices like [ x0,y0, x1,y1, x2,y2, ... ]
  21059. const holeIndices = []; // array of hole indices
  21060. const faces = []; // final array of vertex indices like [ [ a,b,d ], [ b,c,d ] ]
  21061. removeDupEndPts(contour);
  21062. addContour(vertices, contour); //
  21063. let holeIndex = contour.length;
  21064. holes.forEach(removeDupEndPts);
  21065. for (let i = 0; i < holes.length; i++) {
  21066. holeIndices.push(holeIndex);
  21067. holeIndex += holes[i].length;
  21068. addContour(vertices, holes[i]);
  21069. } //
  21070. const triangles = Earcut.triangulate(vertices, holeIndices); //
  21071. for (let i = 0; i < triangles.length; i += 3) {
  21072. faces.push(triangles.slice(i, i + 3));
  21073. }
  21074. return faces;
  21075. }
  21076. }
  21077. function removeDupEndPts(points) {
  21078. const l = points.length;
  21079. if (l > 2 && points[l - 1].equals(points[0])) {
  21080. points.pop();
  21081. }
  21082. }
  21083. function addContour(vertices, contour) {
  21084. for (let i = 0; i < contour.length; i++) {
  21085. vertices.push(contour[i].x);
  21086. vertices.push(contour[i].y);
  21087. }
  21088. }
  21089. /**
  21090. * Creates extruded geometry from a path shape.
  21091. *
  21092. * parameters = {
  21093. *
  21094. * curveSegments: <int>, // number of points on the curves
  21095. * steps: <int>, // number of points for z-side extrusions / used for subdividing segments of extrude spline too
  21096. * depth: <float>, // Depth to extrude the shape
  21097. *
  21098. * bevelEnabled: <bool>, // turn on bevel
  21099. * bevelThickness: <float>, // how deep into the original shape bevel goes
  21100. * bevelSize: <float>, // how far from shape outline (including bevelOffset) is bevel
  21101. * bevelOffset: <float>, // how far from shape outline does bevel start
  21102. * bevelSegments: <int>, // number of bevel layers
  21103. *
  21104. * extrudePath: <THREE.Curve> // curve to extrude shape along
  21105. *
  21106. * UVGenerator: <Object> // object that provides UV generator functions
  21107. *
  21108. * }
  21109. */
  21110. class ExtrudeGeometry extends BufferGeometry {
  21111. constructor(shapes = new Shape([new Vector2(0.5, 0.5), new Vector2(-0.5, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), options = {}) {
  21112. super();
  21113. this.type = 'ExtrudeGeometry';
  21114. this.parameters = {
  21115. shapes: shapes,
  21116. options: options
  21117. };
  21118. shapes = Array.isArray(shapes) ? shapes : [shapes];
  21119. const scope = this;
  21120. const verticesArray = [];
  21121. const uvArray = [];
  21122. for (let i = 0, l = shapes.length; i < l; i++) {
  21123. const shape = shapes[i];
  21124. addShape(shape);
  21125. } // build geometry
  21126. this.setAttribute('position', new Float32BufferAttribute(verticesArray, 3));
  21127. this.setAttribute('uv', new Float32BufferAttribute(uvArray, 2));
  21128. this.computeVertexNormals(); // functions
  21129. function addShape(shape) {
  21130. const placeholder = []; // options
  21131. const curveSegments = options.curveSegments !== undefined ? options.curveSegments : 12;
  21132. const steps = options.steps !== undefined ? options.steps : 1;
  21133. const depth = options.depth !== undefined ? options.depth : 1;
  21134. let bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true;
  21135. let bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 0.2;
  21136. let bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 0.1;
  21137. let bevelOffset = options.bevelOffset !== undefined ? options.bevelOffset : 0;
  21138. let bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
  21139. const extrudePath = options.extrudePath;
  21140. const uvgen = options.UVGenerator !== undefined ? options.UVGenerator : WorldUVGenerator; //
  21141. let extrudePts,
  21142. extrudeByPath = false;
  21143. let splineTube, binormal, normal, position2;
  21144. if (extrudePath) {
  21145. extrudePts = extrudePath.getSpacedPoints(steps);
  21146. extrudeByPath = true;
  21147. bevelEnabled = false; // bevels not supported for path extrusion
  21148. // SETUP TNB variables
  21149. // TODO1 - have a .isClosed in spline?
  21150. splineTube = extrudePath.computeFrenetFrames(steps, false); // console.log(splineTube, 'splineTube', splineTube.normals.length, 'steps', steps, 'extrudePts', extrudePts.length);
  21151. binormal = new Vector3();
  21152. normal = new Vector3();
  21153. position2 = new Vector3();
  21154. } // Safeguards if bevels are not enabled
  21155. if (!bevelEnabled) {
  21156. bevelSegments = 0;
  21157. bevelThickness = 0;
  21158. bevelSize = 0;
  21159. bevelOffset = 0;
  21160. } // Variables initialization
  21161. const shapePoints = shape.extractPoints(curveSegments);
  21162. let vertices = shapePoints.shape;
  21163. const holes = shapePoints.holes;
  21164. const reverse = !ShapeUtils.isClockWise(vertices);
  21165. if (reverse) {
  21166. vertices = vertices.reverse(); // Maybe we should also check if holes are in the opposite direction, just to be safe ...
  21167. for (let h = 0, hl = holes.length; h < hl; h++) {
  21168. const ahole = holes[h];
  21169. if (ShapeUtils.isClockWise(ahole)) {
  21170. holes[h] = ahole.reverse();
  21171. }
  21172. }
  21173. }
  21174. const faces = ShapeUtils.triangulateShape(vertices, holes);
  21175. /* Vertices */
  21176. const contour = vertices; // vertices has all points but contour has only points of circumference
  21177. for (let h = 0, hl = holes.length; h < hl; h++) {
  21178. const ahole = holes[h];
  21179. vertices = vertices.concat(ahole);
  21180. }
  21181. function scalePt2(pt, vec, size) {
  21182. if (!vec) console.error('THREE.ExtrudeGeometry: vec does not exist');
  21183. return vec.clone().multiplyScalar(size).add(pt);
  21184. }
  21185. const vlen = vertices.length,
  21186. flen = faces.length; // Find directions for point movement
  21187. function getBevelVec(inPt, inPrev, inNext) {
  21188. // computes for inPt the corresponding point inPt' on a new contour
  21189. // shifted by 1 unit (length of normalized vector) to the left
  21190. // if we walk along contour clockwise, this new contour is outside the old one
  21191. //
  21192. // inPt' is the intersection of the two lines parallel to the two
  21193. // adjacent edges of inPt at a distance of 1 unit on the left side.
  21194. let v_trans_x, v_trans_y, shrink_by; // resulting translation vector for inPt
  21195. // good reading for geometry algorithms (here: line-line intersection)
  21196. // http://geomalgorithms.com/a05-_intersect-1.html
  21197. const v_prev_x = inPt.x - inPrev.x,
  21198. v_prev_y = inPt.y - inPrev.y;
  21199. const v_next_x = inNext.x - inPt.x,
  21200. v_next_y = inNext.y - inPt.y;
  21201. const v_prev_lensq = v_prev_x * v_prev_x + v_prev_y * v_prev_y; // check for collinear edges
  21202. const collinear0 = v_prev_x * v_next_y - v_prev_y * v_next_x;
  21203. if (Math.abs(collinear0) > Number.EPSILON) {
  21204. // not collinear
  21205. // length of vectors for normalizing
  21206. const v_prev_len = Math.sqrt(v_prev_lensq);
  21207. const v_next_len = Math.sqrt(v_next_x * v_next_x + v_next_y * v_next_y); // shift adjacent points by unit vectors to the left
  21208. const ptPrevShift_x = inPrev.x - v_prev_y / v_prev_len;
  21209. const ptPrevShift_y = inPrev.y + v_prev_x / v_prev_len;
  21210. const ptNextShift_x = inNext.x - v_next_y / v_next_len;
  21211. const ptNextShift_y = inNext.y + v_next_x / v_next_len; // scaling factor for v_prev to intersection point
  21212. const sf = ((ptNextShift_x - ptPrevShift_x) * v_next_y - (ptNextShift_y - ptPrevShift_y) * v_next_x) / (v_prev_x * v_next_y - v_prev_y * v_next_x); // vector from inPt to intersection point
  21213. v_trans_x = ptPrevShift_x + v_prev_x * sf - inPt.x;
  21214. v_trans_y = ptPrevShift_y + v_prev_y * sf - inPt.y; // Don't normalize!, otherwise sharp corners become ugly
  21215. // but prevent crazy spikes
  21216. const v_trans_lensq = v_trans_x * v_trans_x + v_trans_y * v_trans_y;
  21217. if (v_trans_lensq <= 2) {
  21218. return new Vector2(v_trans_x, v_trans_y);
  21219. } else {
  21220. shrink_by = Math.sqrt(v_trans_lensq / 2);
  21221. }
  21222. } else {
  21223. // handle special case of collinear edges
  21224. let direction_eq = false; // assumes: opposite
  21225. if (v_prev_x > Number.EPSILON) {
  21226. if (v_next_x > Number.EPSILON) {
  21227. direction_eq = true;
  21228. }
  21229. } else {
  21230. if (v_prev_x < -Number.EPSILON) {
  21231. if (v_next_x < -Number.EPSILON) {
  21232. direction_eq = true;
  21233. }
  21234. } else {
  21235. if (Math.sign(v_prev_y) === Math.sign(v_next_y)) {
  21236. direction_eq = true;
  21237. }
  21238. }
  21239. }
  21240. if (direction_eq) {
  21241. // console.log("Warning: lines are a straight sequence");
  21242. v_trans_x = -v_prev_y;
  21243. v_trans_y = v_prev_x;
  21244. shrink_by = Math.sqrt(v_prev_lensq);
  21245. } else {
  21246. // console.log("Warning: lines are a straight spike");
  21247. v_trans_x = v_prev_x;
  21248. v_trans_y = v_prev_y;
  21249. shrink_by = Math.sqrt(v_prev_lensq / 2);
  21250. }
  21251. }
  21252. return new Vector2(v_trans_x / shrink_by, v_trans_y / shrink_by);
  21253. }
  21254. const contourMovements = [];
  21255. for (let i = 0, il = contour.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {
  21256. if (j === il) j = 0;
  21257. if (k === il) k = 0; // (j)---(i)---(k)
  21258. // console.log('i,j,k', i, j , k)
  21259. contourMovements[i] = getBevelVec(contour[i], contour[j], contour[k]);
  21260. }
  21261. const holesMovements = [];
  21262. let oneHoleMovements,
  21263. verticesMovements = contourMovements.concat();
  21264. for (let h = 0, hl = holes.length; h < hl; h++) {
  21265. const ahole = holes[h];
  21266. oneHoleMovements = [];
  21267. for (let i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i++, j++, k++) {
  21268. if (j === il) j = 0;
  21269. if (k === il) k = 0; // (j)---(i)---(k)
  21270. oneHoleMovements[i] = getBevelVec(ahole[i], ahole[j], ahole[k]);
  21271. }
  21272. holesMovements.push(oneHoleMovements);
  21273. verticesMovements = verticesMovements.concat(oneHoleMovements);
  21274. } // Loop bevelSegments, 1 for the front, 1 for the back
  21275. for (let b = 0; b < bevelSegments; b++) {
  21276. //for ( b = bevelSegments; b > 0; b -- ) {
  21277. const t = b / bevelSegments;
  21278. const z = bevelThickness * Math.cos(t * Math.PI / 2);
  21279. const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape
  21280. for (let i = 0, il = contour.length; i < il; i++) {
  21281. const vert = scalePt2(contour[i], contourMovements[i], bs);
  21282. v(vert.x, vert.y, -z);
  21283. } // expand holes
  21284. for (let h = 0, hl = holes.length; h < hl; h++) {
  21285. const ahole = holes[h];
  21286. oneHoleMovements = holesMovements[h];
  21287. for (let i = 0, il = ahole.length; i < il; i++) {
  21288. const vert = scalePt2(ahole[i], oneHoleMovements[i], bs);
  21289. v(vert.x, vert.y, -z);
  21290. }
  21291. }
  21292. }
  21293. const bs = bevelSize + bevelOffset; // Back facing vertices
  21294. for (let i = 0; i < vlen; i++) {
  21295. const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
  21296. if (!extrudeByPath) {
  21297. v(vert.x, vert.y, 0);
  21298. } else {
  21299. // v( vert.x, vert.y + extrudePts[ 0 ].y, extrudePts[ 0 ].x );
  21300. normal.copy(splineTube.normals[0]).multiplyScalar(vert.x);
  21301. binormal.copy(splineTube.binormals[0]).multiplyScalar(vert.y);
  21302. position2.copy(extrudePts[0]).add(normal).add(binormal);
  21303. v(position2.x, position2.y, position2.z);
  21304. }
  21305. } // Add stepped vertices...
  21306. // Including front facing vertices
  21307. for (let s = 1; s <= steps; s++) {
  21308. for (let i = 0; i < vlen; i++) {
  21309. const vert = bevelEnabled ? scalePt2(vertices[i], verticesMovements[i], bs) : vertices[i];
  21310. if (!extrudeByPath) {
  21311. v(vert.x, vert.y, depth / steps * s);
  21312. } else {
  21313. // v( vert.x, vert.y + extrudePts[ s - 1 ].y, extrudePts[ s - 1 ].x );
  21314. normal.copy(splineTube.normals[s]).multiplyScalar(vert.x);
  21315. binormal.copy(splineTube.binormals[s]).multiplyScalar(vert.y);
  21316. position2.copy(extrudePts[s]).add(normal).add(binormal);
  21317. v(position2.x, position2.y, position2.z);
  21318. }
  21319. }
  21320. } // Add bevel segments planes
  21321. //for ( b = 1; b <= bevelSegments; b ++ ) {
  21322. for (let b = bevelSegments - 1; b >= 0; b--) {
  21323. const t = b / bevelSegments;
  21324. const z = bevelThickness * Math.cos(t * Math.PI / 2);
  21325. const bs = bevelSize * Math.sin(t * Math.PI / 2) + bevelOffset; // contract shape
  21326. for (let i = 0, il = contour.length; i < il; i++) {
  21327. const vert = scalePt2(contour[i], contourMovements[i], bs);
  21328. v(vert.x, vert.y, depth + z);
  21329. } // expand holes
  21330. for (let h = 0, hl = holes.length; h < hl; h++) {
  21331. const ahole = holes[h];
  21332. oneHoleMovements = holesMovements[h];
  21333. for (let i = 0, il = ahole.length; i < il; i++) {
  21334. const vert = scalePt2(ahole[i], oneHoleMovements[i], bs);
  21335. if (!extrudeByPath) {
  21336. v(vert.x, vert.y, depth + z);
  21337. } else {
  21338. v(vert.x, vert.y + extrudePts[steps - 1].y, extrudePts[steps - 1].x + z);
  21339. }
  21340. }
  21341. }
  21342. }
  21343. /* Faces */
  21344. // Top and bottom faces
  21345. buildLidFaces(); // Sides faces
  21346. buildSideFaces(); ///// Internal functions
  21347. function buildLidFaces() {
  21348. const start = verticesArray.length / 3;
  21349. if (bevelEnabled) {
  21350. let layer = 0; // steps + 1
  21351. let offset = vlen * layer; // Bottom faces
  21352. for (let i = 0; i < flen; i++) {
  21353. const face = faces[i];
  21354. f3(face[2] + offset, face[1] + offset, face[0] + offset);
  21355. }
  21356. layer = steps + bevelSegments * 2;
  21357. offset = vlen * layer; // Top faces
  21358. for (let i = 0; i < flen; i++) {
  21359. const face = faces[i];
  21360. f3(face[0] + offset, face[1] + offset, face[2] + offset);
  21361. }
  21362. } else {
  21363. // Bottom faces
  21364. for (let i = 0; i < flen; i++) {
  21365. const face = faces[i];
  21366. f3(face[2], face[1], face[0]);
  21367. } // Top faces
  21368. for (let i = 0; i < flen; i++) {
  21369. const face = faces[i];
  21370. f3(face[0] + vlen * steps, face[1] + vlen * steps, face[2] + vlen * steps);
  21371. }
  21372. }
  21373. scope.addGroup(start, verticesArray.length / 3 - start, 0);
  21374. } // Create faces for the z-sides of the shape
  21375. function buildSideFaces() {
  21376. const start = verticesArray.length / 3;
  21377. let layeroffset = 0;
  21378. sidewalls(contour, layeroffset);
  21379. layeroffset += contour.length;
  21380. for (let h = 0, hl = holes.length; h < hl; h++) {
  21381. const ahole = holes[h];
  21382. sidewalls(ahole, layeroffset); //, true
  21383. layeroffset += ahole.length;
  21384. }
  21385. scope.addGroup(start, verticesArray.length / 3 - start, 1);
  21386. }
  21387. function sidewalls(contour, layeroffset) {
  21388. let i = contour.length;
  21389. while (--i >= 0) {
  21390. const j = i;
  21391. let k = i - 1;
  21392. if (k < 0) k = contour.length - 1; //console.log('b', i,j, i-1, k,vertices.length);
  21393. for (let s = 0, sl = steps + bevelSegments * 2; s < sl; s++) {
  21394. const slen1 = vlen * s;
  21395. const slen2 = vlen * (s + 1);
  21396. const a = layeroffset + j + slen1,
  21397. b = layeroffset + k + slen1,
  21398. c = layeroffset + k + slen2,
  21399. d = layeroffset + j + slen2;
  21400. f4(a, b, c, d);
  21401. }
  21402. }
  21403. }
  21404. function v(x, y, z) {
  21405. placeholder.push(x);
  21406. placeholder.push(y);
  21407. placeholder.push(z);
  21408. }
  21409. function f3(a, b, c) {
  21410. addVertex(a);
  21411. addVertex(b);
  21412. addVertex(c);
  21413. const nextIndex = verticesArray.length / 3;
  21414. const uvs = uvgen.generateTopUV(scope, verticesArray, nextIndex - 3, nextIndex - 2, nextIndex - 1);
  21415. addUV(uvs[0]);
  21416. addUV(uvs[1]);
  21417. addUV(uvs[2]);
  21418. }
  21419. function f4(a, b, c, d) {
  21420. addVertex(a);
  21421. addVertex(b);
  21422. addVertex(d);
  21423. addVertex(b);
  21424. addVertex(c);
  21425. addVertex(d);
  21426. const nextIndex = verticesArray.length / 3;
  21427. const uvs = uvgen.generateSideWallUV(scope, verticesArray, nextIndex - 6, nextIndex - 3, nextIndex - 2, nextIndex - 1);
  21428. addUV(uvs[0]);
  21429. addUV(uvs[1]);
  21430. addUV(uvs[3]);
  21431. addUV(uvs[1]);
  21432. addUV(uvs[2]);
  21433. addUV(uvs[3]);
  21434. }
  21435. function addVertex(index) {
  21436. verticesArray.push(placeholder[index * 3 + 0]);
  21437. verticesArray.push(placeholder[index * 3 + 1]);
  21438. verticesArray.push(placeholder[index * 3 + 2]);
  21439. }
  21440. function addUV(vector2) {
  21441. uvArray.push(vector2.x);
  21442. uvArray.push(vector2.y);
  21443. }
  21444. }
  21445. }
  21446. toJSON() {
  21447. const data = super.toJSON();
  21448. const shapes = this.parameters.shapes;
  21449. const options = this.parameters.options;
  21450. return toJSON$1(shapes, options, data);
  21451. }
  21452. static fromJSON(data, shapes) {
  21453. const geometryShapes = [];
  21454. for (let j = 0, jl = data.shapes.length; j < jl; j++) {
  21455. const shape = shapes[data.shapes[j]];
  21456. geometryShapes.push(shape);
  21457. }
  21458. const extrudePath = data.options.extrudePath;
  21459. if (extrudePath !== undefined) {
  21460. data.options.extrudePath = new Curves[extrudePath.type]().fromJSON(extrudePath);
  21461. }
  21462. return new ExtrudeGeometry(geometryShapes, data.options);
  21463. }
  21464. }
  21465. const WorldUVGenerator = {
  21466. generateTopUV: function (geometry, vertices, indexA, indexB, indexC) {
  21467. const a_x = vertices[indexA * 3];
  21468. const a_y = vertices[indexA * 3 + 1];
  21469. const b_x = vertices[indexB * 3];
  21470. const b_y = vertices[indexB * 3 + 1];
  21471. const c_x = vertices[indexC * 3];
  21472. const c_y = vertices[indexC * 3 + 1];
  21473. return [new Vector2(a_x, a_y), new Vector2(b_x, b_y), new Vector2(c_x, c_y)];
  21474. },
  21475. generateSideWallUV: function (geometry, vertices, indexA, indexB, indexC, indexD) {
  21476. const a_x = vertices[indexA * 3];
  21477. const a_y = vertices[indexA * 3 + 1];
  21478. const a_z = vertices[indexA * 3 + 2];
  21479. const b_x = vertices[indexB * 3];
  21480. const b_y = vertices[indexB * 3 + 1];
  21481. const b_z = vertices[indexB * 3 + 2];
  21482. const c_x = vertices[indexC * 3];
  21483. const c_y = vertices[indexC * 3 + 1];
  21484. const c_z = vertices[indexC * 3 + 2];
  21485. const d_x = vertices[indexD * 3];
  21486. const d_y = vertices[indexD * 3 + 1];
  21487. const d_z = vertices[indexD * 3 + 2];
  21488. if (Math.abs(a_y - b_y) < Math.abs(a_x - b_x)) {
  21489. return [new Vector2(a_x, 1 - a_z), new Vector2(b_x, 1 - b_z), new Vector2(c_x, 1 - c_z), new Vector2(d_x, 1 - d_z)];
  21490. } else {
  21491. return [new Vector2(a_y, 1 - a_z), new Vector2(b_y, 1 - b_z), new Vector2(c_y, 1 - c_z), new Vector2(d_y, 1 - d_z)];
  21492. }
  21493. }
  21494. };
  21495. function toJSON$1(shapes, options, data) {
  21496. data.shapes = [];
  21497. if (Array.isArray(shapes)) {
  21498. for (let i = 0, l = shapes.length; i < l; i++) {
  21499. const shape = shapes[i];
  21500. data.shapes.push(shape.uuid);
  21501. }
  21502. } else {
  21503. data.shapes.push(shapes.uuid);
  21504. }
  21505. data.options = Object.assign({}, options);
  21506. if (options.extrudePath !== undefined) data.options.extrudePath = options.extrudePath.toJSON();
  21507. return data;
  21508. }
  21509. class IcosahedronGeometry extends PolyhedronGeometry {
  21510. constructor(radius = 1, detail = 0) {
  21511. const t = (1 + Math.sqrt(5)) / 2;
  21512. const vertices = [-1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, 0, 0, -1, t, 0, 1, t, 0, -1, -t, 0, 1, -t, t, 0, -1, t, 0, 1, -t, 0, -1, -t, 0, 1];
  21513. const indices = [0, 11, 5, 0, 5, 1, 0, 1, 7, 0, 7, 10, 0, 10, 11, 1, 5, 9, 5, 11, 4, 11, 10, 2, 10, 7, 6, 7, 1, 8, 3, 9, 4, 3, 4, 2, 3, 2, 6, 3, 6, 8, 3, 8, 9, 4, 9, 5, 2, 4, 11, 6, 2, 10, 8, 6, 7, 9, 8, 1];
  21514. super(vertices, indices, radius, detail);
  21515. this.type = 'IcosahedronGeometry';
  21516. this.parameters = {
  21517. radius: radius,
  21518. detail: detail
  21519. };
  21520. }
  21521. static fromJSON(data) {
  21522. return new IcosahedronGeometry(data.radius, data.detail);
  21523. }
  21524. }
  21525. class OctahedronGeometry extends PolyhedronGeometry {
  21526. constructor(radius = 1, detail = 0) {
  21527. const vertices = [1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 1, 0, 0, -1];
  21528. const indices = [0, 2, 4, 0, 4, 3, 0, 3, 5, 0, 5, 2, 1, 2, 5, 1, 5, 3, 1, 3, 4, 1, 4, 2];
  21529. super(vertices, indices, radius, detail);
  21530. this.type = 'OctahedronGeometry';
  21531. this.parameters = {
  21532. radius: radius,
  21533. detail: detail
  21534. };
  21535. }
  21536. static fromJSON(data) {
  21537. return new OctahedronGeometry(data.radius, data.detail);
  21538. }
  21539. }
  21540. class RingGeometry extends BufferGeometry {
  21541. constructor(innerRadius = 0.5, outerRadius = 1, thetaSegments = 8, phiSegments = 1, thetaStart = 0, thetaLength = Math.PI * 2) {
  21542. super();
  21543. this.type = 'RingGeometry';
  21544. this.parameters = {
  21545. innerRadius: innerRadius,
  21546. outerRadius: outerRadius,
  21547. thetaSegments: thetaSegments,
  21548. phiSegments: phiSegments,
  21549. thetaStart: thetaStart,
  21550. thetaLength: thetaLength
  21551. };
  21552. thetaSegments = Math.max(3, thetaSegments);
  21553. phiSegments = Math.max(1, phiSegments); // buffers
  21554. const indices = [];
  21555. const vertices = [];
  21556. const normals = [];
  21557. const uvs = []; // some helper variables
  21558. let radius = innerRadius;
  21559. const radiusStep = (outerRadius - innerRadius) / phiSegments;
  21560. const vertex = new Vector3();
  21561. const uv = new Vector2(); // generate vertices, normals and uvs
  21562. for (let j = 0; j <= phiSegments; j++) {
  21563. for (let i = 0; i <= thetaSegments; i++) {
  21564. // values are generate from the inside of the ring to the outside
  21565. const segment = thetaStart + i / thetaSegments * thetaLength; // vertex
  21566. vertex.x = radius * Math.cos(segment);
  21567. vertex.y = radius * Math.sin(segment);
  21568. vertices.push(vertex.x, vertex.y, vertex.z); // normal
  21569. normals.push(0, 0, 1); // uv
  21570. uv.x = (vertex.x / outerRadius + 1) / 2;
  21571. uv.y = (vertex.y / outerRadius + 1) / 2;
  21572. uvs.push(uv.x, uv.y);
  21573. } // increase the radius for next row of vertices
  21574. radius += radiusStep;
  21575. } // indices
  21576. for (let j = 0; j < phiSegments; j++) {
  21577. const thetaSegmentLevel = j * (thetaSegments + 1);
  21578. for (let i = 0; i < thetaSegments; i++) {
  21579. const segment = i + thetaSegmentLevel;
  21580. const a = segment;
  21581. const b = segment + thetaSegments + 1;
  21582. const c = segment + thetaSegments + 2;
  21583. const d = segment + 1; // faces
  21584. indices.push(a, b, d);
  21585. indices.push(b, c, d);
  21586. }
  21587. } // build geometry
  21588. this.setIndex(indices);
  21589. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  21590. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  21591. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  21592. }
  21593. static fromJSON(data) {
  21594. return new RingGeometry(data.innerRadius, data.outerRadius, data.thetaSegments, data.phiSegments, data.thetaStart, data.thetaLength);
  21595. }
  21596. }
  21597. class ShapeGeometry extends BufferGeometry {
  21598. constructor(shapes = new Shape([new Vector2(0, 0.5), new Vector2(-0.5, -0.5), new Vector2(0.5, -0.5)]), curveSegments = 12) {
  21599. super();
  21600. this.type = 'ShapeGeometry';
  21601. this.parameters = {
  21602. shapes: shapes,
  21603. curveSegments: curveSegments
  21604. }; // buffers
  21605. const indices = [];
  21606. const vertices = [];
  21607. const normals = [];
  21608. const uvs = []; // helper variables
  21609. let groupStart = 0;
  21610. let groupCount = 0; // allow single and array values for "shapes" parameter
  21611. if (Array.isArray(shapes) === false) {
  21612. addShape(shapes);
  21613. } else {
  21614. for (let i = 0; i < shapes.length; i++) {
  21615. addShape(shapes[i]);
  21616. this.addGroup(groupStart, groupCount, i); // enables MultiMaterial support
  21617. groupStart += groupCount;
  21618. groupCount = 0;
  21619. }
  21620. } // build geometry
  21621. this.setIndex(indices);
  21622. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  21623. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  21624. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // helper functions
  21625. function addShape(shape) {
  21626. const indexOffset = vertices.length / 3;
  21627. const points = shape.extractPoints(curveSegments);
  21628. let shapeVertices = points.shape;
  21629. const shapeHoles = points.holes; // check direction of vertices
  21630. if (ShapeUtils.isClockWise(shapeVertices) === false) {
  21631. shapeVertices = shapeVertices.reverse();
  21632. }
  21633. for (let i = 0, l = shapeHoles.length; i < l; i++) {
  21634. const shapeHole = shapeHoles[i];
  21635. if (ShapeUtils.isClockWise(shapeHole) === true) {
  21636. shapeHoles[i] = shapeHole.reverse();
  21637. }
  21638. }
  21639. const faces = ShapeUtils.triangulateShape(shapeVertices, shapeHoles); // join vertices of inner and outer paths to a single array
  21640. for (let i = 0, l = shapeHoles.length; i < l; i++) {
  21641. const shapeHole = shapeHoles[i];
  21642. shapeVertices = shapeVertices.concat(shapeHole);
  21643. } // vertices, normals, uvs
  21644. for (let i = 0, l = shapeVertices.length; i < l; i++) {
  21645. const vertex = shapeVertices[i];
  21646. vertices.push(vertex.x, vertex.y, 0);
  21647. normals.push(0, 0, 1);
  21648. uvs.push(vertex.x, vertex.y); // world uvs
  21649. } // incides
  21650. for (let i = 0, l = faces.length; i < l; i++) {
  21651. const face = faces[i];
  21652. const a = face[0] + indexOffset;
  21653. const b = face[1] + indexOffset;
  21654. const c = face[2] + indexOffset;
  21655. indices.push(a, b, c);
  21656. groupCount += 3;
  21657. }
  21658. }
  21659. }
  21660. toJSON() {
  21661. const data = super.toJSON();
  21662. const shapes = this.parameters.shapes;
  21663. return toJSON(shapes, data);
  21664. }
  21665. static fromJSON(data, shapes) {
  21666. const geometryShapes = [];
  21667. for (let j = 0, jl = data.shapes.length; j < jl; j++) {
  21668. const shape = shapes[data.shapes[j]];
  21669. geometryShapes.push(shape);
  21670. }
  21671. return new ShapeGeometry(geometryShapes, data.curveSegments);
  21672. }
  21673. }
  21674. function toJSON(shapes, data) {
  21675. data.shapes = [];
  21676. if (Array.isArray(shapes)) {
  21677. for (let i = 0, l = shapes.length; i < l; i++) {
  21678. const shape = shapes[i];
  21679. data.shapes.push(shape.uuid);
  21680. }
  21681. } else {
  21682. data.shapes.push(shapes.uuid);
  21683. }
  21684. return data;
  21685. }
  21686. class SphereGeometry extends BufferGeometry {
  21687. constructor(radius = 1, widthSegments = 32, heightSegments = 16, phiStart = 0, phiLength = Math.PI * 2, thetaStart = 0, thetaLength = Math.PI) {
  21688. super();
  21689. this.type = 'SphereGeometry';
  21690. this.parameters = {
  21691. radius: radius,
  21692. widthSegments: widthSegments,
  21693. heightSegments: heightSegments,
  21694. phiStart: phiStart,
  21695. phiLength: phiLength,
  21696. thetaStart: thetaStart,
  21697. thetaLength: thetaLength
  21698. };
  21699. widthSegments = Math.max(3, Math.floor(widthSegments));
  21700. heightSegments = Math.max(2, Math.floor(heightSegments));
  21701. const thetaEnd = Math.min(thetaStart + thetaLength, Math.PI);
  21702. let index = 0;
  21703. const grid = [];
  21704. const vertex = new Vector3();
  21705. const normal = new Vector3(); // buffers
  21706. const indices = [];
  21707. const vertices = [];
  21708. const normals = [];
  21709. const uvs = []; // generate vertices, normals and uvs
  21710. for (let iy = 0; iy <= heightSegments; iy++) {
  21711. const verticesRow = [];
  21712. const v = iy / heightSegments; // special case for the poles
  21713. let uOffset = 0;
  21714. if (iy == 0 && thetaStart == 0) {
  21715. uOffset = 0.5 / widthSegments;
  21716. } else if (iy == heightSegments && thetaEnd == Math.PI) {
  21717. uOffset = -0.5 / widthSegments;
  21718. }
  21719. for (let ix = 0; ix <= widthSegments; ix++) {
  21720. const u = ix / widthSegments; // vertex
  21721. vertex.x = -radius * Math.cos(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
  21722. vertex.y = radius * Math.cos(thetaStart + v * thetaLength);
  21723. vertex.z = radius * Math.sin(phiStart + u * phiLength) * Math.sin(thetaStart + v * thetaLength);
  21724. vertices.push(vertex.x, vertex.y, vertex.z); // normal
  21725. normal.copy(vertex).normalize();
  21726. normals.push(normal.x, normal.y, normal.z); // uv
  21727. uvs.push(u + uOffset, 1 - v);
  21728. verticesRow.push(index++);
  21729. }
  21730. grid.push(verticesRow);
  21731. } // indices
  21732. for (let iy = 0; iy < heightSegments; iy++) {
  21733. for (let ix = 0; ix < widthSegments; ix++) {
  21734. const a = grid[iy][ix + 1];
  21735. const b = grid[iy][ix];
  21736. const c = grid[iy + 1][ix];
  21737. const d = grid[iy + 1][ix + 1];
  21738. if (iy !== 0 || thetaStart > 0) indices.push(a, b, d);
  21739. if (iy !== heightSegments - 1 || thetaEnd < Math.PI) indices.push(b, c, d);
  21740. }
  21741. } // build geometry
  21742. this.setIndex(indices);
  21743. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  21744. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  21745. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  21746. }
  21747. static fromJSON(data) {
  21748. return new SphereGeometry(data.radius, data.widthSegments, data.heightSegments, data.phiStart, data.phiLength, data.thetaStart, data.thetaLength);
  21749. }
  21750. }
  21751. class TetrahedronGeometry extends PolyhedronGeometry {
  21752. constructor(radius = 1, detail = 0) {
  21753. const vertices = [1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1];
  21754. const indices = [2, 1, 0, 0, 3, 2, 1, 3, 0, 2, 3, 1];
  21755. super(vertices, indices, radius, detail);
  21756. this.type = 'TetrahedronGeometry';
  21757. this.parameters = {
  21758. radius: radius,
  21759. detail: detail
  21760. };
  21761. }
  21762. static fromJSON(data) {
  21763. return new TetrahedronGeometry(data.radius, data.detail);
  21764. }
  21765. }
  21766. class TorusGeometry extends BufferGeometry {
  21767. constructor(radius = 1, tube = 0.4, radialSegments = 8, tubularSegments = 6, arc = Math.PI * 2) {
  21768. super();
  21769. this.type = 'TorusGeometry';
  21770. this.parameters = {
  21771. radius: radius,
  21772. tube: tube,
  21773. radialSegments: radialSegments,
  21774. tubularSegments: tubularSegments,
  21775. arc: arc
  21776. };
  21777. radialSegments = Math.floor(radialSegments);
  21778. tubularSegments = Math.floor(tubularSegments); // buffers
  21779. const indices = [];
  21780. const vertices = [];
  21781. const normals = [];
  21782. const uvs = []; // helper variables
  21783. const center = new Vector3();
  21784. const vertex = new Vector3();
  21785. const normal = new Vector3(); // generate vertices, normals and uvs
  21786. for (let j = 0; j <= radialSegments; j++) {
  21787. for (let i = 0; i <= tubularSegments; i++) {
  21788. const u = i / tubularSegments * arc;
  21789. const v = j / radialSegments * Math.PI * 2; // vertex
  21790. vertex.x = (radius + tube * Math.cos(v)) * Math.cos(u);
  21791. vertex.y = (radius + tube * Math.cos(v)) * Math.sin(u);
  21792. vertex.z = tube * Math.sin(v);
  21793. vertices.push(vertex.x, vertex.y, vertex.z); // normal
  21794. center.x = radius * Math.cos(u);
  21795. center.y = radius * Math.sin(u);
  21796. normal.subVectors(vertex, center).normalize();
  21797. normals.push(normal.x, normal.y, normal.z); // uv
  21798. uvs.push(i / tubularSegments);
  21799. uvs.push(j / radialSegments);
  21800. }
  21801. } // generate indices
  21802. for (let j = 1; j <= radialSegments; j++) {
  21803. for (let i = 1; i <= tubularSegments; i++) {
  21804. // indices
  21805. const a = (tubularSegments + 1) * j + i - 1;
  21806. const b = (tubularSegments + 1) * (j - 1) + i - 1;
  21807. const c = (tubularSegments + 1) * (j - 1) + i;
  21808. const d = (tubularSegments + 1) * j + i; // faces
  21809. indices.push(a, b, d);
  21810. indices.push(b, c, d);
  21811. }
  21812. } // build geometry
  21813. this.setIndex(indices);
  21814. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  21815. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  21816. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2));
  21817. }
  21818. static fromJSON(data) {
  21819. return new TorusGeometry(data.radius, data.tube, data.radialSegments, data.tubularSegments, data.arc);
  21820. }
  21821. }
  21822. class TorusKnotGeometry extends BufferGeometry {
  21823. constructor(radius = 1, tube = 0.4, tubularSegments = 64, radialSegments = 8, p = 2, q = 3) {
  21824. super();
  21825. this.type = 'TorusKnotGeometry';
  21826. this.parameters = {
  21827. radius: radius,
  21828. tube: tube,
  21829. tubularSegments: tubularSegments,
  21830. radialSegments: radialSegments,
  21831. p: p,
  21832. q: q
  21833. };
  21834. tubularSegments = Math.floor(tubularSegments);
  21835. radialSegments = Math.floor(radialSegments); // buffers
  21836. const indices = [];
  21837. const vertices = [];
  21838. const normals = [];
  21839. const uvs = []; // helper variables
  21840. const vertex = new Vector3();
  21841. const normal = new Vector3();
  21842. const P1 = new Vector3();
  21843. const P2 = new Vector3();
  21844. const B = new Vector3();
  21845. const T = new Vector3();
  21846. const N = new Vector3(); // generate vertices, normals and uvs
  21847. for (let i = 0; i <= tubularSegments; ++i) {
  21848. // the radian "u" is used to calculate the position on the torus curve of the current tubular segment
  21849. const u = i / tubularSegments * p * Math.PI * 2; // now we calculate two points. P1 is our current position on the curve, P2 is a little farther ahead.
  21850. // these points are used to create a special "coordinate space", which is necessary to calculate the correct vertex positions
  21851. calculatePositionOnCurve(u, p, q, radius, P1);
  21852. calculatePositionOnCurve(u + 0.01, p, q, radius, P2); // calculate orthonormal basis
  21853. T.subVectors(P2, P1);
  21854. N.addVectors(P2, P1);
  21855. B.crossVectors(T, N);
  21856. N.crossVectors(B, T); // normalize B, N. T can be ignored, we don't use it
  21857. B.normalize();
  21858. N.normalize();
  21859. for (let j = 0; j <= radialSegments; ++j) {
  21860. // now calculate the vertices. they are nothing more than an extrusion of the torus curve.
  21861. // because we extrude a shape in the xy-plane, there is no need to calculate a z-value.
  21862. const v = j / radialSegments * Math.PI * 2;
  21863. const cx = -tube * Math.cos(v);
  21864. const cy = tube * Math.sin(v); // now calculate the final vertex position.
  21865. // first we orient the extrusion with our basis vectors, then we add it to the current position on the curve
  21866. vertex.x = P1.x + (cx * N.x + cy * B.x);
  21867. vertex.y = P1.y + (cx * N.y + cy * B.y);
  21868. vertex.z = P1.z + (cx * N.z + cy * B.z);
  21869. vertices.push(vertex.x, vertex.y, vertex.z); // normal (P1 is always the center/origin of the extrusion, thus we can use it to calculate the normal)
  21870. normal.subVectors(vertex, P1).normalize();
  21871. normals.push(normal.x, normal.y, normal.z); // uv
  21872. uvs.push(i / tubularSegments);
  21873. uvs.push(j / radialSegments);
  21874. }
  21875. } // generate indices
  21876. for (let j = 1; j <= tubularSegments; j++) {
  21877. for (let i = 1; i <= radialSegments; i++) {
  21878. // indices
  21879. const a = (radialSegments + 1) * (j - 1) + (i - 1);
  21880. const b = (radialSegments + 1) * j + (i - 1);
  21881. const c = (radialSegments + 1) * j + i;
  21882. const d = (radialSegments + 1) * (j - 1) + i; // faces
  21883. indices.push(a, b, d);
  21884. indices.push(b, c, d);
  21885. }
  21886. } // build geometry
  21887. this.setIndex(indices);
  21888. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  21889. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  21890. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // this function calculates the current position on the torus curve
  21891. function calculatePositionOnCurve(u, p, q, radius, position) {
  21892. const cu = Math.cos(u);
  21893. const su = Math.sin(u);
  21894. const quOverP = q / p * u;
  21895. const cs = Math.cos(quOverP);
  21896. position.x = radius * (2 + cs) * 0.5 * cu;
  21897. position.y = radius * (2 + cs) * su * 0.5;
  21898. position.z = radius * Math.sin(quOverP) * 0.5;
  21899. }
  21900. }
  21901. static fromJSON(data) {
  21902. return new TorusKnotGeometry(data.radius, data.tube, data.tubularSegments, data.radialSegments, data.p, data.q);
  21903. }
  21904. }
  21905. class TubeGeometry extends BufferGeometry {
  21906. constructor(path = new QuadraticBezierCurve3(new Vector3(-1, -1, 0), new Vector3(-1, 1, 0), new Vector3(1, 1, 0)), tubularSegments = 64, radius = 1, radialSegments = 8, closed = false) {
  21907. super();
  21908. this.type = 'TubeGeometry';
  21909. this.parameters = {
  21910. path: path,
  21911. tubularSegments: tubularSegments,
  21912. radius: radius,
  21913. radialSegments: radialSegments,
  21914. closed: closed
  21915. };
  21916. const frames = path.computeFrenetFrames(tubularSegments, closed); // expose internals
  21917. this.tangents = frames.tangents;
  21918. this.normals = frames.normals;
  21919. this.binormals = frames.binormals; // helper variables
  21920. const vertex = new Vector3();
  21921. const normal = new Vector3();
  21922. const uv = new Vector2();
  21923. let P = new Vector3(); // buffer
  21924. const vertices = [];
  21925. const normals = [];
  21926. const uvs = [];
  21927. const indices = []; // create buffer data
  21928. generateBufferData(); // build geometry
  21929. this.setIndex(indices);
  21930. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  21931. this.setAttribute('normal', new Float32BufferAttribute(normals, 3));
  21932. this.setAttribute('uv', new Float32BufferAttribute(uvs, 2)); // functions
  21933. function generateBufferData() {
  21934. for (let i = 0; i < tubularSegments; i++) {
  21935. generateSegment(i);
  21936. } // if the geometry is not closed, generate the last row of vertices and normals
  21937. // at the regular position on the given path
  21938. //
  21939. // if the geometry is closed, duplicate the first row of vertices and normals (uvs will differ)
  21940. generateSegment(closed === false ? tubularSegments : 0); // uvs are generated in a separate function.
  21941. // this makes it easy compute correct values for closed geometries
  21942. generateUVs(); // finally create faces
  21943. generateIndices();
  21944. }
  21945. function generateSegment(i) {
  21946. // we use getPointAt to sample evenly distributed points from the given path
  21947. P = path.getPointAt(i / tubularSegments, P); // retrieve corresponding normal and binormal
  21948. const N = frames.normals[i];
  21949. const B = frames.binormals[i]; // generate normals and vertices for the current segment
  21950. for (let j = 0; j <= radialSegments; j++) {
  21951. const v = j / radialSegments * Math.PI * 2;
  21952. const sin = Math.sin(v);
  21953. const cos = -Math.cos(v); // normal
  21954. normal.x = cos * N.x + sin * B.x;
  21955. normal.y = cos * N.y + sin * B.y;
  21956. normal.z = cos * N.z + sin * B.z;
  21957. normal.normalize();
  21958. normals.push(normal.x, normal.y, normal.z); // vertex
  21959. vertex.x = P.x + radius * normal.x;
  21960. vertex.y = P.y + radius * normal.y;
  21961. vertex.z = P.z + radius * normal.z;
  21962. vertices.push(vertex.x, vertex.y, vertex.z);
  21963. }
  21964. }
  21965. function generateIndices() {
  21966. for (let j = 1; j <= tubularSegments; j++) {
  21967. for (let i = 1; i <= radialSegments; i++) {
  21968. const a = (radialSegments + 1) * (j - 1) + (i - 1);
  21969. const b = (radialSegments + 1) * j + (i - 1);
  21970. const c = (radialSegments + 1) * j + i;
  21971. const d = (radialSegments + 1) * (j - 1) + i; // faces
  21972. indices.push(a, b, d);
  21973. indices.push(b, c, d);
  21974. }
  21975. }
  21976. }
  21977. function generateUVs() {
  21978. for (let i = 0; i <= tubularSegments; i++) {
  21979. for (let j = 0; j <= radialSegments; j++) {
  21980. uv.x = i / tubularSegments;
  21981. uv.y = j / radialSegments;
  21982. uvs.push(uv.x, uv.y);
  21983. }
  21984. }
  21985. }
  21986. }
  21987. toJSON() {
  21988. const data = super.toJSON();
  21989. data.path = this.parameters.path.toJSON();
  21990. return data;
  21991. }
  21992. static fromJSON(data) {
  21993. // This only works for built-in curves (e.g. CatmullRomCurve3).
  21994. // User defined curves or instances of CurvePath will not be deserialized.
  21995. return new TubeGeometry(new Curves[data.path.type]().fromJSON(data.path), data.tubularSegments, data.radius, data.radialSegments, data.closed);
  21996. }
  21997. }
  21998. class WireframeGeometry extends BufferGeometry {
  21999. constructor(geometry = null) {
  22000. super();
  22001. this.type = 'WireframeGeometry';
  22002. this.parameters = {
  22003. geometry: geometry
  22004. };
  22005. if (geometry !== null) {
  22006. // buffer
  22007. const vertices = [];
  22008. const edges = new Set(); // helper variables
  22009. const start = new Vector3();
  22010. const end = new Vector3();
  22011. if (geometry.index !== null) {
  22012. // indexed BufferGeometry
  22013. const position = geometry.attributes.position;
  22014. const indices = geometry.index;
  22015. let groups = geometry.groups;
  22016. if (groups.length === 0) {
  22017. groups = [{
  22018. start: 0,
  22019. count: indices.count,
  22020. materialIndex: 0
  22021. }];
  22022. } // create a data structure that contains all edges without duplicates
  22023. for (let o = 0, ol = groups.length; o < ol; ++o) {
  22024. const group = groups[o];
  22025. const groupStart = group.start;
  22026. const groupCount = group.count;
  22027. for (let i = groupStart, l = groupStart + groupCount; i < l; i += 3) {
  22028. for (let j = 0; j < 3; j++) {
  22029. const index1 = indices.getX(i + j);
  22030. const index2 = indices.getX(i + (j + 1) % 3);
  22031. start.fromBufferAttribute(position, index1);
  22032. end.fromBufferAttribute(position, index2);
  22033. if (isUniqueEdge(start, end, edges) === true) {
  22034. vertices.push(start.x, start.y, start.z);
  22035. vertices.push(end.x, end.y, end.z);
  22036. }
  22037. }
  22038. }
  22039. }
  22040. } else {
  22041. // non-indexed BufferGeometry
  22042. const position = geometry.attributes.position;
  22043. for (let i = 0, l = position.count / 3; i < l; i++) {
  22044. for (let j = 0; j < 3; j++) {
  22045. // three edges per triangle, an edge is represented as (index1, index2)
  22046. // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0)
  22047. const index1 = 3 * i + j;
  22048. const index2 = 3 * i + (j + 1) % 3;
  22049. start.fromBufferAttribute(position, index1);
  22050. end.fromBufferAttribute(position, index2);
  22051. if (isUniqueEdge(start, end, edges) === true) {
  22052. vertices.push(start.x, start.y, start.z);
  22053. vertices.push(end.x, end.y, end.z);
  22054. }
  22055. }
  22056. }
  22057. } // build geometry
  22058. this.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  22059. }
  22060. }
  22061. }
  22062. function isUniqueEdge(start, end, edges) {
  22063. const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`;
  22064. const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge
  22065. if (edges.has(hash1) === true || edges.has(hash2) === true) {
  22066. return false;
  22067. } else {
  22068. edges.add(hash1);
  22069. edges.add(hash2);
  22070. return true;
  22071. }
  22072. }
  22073. var Geometries = /*#__PURE__*/Object.freeze({
  22074. __proto__: null,
  22075. BoxGeometry: BoxGeometry,
  22076. BoxBufferGeometry: BoxGeometry,
  22077. CapsuleGeometry: CapsuleGeometry,
  22078. CapsuleBufferGeometry: CapsuleGeometry,
  22079. CircleGeometry: CircleGeometry,
  22080. CircleBufferGeometry: CircleGeometry,
  22081. ConeGeometry: ConeGeometry,
  22082. ConeBufferGeometry: ConeGeometry,
  22083. CylinderGeometry: CylinderGeometry,
  22084. CylinderBufferGeometry: CylinderGeometry,
  22085. DodecahedronGeometry: DodecahedronGeometry,
  22086. DodecahedronBufferGeometry: DodecahedronGeometry,
  22087. EdgesGeometry: EdgesGeometry,
  22088. ExtrudeGeometry: ExtrudeGeometry,
  22089. ExtrudeBufferGeometry: ExtrudeGeometry,
  22090. IcosahedronGeometry: IcosahedronGeometry,
  22091. IcosahedronBufferGeometry: IcosahedronGeometry,
  22092. LatheGeometry: LatheGeometry,
  22093. LatheBufferGeometry: LatheGeometry,
  22094. OctahedronGeometry: OctahedronGeometry,
  22095. OctahedronBufferGeometry: OctahedronGeometry,
  22096. PlaneGeometry: PlaneGeometry,
  22097. PlaneBufferGeometry: PlaneGeometry,
  22098. PolyhedronGeometry: PolyhedronGeometry,
  22099. PolyhedronBufferGeometry: PolyhedronGeometry,
  22100. RingGeometry: RingGeometry,
  22101. RingBufferGeometry: RingGeometry,
  22102. ShapeGeometry: ShapeGeometry,
  22103. ShapeBufferGeometry: ShapeGeometry,
  22104. SphereGeometry: SphereGeometry,
  22105. SphereBufferGeometry: SphereGeometry,
  22106. TetrahedronGeometry: TetrahedronGeometry,
  22107. TetrahedronBufferGeometry: TetrahedronGeometry,
  22108. TorusGeometry: TorusGeometry,
  22109. TorusBufferGeometry: TorusGeometry,
  22110. TorusKnotGeometry: TorusKnotGeometry,
  22111. TorusKnotBufferGeometry: TorusKnotGeometry,
  22112. TubeGeometry: TubeGeometry,
  22113. TubeBufferGeometry: TubeGeometry,
  22114. WireframeGeometry: WireframeGeometry
  22115. });
  22116. class ShadowMaterial extends Material {
  22117. constructor(parameters) {
  22118. super();
  22119. this.isShadowMaterial = true;
  22120. this.type = 'ShadowMaterial';
  22121. this.color = new Color(0x000000);
  22122. this.transparent = true;
  22123. this.fog = true;
  22124. this.setValues(parameters);
  22125. }
  22126. copy(source) {
  22127. super.copy(source);
  22128. this.color.copy(source.color);
  22129. this.fog = source.fog;
  22130. return this;
  22131. }
  22132. }
  22133. class RawShaderMaterial extends ShaderMaterial {
  22134. constructor(parameters) {
  22135. super(parameters);
  22136. this.isRawShaderMaterial = true;
  22137. this.type = 'RawShaderMaterial';
  22138. }
  22139. }
  22140. class MeshStandardMaterial extends Material {
  22141. constructor(parameters) {
  22142. super();
  22143. this.isMeshStandardMaterial = true;
  22144. this.defines = {
  22145. 'STANDARD': ''
  22146. };
  22147. this.type = 'MeshStandardMaterial';
  22148. this.color = new Color(0xffffff); // diffuse
  22149. this.roughness = 1.0;
  22150. this.metalness = 0.0;
  22151. this.map = null;
  22152. this.lightMap = null;
  22153. this.lightMapIntensity = 1.0;
  22154. this.aoMap = null;
  22155. this.aoMapIntensity = 1.0;
  22156. this.emissive = new Color(0x000000);
  22157. this.emissiveIntensity = 1.0;
  22158. this.emissiveMap = null;
  22159. this.bumpMap = null;
  22160. this.bumpScale = 1;
  22161. this.normalMap = null;
  22162. this.normalMapType = TangentSpaceNormalMap;
  22163. this.normalScale = new Vector2(1, 1);
  22164. this.displacementMap = null;
  22165. this.displacementScale = 1;
  22166. this.displacementBias = 0;
  22167. this.roughnessMap = null;
  22168. this.metalnessMap = null;
  22169. this.alphaMap = null;
  22170. this.envMap = null;
  22171. this.envMapIntensity = 1.0;
  22172. this.wireframe = false;
  22173. this.wireframeLinewidth = 1;
  22174. this.wireframeLinecap = 'round';
  22175. this.wireframeLinejoin = 'round';
  22176. this.flatShading = false;
  22177. this.fog = true;
  22178. this.setValues(parameters);
  22179. }
  22180. copy(source) {
  22181. super.copy(source);
  22182. this.defines = {
  22183. 'STANDARD': ''
  22184. };
  22185. this.color.copy(source.color);
  22186. this.roughness = source.roughness;
  22187. this.metalness = source.metalness;
  22188. this.map = source.map;
  22189. this.lightMap = source.lightMap;
  22190. this.lightMapIntensity = source.lightMapIntensity;
  22191. this.aoMap = source.aoMap;
  22192. this.aoMapIntensity = source.aoMapIntensity;
  22193. this.emissive.copy(source.emissive);
  22194. this.emissiveMap = source.emissiveMap;
  22195. this.emissiveIntensity = source.emissiveIntensity;
  22196. this.bumpMap = source.bumpMap;
  22197. this.bumpScale = source.bumpScale;
  22198. this.normalMap = source.normalMap;
  22199. this.normalMapType = source.normalMapType;
  22200. this.normalScale.copy(source.normalScale);
  22201. this.displacementMap = source.displacementMap;
  22202. this.displacementScale = source.displacementScale;
  22203. this.displacementBias = source.displacementBias;
  22204. this.roughnessMap = source.roughnessMap;
  22205. this.metalnessMap = source.metalnessMap;
  22206. this.alphaMap = source.alphaMap;
  22207. this.envMap = source.envMap;
  22208. this.envMapIntensity = source.envMapIntensity;
  22209. this.wireframe = source.wireframe;
  22210. this.wireframeLinewidth = source.wireframeLinewidth;
  22211. this.wireframeLinecap = source.wireframeLinecap;
  22212. this.wireframeLinejoin = source.wireframeLinejoin;
  22213. this.flatShading = source.flatShading;
  22214. this.fog = source.fog;
  22215. return this;
  22216. }
  22217. }
  22218. class MeshPhysicalMaterial extends MeshStandardMaterial {
  22219. constructor(parameters) {
  22220. super();
  22221. this.isMeshPhysicalMaterial = true;
  22222. this.defines = {
  22223. 'STANDARD': '',
  22224. 'PHYSICAL': ''
  22225. };
  22226. this.type = 'MeshPhysicalMaterial';
  22227. this.clearcoatMap = null;
  22228. this.clearcoatRoughness = 0.0;
  22229. this.clearcoatRoughnessMap = null;
  22230. this.clearcoatNormalScale = new Vector2(1, 1);
  22231. this.clearcoatNormalMap = null;
  22232. this.ior = 1.5;
  22233. Object.defineProperty(this, 'reflectivity', {
  22234. get: function () {
  22235. return clamp(2.5 * (this.ior - 1) / (this.ior + 1), 0, 1);
  22236. },
  22237. set: function (reflectivity) {
  22238. this.ior = (1 + 0.4 * reflectivity) / (1 - 0.4 * reflectivity);
  22239. }
  22240. });
  22241. this.iridescenceMap = null;
  22242. this.iridescenceIOR = 1.3;
  22243. this.iridescenceThicknessRange = [100, 400];
  22244. this.iridescenceThicknessMap = null;
  22245. this.sheenColor = new Color(0x000000);
  22246. this.sheenColorMap = null;
  22247. this.sheenRoughness = 1.0;
  22248. this.sheenRoughnessMap = null;
  22249. this.transmissionMap = null;
  22250. this.thickness = 0;
  22251. this.thicknessMap = null;
  22252. this.attenuationDistance = 0.0;
  22253. this.attenuationColor = new Color(1, 1, 1);
  22254. this.specularIntensity = 1.0;
  22255. this.specularIntensityMap = null;
  22256. this.specularColor = new Color(1, 1, 1);
  22257. this.specularColorMap = null;
  22258. this._sheen = 0.0;
  22259. this._clearcoat = 0;
  22260. this._iridescence = 0;
  22261. this._transmission = 0;
  22262. this.setValues(parameters);
  22263. }
  22264. get sheen() {
  22265. return this._sheen;
  22266. }
  22267. set sheen(value) {
  22268. if (this._sheen > 0 !== value > 0) {
  22269. this.version++;
  22270. }
  22271. this._sheen = value;
  22272. }
  22273. get clearcoat() {
  22274. return this._clearcoat;
  22275. }
  22276. set clearcoat(value) {
  22277. if (this._clearcoat > 0 !== value > 0) {
  22278. this.version++;
  22279. }
  22280. this._clearcoat = value;
  22281. }
  22282. get iridescence() {
  22283. return this._iridescence;
  22284. }
  22285. set iridescence(value) {
  22286. if (this._iridescence > 0 !== value > 0) {
  22287. this.version++;
  22288. }
  22289. this._iridescence = value;
  22290. }
  22291. get transmission() {
  22292. return this._transmission;
  22293. }
  22294. set transmission(value) {
  22295. if (this._transmission > 0 !== value > 0) {
  22296. this.version++;
  22297. }
  22298. this._transmission = value;
  22299. }
  22300. copy(source) {
  22301. super.copy(source);
  22302. this.defines = {
  22303. 'STANDARD': '',
  22304. 'PHYSICAL': ''
  22305. };
  22306. this.clearcoat = source.clearcoat;
  22307. this.clearcoatMap = source.clearcoatMap;
  22308. this.clearcoatRoughness = source.clearcoatRoughness;
  22309. this.clearcoatRoughnessMap = source.clearcoatRoughnessMap;
  22310. this.clearcoatNormalMap = source.clearcoatNormalMap;
  22311. this.clearcoatNormalScale.copy(source.clearcoatNormalScale);
  22312. this.ior = source.ior;
  22313. this.iridescence = source.iridescence;
  22314. this.iridescenceMap = source.iridescenceMap;
  22315. this.iridescenceIOR = source.iridescenceIOR;
  22316. this.iridescenceThicknessRange = [...source.iridescenceThicknessRange];
  22317. this.iridescenceThicknessMap = source.iridescenceThicknessMap;
  22318. this.sheen = source.sheen;
  22319. this.sheenColor.copy(source.sheenColor);
  22320. this.sheenColorMap = source.sheenColorMap;
  22321. this.sheenRoughness = source.sheenRoughness;
  22322. this.sheenRoughnessMap = source.sheenRoughnessMap;
  22323. this.transmission = source.transmission;
  22324. this.transmissionMap = source.transmissionMap;
  22325. this.thickness = source.thickness;
  22326. this.thicknessMap = source.thicknessMap;
  22327. this.attenuationDistance = source.attenuationDistance;
  22328. this.attenuationColor.copy(source.attenuationColor);
  22329. this.specularIntensity = source.specularIntensity;
  22330. this.specularIntensityMap = source.specularIntensityMap;
  22331. this.specularColor.copy(source.specularColor);
  22332. this.specularColorMap = source.specularColorMap;
  22333. return this;
  22334. }
  22335. }
  22336. class MeshPhongMaterial extends Material {
  22337. constructor(parameters) {
  22338. super();
  22339. this.isMeshPhongMaterial = true;
  22340. this.type = 'MeshPhongMaterial';
  22341. this.color = new Color(0xffffff); // diffuse
  22342. this.specular = new Color(0x111111);
  22343. this.shininess = 30;
  22344. this.map = null;
  22345. this.lightMap = null;
  22346. this.lightMapIntensity = 1.0;
  22347. this.aoMap = null;
  22348. this.aoMapIntensity = 1.0;
  22349. this.emissive = new Color(0x000000);
  22350. this.emissiveIntensity = 1.0;
  22351. this.emissiveMap = null;
  22352. this.bumpMap = null;
  22353. this.bumpScale = 1;
  22354. this.normalMap = null;
  22355. this.normalMapType = TangentSpaceNormalMap;
  22356. this.normalScale = new Vector2(1, 1);
  22357. this.displacementMap = null;
  22358. this.displacementScale = 1;
  22359. this.displacementBias = 0;
  22360. this.specularMap = null;
  22361. this.alphaMap = null;
  22362. this.envMap = null;
  22363. this.combine = MultiplyOperation;
  22364. this.reflectivity = 1;
  22365. this.refractionRatio = 0.98;
  22366. this.wireframe = false;
  22367. this.wireframeLinewidth = 1;
  22368. this.wireframeLinecap = 'round';
  22369. this.wireframeLinejoin = 'round';
  22370. this.flatShading = false;
  22371. this.fog = true;
  22372. this.setValues(parameters);
  22373. }
  22374. copy(source) {
  22375. super.copy(source);
  22376. this.color.copy(source.color);
  22377. this.specular.copy(source.specular);
  22378. this.shininess = source.shininess;
  22379. this.map = source.map;
  22380. this.lightMap = source.lightMap;
  22381. this.lightMapIntensity = source.lightMapIntensity;
  22382. this.aoMap = source.aoMap;
  22383. this.aoMapIntensity = source.aoMapIntensity;
  22384. this.emissive.copy(source.emissive);
  22385. this.emissiveMap = source.emissiveMap;
  22386. this.emissiveIntensity = source.emissiveIntensity;
  22387. this.bumpMap = source.bumpMap;
  22388. this.bumpScale = source.bumpScale;
  22389. this.normalMap = source.normalMap;
  22390. this.normalMapType = source.normalMapType;
  22391. this.normalScale.copy(source.normalScale);
  22392. this.displacementMap = source.displacementMap;
  22393. this.displacementScale = source.displacementScale;
  22394. this.displacementBias = source.displacementBias;
  22395. this.specularMap = source.specularMap;
  22396. this.alphaMap = source.alphaMap;
  22397. this.envMap = source.envMap;
  22398. this.combine = source.combine;
  22399. this.reflectivity = source.reflectivity;
  22400. this.refractionRatio = source.refractionRatio;
  22401. this.wireframe = source.wireframe;
  22402. this.wireframeLinewidth = source.wireframeLinewidth;
  22403. this.wireframeLinecap = source.wireframeLinecap;
  22404. this.wireframeLinejoin = source.wireframeLinejoin;
  22405. this.flatShading = source.flatShading;
  22406. this.fog = source.fog;
  22407. return this;
  22408. }
  22409. }
  22410. class MeshToonMaterial extends Material {
  22411. constructor(parameters) {
  22412. super();
  22413. this.isMeshToonMaterial = true;
  22414. this.defines = {
  22415. 'TOON': ''
  22416. };
  22417. this.type = 'MeshToonMaterial';
  22418. this.color = new Color(0xffffff);
  22419. this.map = null;
  22420. this.gradientMap = null;
  22421. this.lightMap = null;
  22422. this.lightMapIntensity = 1.0;
  22423. this.aoMap = null;
  22424. this.aoMapIntensity = 1.0;
  22425. this.emissive = new Color(0x000000);
  22426. this.emissiveIntensity = 1.0;
  22427. this.emissiveMap = null;
  22428. this.bumpMap = null;
  22429. this.bumpScale = 1;
  22430. this.normalMap = null;
  22431. this.normalMapType = TangentSpaceNormalMap;
  22432. this.normalScale = new Vector2(1, 1);
  22433. this.displacementMap = null;
  22434. this.displacementScale = 1;
  22435. this.displacementBias = 0;
  22436. this.alphaMap = null;
  22437. this.wireframe = false;
  22438. this.wireframeLinewidth = 1;
  22439. this.wireframeLinecap = 'round';
  22440. this.wireframeLinejoin = 'round';
  22441. this.fog = true;
  22442. this.setValues(parameters);
  22443. }
  22444. copy(source) {
  22445. super.copy(source);
  22446. this.color.copy(source.color);
  22447. this.map = source.map;
  22448. this.gradientMap = source.gradientMap;
  22449. this.lightMap = source.lightMap;
  22450. this.lightMapIntensity = source.lightMapIntensity;
  22451. this.aoMap = source.aoMap;
  22452. this.aoMapIntensity = source.aoMapIntensity;
  22453. this.emissive.copy(source.emissive);
  22454. this.emissiveMap = source.emissiveMap;
  22455. this.emissiveIntensity = source.emissiveIntensity;
  22456. this.bumpMap = source.bumpMap;
  22457. this.bumpScale = source.bumpScale;
  22458. this.normalMap = source.normalMap;
  22459. this.normalMapType = source.normalMapType;
  22460. this.normalScale.copy(source.normalScale);
  22461. this.displacementMap = source.displacementMap;
  22462. this.displacementScale = source.displacementScale;
  22463. this.displacementBias = source.displacementBias;
  22464. this.alphaMap = source.alphaMap;
  22465. this.wireframe = source.wireframe;
  22466. this.wireframeLinewidth = source.wireframeLinewidth;
  22467. this.wireframeLinecap = source.wireframeLinecap;
  22468. this.wireframeLinejoin = source.wireframeLinejoin;
  22469. this.fog = source.fog;
  22470. return this;
  22471. }
  22472. }
  22473. class MeshNormalMaterial extends Material {
  22474. constructor(parameters) {
  22475. super();
  22476. this.isMeshNormalMaterial = true;
  22477. this.type = 'MeshNormalMaterial';
  22478. this.bumpMap = null;
  22479. this.bumpScale = 1;
  22480. this.normalMap = null;
  22481. this.normalMapType = TangentSpaceNormalMap;
  22482. this.normalScale = new Vector2(1, 1);
  22483. this.displacementMap = null;
  22484. this.displacementScale = 1;
  22485. this.displacementBias = 0;
  22486. this.wireframe = false;
  22487. this.wireframeLinewidth = 1;
  22488. this.flatShading = false;
  22489. this.setValues(parameters);
  22490. }
  22491. copy(source) {
  22492. super.copy(source);
  22493. this.bumpMap = source.bumpMap;
  22494. this.bumpScale = source.bumpScale;
  22495. this.normalMap = source.normalMap;
  22496. this.normalMapType = source.normalMapType;
  22497. this.normalScale.copy(source.normalScale);
  22498. this.displacementMap = source.displacementMap;
  22499. this.displacementScale = source.displacementScale;
  22500. this.displacementBias = source.displacementBias;
  22501. this.wireframe = source.wireframe;
  22502. this.wireframeLinewidth = source.wireframeLinewidth;
  22503. this.flatShading = source.flatShading;
  22504. return this;
  22505. }
  22506. }
  22507. class MeshLambertMaterial extends Material {
  22508. constructor(parameters) {
  22509. super();
  22510. this.isMeshLambertMaterial = true;
  22511. this.type = 'MeshLambertMaterial';
  22512. this.color = new Color(0xffffff); // diffuse
  22513. this.map = null;
  22514. this.lightMap = null;
  22515. this.lightMapIntensity = 1.0;
  22516. this.aoMap = null;
  22517. this.aoMapIntensity = 1.0;
  22518. this.emissive = new Color(0x000000);
  22519. this.emissiveIntensity = 1.0;
  22520. this.emissiveMap = null;
  22521. this.specularMap = null;
  22522. this.alphaMap = null;
  22523. this.envMap = null;
  22524. this.combine = MultiplyOperation;
  22525. this.reflectivity = 1;
  22526. this.refractionRatio = 0.98;
  22527. this.wireframe = false;
  22528. this.wireframeLinewidth = 1;
  22529. this.wireframeLinecap = 'round';
  22530. this.wireframeLinejoin = 'round';
  22531. this.fog = true;
  22532. this.setValues(parameters);
  22533. }
  22534. copy(source) {
  22535. super.copy(source);
  22536. this.color.copy(source.color);
  22537. this.map = source.map;
  22538. this.lightMap = source.lightMap;
  22539. this.lightMapIntensity = source.lightMapIntensity;
  22540. this.aoMap = source.aoMap;
  22541. this.aoMapIntensity = source.aoMapIntensity;
  22542. this.emissive.copy(source.emissive);
  22543. this.emissiveMap = source.emissiveMap;
  22544. this.emissiveIntensity = source.emissiveIntensity;
  22545. this.specularMap = source.specularMap;
  22546. this.alphaMap = source.alphaMap;
  22547. this.envMap = source.envMap;
  22548. this.combine = source.combine;
  22549. this.reflectivity = source.reflectivity;
  22550. this.refractionRatio = source.refractionRatio;
  22551. this.wireframe = source.wireframe;
  22552. this.wireframeLinewidth = source.wireframeLinewidth;
  22553. this.wireframeLinecap = source.wireframeLinecap;
  22554. this.wireframeLinejoin = source.wireframeLinejoin;
  22555. this.fog = source.fog;
  22556. return this;
  22557. }
  22558. }
  22559. class MeshMatcapMaterial extends Material {
  22560. constructor(parameters) {
  22561. super();
  22562. this.isMeshMatcapMaterial = true;
  22563. this.defines = {
  22564. 'MATCAP': ''
  22565. };
  22566. this.type = 'MeshMatcapMaterial';
  22567. this.color = new Color(0xffffff); // diffuse
  22568. this.matcap = null;
  22569. this.map = null;
  22570. this.bumpMap = null;
  22571. this.bumpScale = 1;
  22572. this.normalMap = null;
  22573. this.normalMapType = TangentSpaceNormalMap;
  22574. this.normalScale = new Vector2(1, 1);
  22575. this.displacementMap = null;
  22576. this.displacementScale = 1;
  22577. this.displacementBias = 0;
  22578. this.alphaMap = null;
  22579. this.flatShading = false;
  22580. this.fog = true;
  22581. this.setValues(parameters);
  22582. }
  22583. copy(source) {
  22584. super.copy(source);
  22585. this.defines = {
  22586. 'MATCAP': ''
  22587. };
  22588. this.color.copy(source.color);
  22589. this.matcap = source.matcap;
  22590. this.map = source.map;
  22591. this.bumpMap = source.bumpMap;
  22592. this.bumpScale = source.bumpScale;
  22593. this.normalMap = source.normalMap;
  22594. this.normalMapType = source.normalMapType;
  22595. this.normalScale.copy(source.normalScale);
  22596. this.displacementMap = source.displacementMap;
  22597. this.displacementScale = source.displacementScale;
  22598. this.displacementBias = source.displacementBias;
  22599. this.alphaMap = source.alphaMap;
  22600. this.flatShading = source.flatShading;
  22601. this.fog = source.fog;
  22602. return this;
  22603. }
  22604. }
  22605. class LineDashedMaterial extends LineBasicMaterial {
  22606. constructor(parameters) {
  22607. super();
  22608. this.isLineDashedMaterial = true;
  22609. this.type = 'LineDashedMaterial';
  22610. this.scale = 1;
  22611. this.dashSize = 3;
  22612. this.gapSize = 1;
  22613. this.setValues(parameters);
  22614. }
  22615. copy(source) {
  22616. super.copy(source);
  22617. this.scale = source.scale;
  22618. this.dashSize = source.dashSize;
  22619. this.gapSize = source.gapSize;
  22620. return this;
  22621. }
  22622. }
  22623. function arraySlice(array, from, to) {
  22624. if (isTypedArray(array)) {
  22625. // in ios9 array.subarray(from, undefined) will return empty array
  22626. // but array.subarray(from) or array.subarray(from, len) is correct
  22627. return new array.constructor(array.subarray(from, to !== undefined ? to : array.length));
  22628. }
  22629. return array.slice(from, to);
  22630. } // converts an array to a specific type
  22631. function convertArray(array, type, forceClone) {
  22632. if (!array || // let 'undefined' and 'null' pass
  22633. !forceClone && array.constructor === type) return array;
  22634. if (typeof type.BYTES_PER_ELEMENT === 'number') {
  22635. return new type(array); // create typed array
  22636. }
  22637. return Array.prototype.slice.call(array); // create Array
  22638. }
  22639. function isTypedArray(object) {
  22640. return ArrayBuffer.isView(object) && !(object instanceof DataView);
  22641. } // returns an array by which times and values can be sorted
  22642. function getKeyframeOrder(times) {
  22643. function compareTime(i, j) {
  22644. return times[i] - times[j];
  22645. }
  22646. const n = times.length;
  22647. const result = new Array(n);
  22648. for (let i = 0; i !== n; ++i) result[i] = i;
  22649. result.sort(compareTime);
  22650. return result;
  22651. } // uses the array previously returned by 'getKeyframeOrder' to sort data
  22652. function sortedArray(values, stride, order) {
  22653. const nValues = values.length;
  22654. const result = new values.constructor(nValues);
  22655. for (let i = 0, dstOffset = 0; dstOffset !== nValues; ++i) {
  22656. const srcOffset = order[i] * stride;
  22657. for (let j = 0; j !== stride; ++j) {
  22658. result[dstOffset++] = values[srcOffset + j];
  22659. }
  22660. }
  22661. return result;
  22662. } // function for parsing AOS keyframe formats
  22663. function flattenJSON(jsonKeys, times, values, valuePropertyName) {
  22664. let i = 1,
  22665. key = jsonKeys[0];
  22666. while (key !== undefined && key[valuePropertyName] === undefined) {
  22667. key = jsonKeys[i++];
  22668. }
  22669. if (key === undefined) return; // no data
  22670. let value = key[valuePropertyName];
  22671. if (value === undefined) return; // no data
  22672. if (Array.isArray(value)) {
  22673. do {
  22674. value = key[valuePropertyName];
  22675. if (value !== undefined) {
  22676. times.push(key.time);
  22677. values.push.apply(values, value); // push all elements
  22678. }
  22679. key = jsonKeys[i++];
  22680. } while (key !== undefined);
  22681. } else if (value.toArray !== undefined) {
  22682. // ...assume THREE.Math-ish
  22683. do {
  22684. value = key[valuePropertyName];
  22685. if (value !== undefined) {
  22686. times.push(key.time);
  22687. value.toArray(values, values.length);
  22688. }
  22689. key = jsonKeys[i++];
  22690. } while (key !== undefined);
  22691. } else {
  22692. // otherwise push as-is
  22693. do {
  22694. value = key[valuePropertyName];
  22695. if (value !== undefined) {
  22696. times.push(key.time);
  22697. values.push(value);
  22698. }
  22699. key = jsonKeys[i++];
  22700. } while (key !== undefined);
  22701. }
  22702. }
  22703. function subclip(sourceClip, name, startFrame, endFrame, fps = 30) {
  22704. const clip = sourceClip.clone();
  22705. clip.name = name;
  22706. const tracks = [];
  22707. for (let i = 0; i < clip.tracks.length; ++i) {
  22708. const track = clip.tracks[i];
  22709. const valueSize = track.getValueSize();
  22710. const times = [];
  22711. const values = [];
  22712. for (let j = 0; j < track.times.length; ++j) {
  22713. const frame = track.times[j] * fps;
  22714. if (frame < startFrame || frame >= endFrame) continue;
  22715. times.push(track.times[j]);
  22716. for (let k = 0; k < valueSize; ++k) {
  22717. values.push(track.values[j * valueSize + k]);
  22718. }
  22719. }
  22720. if (times.length === 0) continue;
  22721. track.times = convertArray(times, track.times.constructor);
  22722. track.values = convertArray(values, track.values.constructor);
  22723. tracks.push(track);
  22724. }
  22725. clip.tracks = tracks; // find minimum .times value across all tracks in the trimmed clip
  22726. let minStartTime = Infinity;
  22727. for (let i = 0; i < clip.tracks.length; ++i) {
  22728. if (minStartTime > clip.tracks[i].times[0]) {
  22729. minStartTime = clip.tracks[i].times[0];
  22730. }
  22731. } // shift all tracks such that clip begins at t=0
  22732. for (let i = 0; i < clip.tracks.length; ++i) {
  22733. clip.tracks[i].shift(-1 * minStartTime);
  22734. }
  22735. clip.resetDuration();
  22736. return clip;
  22737. }
  22738. function makeClipAdditive(targetClip, referenceFrame = 0, referenceClip = targetClip, fps = 30) {
  22739. if (fps <= 0) fps = 30;
  22740. const numTracks = referenceClip.tracks.length;
  22741. const referenceTime = referenceFrame / fps; // Make each track's values relative to the values at the reference frame
  22742. for (let i = 0; i < numTracks; ++i) {
  22743. const referenceTrack = referenceClip.tracks[i];
  22744. const referenceTrackType = referenceTrack.ValueTypeName; // Skip this track if it's non-numeric
  22745. if (referenceTrackType === 'bool' || referenceTrackType === 'string') continue; // Find the track in the target clip whose name and type matches the reference track
  22746. const targetTrack = targetClip.tracks.find(function (track) {
  22747. return track.name === referenceTrack.name && track.ValueTypeName === referenceTrackType;
  22748. });
  22749. if (targetTrack === undefined) continue;
  22750. let referenceOffset = 0;
  22751. const referenceValueSize = referenceTrack.getValueSize();
  22752. if (referenceTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
  22753. referenceOffset = referenceValueSize / 3;
  22754. }
  22755. let targetOffset = 0;
  22756. const targetValueSize = targetTrack.getValueSize();
  22757. if (targetTrack.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline) {
  22758. targetOffset = targetValueSize / 3;
  22759. }
  22760. const lastIndex = referenceTrack.times.length - 1;
  22761. let referenceValue; // Find the value to subtract out of the track
  22762. if (referenceTime <= referenceTrack.times[0]) {
  22763. // Reference frame is earlier than the first keyframe, so just use the first keyframe
  22764. const startIndex = referenceOffset;
  22765. const endIndex = referenceValueSize - referenceOffset;
  22766. referenceValue = arraySlice(referenceTrack.values, startIndex, endIndex);
  22767. } else if (referenceTime >= referenceTrack.times[lastIndex]) {
  22768. // Reference frame is after the last keyframe, so just use the last keyframe
  22769. const startIndex = lastIndex * referenceValueSize + referenceOffset;
  22770. const endIndex = startIndex + referenceValueSize - referenceOffset;
  22771. referenceValue = arraySlice(referenceTrack.values, startIndex, endIndex);
  22772. } else {
  22773. // Interpolate to the reference value
  22774. const interpolant = referenceTrack.createInterpolant();
  22775. const startIndex = referenceOffset;
  22776. const endIndex = referenceValueSize - referenceOffset;
  22777. interpolant.evaluate(referenceTime);
  22778. referenceValue = arraySlice(interpolant.resultBuffer, startIndex, endIndex);
  22779. } // Conjugate the quaternion
  22780. if (referenceTrackType === 'quaternion') {
  22781. const referenceQuat = new Quaternion().fromArray(referenceValue).normalize().conjugate();
  22782. referenceQuat.toArray(referenceValue);
  22783. } // Subtract the reference value from all of the track values
  22784. const numTimes = targetTrack.times.length;
  22785. for (let j = 0; j < numTimes; ++j) {
  22786. const valueStart = j * targetValueSize + targetOffset;
  22787. if (referenceTrackType === 'quaternion') {
  22788. // Multiply the conjugate for quaternion track types
  22789. Quaternion.multiplyQuaternionsFlat(targetTrack.values, valueStart, referenceValue, 0, targetTrack.values, valueStart);
  22790. } else {
  22791. const valueEnd = targetValueSize - targetOffset * 2; // Subtract each value for all other numeric track types
  22792. for (let k = 0; k < valueEnd; ++k) {
  22793. targetTrack.values[valueStart + k] -= referenceValue[k];
  22794. }
  22795. }
  22796. }
  22797. }
  22798. targetClip.blendMode = AdditiveAnimationBlendMode;
  22799. return targetClip;
  22800. }
  22801. var AnimationUtils = /*#__PURE__*/Object.freeze({
  22802. __proto__: null,
  22803. arraySlice: arraySlice,
  22804. convertArray: convertArray,
  22805. isTypedArray: isTypedArray,
  22806. getKeyframeOrder: getKeyframeOrder,
  22807. sortedArray: sortedArray,
  22808. flattenJSON: flattenJSON,
  22809. subclip: subclip,
  22810. makeClipAdditive: makeClipAdditive
  22811. });
  22812. /**
  22813. * Abstract base class of interpolants over parametric samples.
  22814. *
  22815. * The parameter domain is one dimensional, typically the time or a path
  22816. * along a curve defined by the data.
  22817. *
  22818. * The sample values can have any dimensionality and derived classes may
  22819. * apply special interpretations to the data.
  22820. *
  22821. * This class provides the interval seek in a Template Method, deferring
  22822. * the actual interpolation to derived classes.
  22823. *
  22824. * Time complexity is O(1) for linear access crossing at most two points
  22825. * and O(log N) for random access, where N is the number of positions.
  22826. *
  22827. * References:
  22828. *
  22829. * http://www.oodesign.com/template-method-pattern.html
  22830. *
  22831. */
  22832. class Interpolant {
  22833. constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  22834. this.parameterPositions = parameterPositions;
  22835. this._cachedIndex = 0;
  22836. this.resultBuffer = resultBuffer !== undefined ? resultBuffer : new sampleValues.constructor(sampleSize);
  22837. this.sampleValues = sampleValues;
  22838. this.valueSize = sampleSize;
  22839. this.settings = null;
  22840. this.DefaultSettings_ = {};
  22841. }
  22842. evaluate(t) {
  22843. const pp = this.parameterPositions;
  22844. let i1 = this._cachedIndex,
  22845. t1 = pp[i1],
  22846. t0 = pp[i1 - 1];
  22847. validate_interval: {
  22848. seek: {
  22849. let right;
  22850. linear_scan: {
  22851. //- See http://jsperf.com/comparison-to-undefined/3
  22852. //- slower code:
  22853. //-
  22854. //- if ( t >= t1 || t1 === undefined ) {
  22855. forward_scan: if (!(t < t1)) {
  22856. for (let giveUpAt = i1 + 2;;) {
  22857. if (t1 === undefined) {
  22858. if (t < t0) break forward_scan; // after end
  22859. i1 = pp.length;
  22860. this._cachedIndex = i1;
  22861. return this.copySampleValue_(i1 - 1);
  22862. }
  22863. if (i1 === giveUpAt) break; // this loop
  22864. t0 = t1;
  22865. t1 = pp[++i1];
  22866. if (t < t1) {
  22867. // we have arrived at the sought interval
  22868. break seek;
  22869. }
  22870. } // prepare binary search on the right side of the index
  22871. right = pp.length;
  22872. break linear_scan;
  22873. } //- slower code:
  22874. //- if ( t < t0 || t0 === undefined ) {
  22875. if (!(t >= t0)) {
  22876. // looping?
  22877. const t1global = pp[1];
  22878. if (t < t1global) {
  22879. i1 = 2; // + 1, using the scan for the details
  22880. t0 = t1global;
  22881. } // linear reverse scan
  22882. for (let giveUpAt = i1 - 2;;) {
  22883. if (t0 === undefined) {
  22884. // before start
  22885. this._cachedIndex = 0;
  22886. return this.copySampleValue_(0);
  22887. }
  22888. if (i1 === giveUpAt) break; // this loop
  22889. t1 = t0;
  22890. t0 = pp[--i1 - 1];
  22891. if (t >= t0) {
  22892. // we have arrived at the sought interval
  22893. break seek;
  22894. }
  22895. } // prepare binary search on the left side of the index
  22896. right = i1;
  22897. i1 = 0;
  22898. break linear_scan;
  22899. } // the interval is valid
  22900. break validate_interval;
  22901. } // linear scan
  22902. // binary search
  22903. while (i1 < right) {
  22904. const mid = i1 + right >>> 1;
  22905. if (t < pp[mid]) {
  22906. right = mid;
  22907. } else {
  22908. i1 = mid + 1;
  22909. }
  22910. }
  22911. t1 = pp[i1];
  22912. t0 = pp[i1 - 1]; // check boundary cases, again
  22913. if (t0 === undefined) {
  22914. this._cachedIndex = 0;
  22915. return this.copySampleValue_(0);
  22916. }
  22917. if (t1 === undefined) {
  22918. i1 = pp.length;
  22919. this._cachedIndex = i1;
  22920. return this.copySampleValue_(i1 - 1);
  22921. }
  22922. } // seek
  22923. this._cachedIndex = i1;
  22924. this.intervalChanged_(i1, t0, t1);
  22925. } // validate_interval
  22926. return this.interpolate_(i1, t0, t, t1);
  22927. }
  22928. getSettings_() {
  22929. return this.settings || this.DefaultSettings_;
  22930. }
  22931. copySampleValue_(index) {
  22932. // copies a sample value to the result buffer
  22933. const result = this.resultBuffer,
  22934. values = this.sampleValues,
  22935. stride = this.valueSize,
  22936. offset = index * stride;
  22937. for (let i = 0; i !== stride; ++i) {
  22938. result[i] = values[offset + i];
  22939. }
  22940. return result;
  22941. } // Template methods for derived classes:
  22942. interpolate_() {
  22943. throw new Error('call to abstract method'); // implementations shall return this.resultBuffer
  22944. }
  22945. intervalChanged_() {// empty
  22946. }
  22947. }
  22948. /**
  22949. * Fast and simple cubic spline interpolant.
  22950. *
  22951. * It was derived from a Hermitian construction setting the first derivative
  22952. * at each sample position to the linear slope between neighboring positions
  22953. * over their parameter interval.
  22954. */
  22955. class CubicInterpolant extends Interpolant {
  22956. constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  22957. super(parameterPositions, sampleValues, sampleSize, resultBuffer);
  22958. this._weightPrev = -0;
  22959. this._offsetPrev = -0;
  22960. this._weightNext = -0;
  22961. this._offsetNext = -0;
  22962. this.DefaultSettings_ = {
  22963. endingStart: ZeroCurvatureEnding,
  22964. endingEnd: ZeroCurvatureEnding
  22965. };
  22966. }
  22967. intervalChanged_(i1, t0, t1) {
  22968. const pp = this.parameterPositions;
  22969. let iPrev = i1 - 2,
  22970. iNext = i1 + 1,
  22971. tPrev = pp[iPrev],
  22972. tNext = pp[iNext];
  22973. if (tPrev === undefined) {
  22974. switch (this.getSettings_().endingStart) {
  22975. case ZeroSlopeEnding:
  22976. // f'(t0) = 0
  22977. iPrev = i1;
  22978. tPrev = 2 * t0 - t1;
  22979. break;
  22980. case WrapAroundEnding:
  22981. // use the other end of the curve
  22982. iPrev = pp.length - 2;
  22983. tPrev = t0 + pp[iPrev] - pp[iPrev + 1];
  22984. break;
  22985. default:
  22986. // ZeroCurvatureEnding
  22987. // f''(t0) = 0 a.k.a. Natural Spline
  22988. iPrev = i1;
  22989. tPrev = t1;
  22990. }
  22991. }
  22992. if (tNext === undefined) {
  22993. switch (this.getSettings_().endingEnd) {
  22994. case ZeroSlopeEnding:
  22995. // f'(tN) = 0
  22996. iNext = i1;
  22997. tNext = 2 * t1 - t0;
  22998. break;
  22999. case WrapAroundEnding:
  23000. // use the other end of the curve
  23001. iNext = 1;
  23002. tNext = t1 + pp[1] - pp[0];
  23003. break;
  23004. default:
  23005. // ZeroCurvatureEnding
  23006. // f''(tN) = 0, a.k.a. Natural Spline
  23007. iNext = i1 - 1;
  23008. tNext = t0;
  23009. }
  23010. }
  23011. const halfDt = (t1 - t0) * 0.5,
  23012. stride = this.valueSize;
  23013. this._weightPrev = halfDt / (t0 - tPrev);
  23014. this._weightNext = halfDt / (tNext - t1);
  23015. this._offsetPrev = iPrev * stride;
  23016. this._offsetNext = iNext * stride;
  23017. }
  23018. interpolate_(i1, t0, t, t1) {
  23019. const result = this.resultBuffer,
  23020. values = this.sampleValues,
  23021. stride = this.valueSize,
  23022. o1 = i1 * stride,
  23023. o0 = o1 - stride,
  23024. oP = this._offsetPrev,
  23025. oN = this._offsetNext,
  23026. wP = this._weightPrev,
  23027. wN = this._weightNext,
  23028. p = (t - t0) / (t1 - t0),
  23029. pp = p * p,
  23030. ppp = pp * p; // evaluate polynomials
  23031. const sP = -wP * ppp + 2 * wP * pp - wP * p;
  23032. const s0 = (1 + wP) * ppp + (-1.5 - 2 * wP) * pp + (-0.5 + wP) * p + 1;
  23033. const s1 = (-1 - wN) * ppp + (1.5 + wN) * pp + 0.5 * p;
  23034. const sN = wN * ppp - wN * pp; // combine data linearly
  23035. for (let i = 0; i !== stride; ++i) {
  23036. result[i] = sP * values[oP + i] + s0 * values[o0 + i] + s1 * values[o1 + i] + sN * values[oN + i];
  23037. }
  23038. return result;
  23039. }
  23040. }
  23041. class LinearInterpolant extends Interpolant {
  23042. constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  23043. super(parameterPositions, sampleValues, sampleSize, resultBuffer);
  23044. }
  23045. interpolate_(i1, t0, t, t1) {
  23046. const result = this.resultBuffer,
  23047. values = this.sampleValues,
  23048. stride = this.valueSize,
  23049. offset1 = i1 * stride,
  23050. offset0 = offset1 - stride,
  23051. weight1 = (t - t0) / (t1 - t0),
  23052. weight0 = 1 - weight1;
  23053. for (let i = 0; i !== stride; ++i) {
  23054. result[i] = values[offset0 + i] * weight0 + values[offset1 + i] * weight1;
  23055. }
  23056. return result;
  23057. }
  23058. }
  23059. /**
  23060. *
  23061. * Interpolant that evaluates to the sample value at the position preceding
  23062. * the parameter.
  23063. */
  23064. class DiscreteInterpolant extends Interpolant {
  23065. constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  23066. super(parameterPositions, sampleValues, sampleSize, resultBuffer);
  23067. }
  23068. interpolate_(i1
  23069. /*, t0, t, t1 */
  23070. ) {
  23071. return this.copySampleValue_(i1 - 1);
  23072. }
  23073. }
  23074. class KeyframeTrack {
  23075. constructor(name, times, values, interpolation) {
  23076. if (name === undefined) throw new Error('THREE.KeyframeTrack: track name is undefined');
  23077. if (times === undefined || times.length === 0) throw new Error('THREE.KeyframeTrack: no keyframes in track named ' + name);
  23078. this.name = name;
  23079. this.times = convertArray(times, this.TimeBufferType);
  23080. this.values = convertArray(values, this.ValueBufferType);
  23081. this.setInterpolation(interpolation || this.DefaultInterpolation);
  23082. } // Serialization (in static context, because of constructor invocation
  23083. // and automatic invocation of .toJSON):
  23084. static toJSON(track) {
  23085. const trackType = track.constructor;
  23086. let json; // derived classes can define a static toJSON method
  23087. if (trackType.toJSON !== this.toJSON) {
  23088. json = trackType.toJSON(track);
  23089. } else {
  23090. // by default, we assume the data can be serialized as-is
  23091. json = {
  23092. 'name': track.name,
  23093. 'times': convertArray(track.times, Array),
  23094. 'values': convertArray(track.values, Array)
  23095. };
  23096. const interpolation = track.getInterpolation();
  23097. if (interpolation !== track.DefaultInterpolation) {
  23098. json.interpolation = interpolation;
  23099. }
  23100. }
  23101. json.type = track.ValueTypeName; // mandatory
  23102. return json;
  23103. }
  23104. InterpolantFactoryMethodDiscrete(result) {
  23105. return new DiscreteInterpolant(this.times, this.values, this.getValueSize(), result);
  23106. }
  23107. InterpolantFactoryMethodLinear(result) {
  23108. return new LinearInterpolant(this.times, this.values, this.getValueSize(), result);
  23109. }
  23110. InterpolantFactoryMethodSmooth(result) {
  23111. return new CubicInterpolant(this.times, this.values, this.getValueSize(), result);
  23112. }
  23113. setInterpolation(interpolation) {
  23114. let factoryMethod;
  23115. switch (interpolation) {
  23116. case InterpolateDiscrete:
  23117. factoryMethod = this.InterpolantFactoryMethodDiscrete;
  23118. break;
  23119. case InterpolateLinear:
  23120. factoryMethod = this.InterpolantFactoryMethodLinear;
  23121. break;
  23122. case InterpolateSmooth:
  23123. factoryMethod = this.InterpolantFactoryMethodSmooth;
  23124. break;
  23125. }
  23126. if (factoryMethod === undefined) {
  23127. const message = 'unsupported interpolation for ' + this.ValueTypeName + ' keyframe track named ' + this.name;
  23128. if (this.createInterpolant === undefined) {
  23129. // fall back to default, unless the default itself is messed up
  23130. if (interpolation !== this.DefaultInterpolation) {
  23131. this.setInterpolation(this.DefaultInterpolation);
  23132. } else {
  23133. throw new Error(message); // fatal, in this case
  23134. }
  23135. }
  23136. console.warn('THREE.KeyframeTrack:', message);
  23137. return this;
  23138. }
  23139. this.createInterpolant = factoryMethod;
  23140. return this;
  23141. }
  23142. getInterpolation() {
  23143. switch (this.createInterpolant) {
  23144. case this.InterpolantFactoryMethodDiscrete:
  23145. return InterpolateDiscrete;
  23146. case this.InterpolantFactoryMethodLinear:
  23147. return InterpolateLinear;
  23148. case this.InterpolantFactoryMethodSmooth:
  23149. return InterpolateSmooth;
  23150. }
  23151. }
  23152. getValueSize() {
  23153. return this.values.length / this.times.length;
  23154. } // move all keyframes either forwards or backwards in time
  23155. shift(timeOffset) {
  23156. if (timeOffset !== 0.0) {
  23157. const times = this.times;
  23158. for (let i = 0, n = times.length; i !== n; ++i) {
  23159. times[i] += timeOffset;
  23160. }
  23161. }
  23162. return this;
  23163. } // scale all keyframe times by a factor (useful for frame <-> seconds conversions)
  23164. scale(timeScale) {
  23165. if (timeScale !== 1.0) {
  23166. const times = this.times;
  23167. for (let i = 0, n = times.length; i !== n; ++i) {
  23168. times[i] *= timeScale;
  23169. }
  23170. }
  23171. return this;
  23172. } // removes keyframes before and after animation without changing any values within the range [startTime, endTime].
  23173. // IMPORTANT: We do not shift around keys to the start of the track time, because for interpolated keys this will change their values
  23174. trim(startTime, endTime) {
  23175. const times = this.times,
  23176. nKeys = times.length;
  23177. let from = 0,
  23178. to = nKeys - 1;
  23179. while (from !== nKeys && times[from] < startTime) {
  23180. ++from;
  23181. }
  23182. while (to !== -1 && times[to] > endTime) {
  23183. --to;
  23184. }
  23185. ++to; // inclusive -> exclusive bound
  23186. if (from !== 0 || to !== nKeys) {
  23187. // empty tracks are forbidden, so keep at least one keyframe
  23188. if (from >= to) {
  23189. to = Math.max(to, 1);
  23190. from = to - 1;
  23191. }
  23192. const stride = this.getValueSize();
  23193. this.times = arraySlice(times, from, to);
  23194. this.values = arraySlice(this.values, from * stride, to * stride);
  23195. }
  23196. return this;
  23197. } // ensure we do not get a GarbageInGarbageOut situation, make sure tracks are at least minimally viable
  23198. validate() {
  23199. let valid = true;
  23200. const valueSize = this.getValueSize();
  23201. if (valueSize - Math.floor(valueSize) !== 0) {
  23202. console.error('THREE.KeyframeTrack: Invalid value size in track.', this);
  23203. valid = false;
  23204. }
  23205. const times = this.times,
  23206. values = this.values,
  23207. nKeys = times.length;
  23208. if (nKeys === 0) {
  23209. console.error('THREE.KeyframeTrack: Track is empty.', this);
  23210. valid = false;
  23211. }
  23212. let prevTime = null;
  23213. for (let i = 0; i !== nKeys; i++) {
  23214. const currTime = times[i];
  23215. if (typeof currTime === 'number' && isNaN(currTime)) {
  23216. console.error('THREE.KeyframeTrack: Time is not a valid number.', this, i, currTime);
  23217. valid = false;
  23218. break;
  23219. }
  23220. if (prevTime !== null && prevTime > currTime) {
  23221. console.error('THREE.KeyframeTrack: Out of order keys.', this, i, currTime, prevTime);
  23222. valid = false;
  23223. break;
  23224. }
  23225. prevTime = currTime;
  23226. }
  23227. if (values !== undefined) {
  23228. if (isTypedArray(values)) {
  23229. for (let i = 0, n = values.length; i !== n; ++i) {
  23230. const value = values[i];
  23231. if (isNaN(value)) {
  23232. console.error('THREE.KeyframeTrack: Value is not a valid number.', this, i, value);
  23233. valid = false;
  23234. break;
  23235. }
  23236. }
  23237. }
  23238. }
  23239. return valid;
  23240. } // removes equivalent sequential keys as common in morph target sequences
  23241. // (0,0,0,0,1,1,1,0,0,0,0,0,0,0) --> (0,0,1,1,0,0)
  23242. optimize() {
  23243. // times or values may be shared with other tracks, so overwriting is unsafe
  23244. const times = arraySlice(this.times),
  23245. values = arraySlice(this.values),
  23246. stride = this.getValueSize(),
  23247. smoothInterpolation = this.getInterpolation() === InterpolateSmooth,
  23248. lastIndex = times.length - 1;
  23249. let writeIndex = 1;
  23250. for (let i = 1; i < lastIndex; ++i) {
  23251. let keep = false;
  23252. const time = times[i];
  23253. const timeNext = times[i + 1]; // remove adjacent keyframes scheduled at the same time
  23254. if (time !== timeNext && (i !== 1 || time !== times[0])) {
  23255. if (!smoothInterpolation) {
  23256. // remove unnecessary keyframes same as their neighbors
  23257. const offset = i * stride,
  23258. offsetP = offset - stride,
  23259. offsetN = offset + stride;
  23260. for (let j = 0; j !== stride; ++j) {
  23261. const value = values[offset + j];
  23262. if (value !== values[offsetP + j] || value !== values[offsetN + j]) {
  23263. keep = true;
  23264. break;
  23265. }
  23266. }
  23267. } else {
  23268. keep = true;
  23269. }
  23270. } // in-place compaction
  23271. if (keep) {
  23272. if (i !== writeIndex) {
  23273. times[writeIndex] = times[i];
  23274. const readOffset = i * stride,
  23275. writeOffset = writeIndex * stride;
  23276. for (let j = 0; j !== stride; ++j) {
  23277. values[writeOffset + j] = values[readOffset + j];
  23278. }
  23279. }
  23280. ++writeIndex;
  23281. }
  23282. } // flush last keyframe (compaction looks ahead)
  23283. if (lastIndex > 0) {
  23284. times[writeIndex] = times[lastIndex];
  23285. for (let readOffset = lastIndex * stride, writeOffset = writeIndex * stride, j = 0; j !== stride; ++j) {
  23286. values[writeOffset + j] = values[readOffset + j];
  23287. }
  23288. ++writeIndex;
  23289. }
  23290. if (writeIndex !== times.length) {
  23291. this.times = arraySlice(times, 0, writeIndex);
  23292. this.values = arraySlice(values, 0, writeIndex * stride);
  23293. } else {
  23294. this.times = times;
  23295. this.values = values;
  23296. }
  23297. return this;
  23298. }
  23299. clone() {
  23300. const times = arraySlice(this.times, 0);
  23301. const values = arraySlice(this.values, 0);
  23302. const TypedKeyframeTrack = this.constructor;
  23303. const track = new TypedKeyframeTrack(this.name, times, values); // Interpolant argument to constructor is not saved, so copy the factory method directly.
  23304. track.createInterpolant = this.createInterpolant;
  23305. return track;
  23306. }
  23307. }
  23308. KeyframeTrack.prototype.TimeBufferType = Float32Array;
  23309. KeyframeTrack.prototype.ValueBufferType = Float32Array;
  23310. KeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
  23311. /**
  23312. * A Track of Boolean keyframe values.
  23313. */
  23314. class BooleanKeyframeTrack extends KeyframeTrack {}
  23315. BooleanKeyframeTrack.prototype.ValueTypeName = 'bool';
  23316. BooleanKeyframeTrack.prototype.ValueBufferType = Array;
  23317. BooleanKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
  23318. BooleanKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
  23319. BooleanKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined; // Note: Actually this track could have a optimized / compressed
  23320. /**
  23321. * A Track of keyframe values that represent color.
  23322. */
  23323. class ColorKeyframeTrack extends KeyframeTrack {}
  23324. ColorKeyframeTrack.prototype.ValueTypeName = 'color'; // ValueBufferType is inherited
  23325. /**
  23326. * A Track of numeric keyframe values.
  23327. */
  23328. class NumberKeyframeTrack extends KeyframeTrack {}
  23329. NumberKeyframeTrack.prototype.ValueTypeName = 'number'; // ValueBufferType is inherited
  23330. /**
  23331. * Spherical linear unit quaternion interpolant.
  23332. */
  23333. class QuaternionLinearInterpolant extends Interpolant {
  23334. constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  23335. super(parameterPositions, sampleValues, sampleSize, resultBuffer);
  23336. }
  23337. interpolate_(i1, t0, t, t1) {
  23338. const result = this.resultBuffer,
  23339. values = this.sampleValues,
  23340. stride = this.valueSize,
  23341. alpha = (t - t0) / (t1 - t0);
  23342. let offset = i1 * stride;
  23343. for (let end = offset + stride; offset !== end; offset += 4) {
  23344. Quaternion.slerpFlat(result, 0, values, offset - stride, values, offset, alpha);
  23345. }
  23346. return result;
  23347. }
  23348. }
  23349. /**
  23350. * A Track of quaternion keyframe values.
  23351. */
  23352. class QuaternionKeyframeTrack extends KeyframeTrack {
  23353. InterpolantFactoryMethodLinear(result) {
  23354. return new QuaternionLinearInterpolant(this.times, this.values, this.getValueSize(), result);
  23355. }
  23356. }
  23357. QuaternionKeyframeTrack.prototype.ValueTypeName = 'quaternion'; // ValueBufferType is inherited
  23358. QuaternionKeyframeTrack.prototype.DefaultInterpolation = InterpolateLinear;
  23359. QuaternionKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
  23360. /**
  23361. * A Track that interpolates Strings
  23362. */
  23363. class StringKeyframeTrack extends KeyframeTrack {}
  23364. StringKeyframeTrack.prototype.ValueTypeName = 'string';
  23365. StringKeyframeTrack.prototype.ValueBufferType = Array;
  23366. StringKeyframeTrack.prototype.DefaultInterpolation = InterpolateDiscrete;
  23367. StringKeyframeTrack.prototype.InterpolantFactoryMethodLinear = undefined;
  23368. StringKeyframeTrack.prototype.InterpolantFactoryMethodSmooth = undefined;
  23369. /**
  23370. * A Track of vectored keyframe values.
  23371. */
  23372. class VectorKeyframeTrack extends KeyframeTrack {}
  23373. VectorKeyframeTrack.prototype.ValueTypeName = 'vector'; // ValueBufferType is inherited
  23374. class AnimationClip {
  23375. constructor(name, duration = -1, tracks, blendMode = NormalAnimationBlendMode) {
  23376. this.name = name;
  23377. this.tracks = tracks;
  23378. this.duration = duration;
  23379. this.blendMode = blendMode;
  23380. this.uuid = generateUUID(); // this means it should figure out its duration by scanning the tracks
  23381. if (this.duration < 0) {
  23382. this.resetDuration();
  23383. }
  23384. }
  23385. static parse(json) {
  23386. const tracks = [],
  23387. jsonTracks = json.tracks,
  23388. frameTime = 1.0 / (json.fps || 1.0);
  23389. for (let i = 0, n = jsonTracks.length; i !== n; ++i) {
  23390. tracks.push(parseKeyframeTrack(jsonTracks[i]).scale(frameTime));
  23391. }
  23392. const clip = new this(json.name, json.duration, tracks, json.blendMode);
  23393. clip.uuid = json.uuid;
  23394. return clip;
  23395. }
  23396. static toJSON(clip) {
  23397. const tracks = [],
  23398. clipTracks = clip.tracks;
  23399. const json = {
  23400. 'name': clip.name,
  23401. 'duration': clip.duration,
  23402. 'tracks': tracks,
  23403. 'uuid': clip.uuid,
  23404. 'blendMode': clip.blendMode
  23405. };
  23406. for (let i = 0, n = clipTracks.length; i !== n; ++i) {
  23407. tracks.push(KeyframeTrack.toJSON(clipTracks[i]));
  23408. }
  23409. return json;
  23410. }
  23411. static CreateFromMorphTargetSequence(name, morphTargetSequence, fps, noLoop) {
  23412. const numMorphTargets = morphTargetSequence.length;
  23413. const tracks = [];
  23414. for (let i = 0; i < numMorphTargets; i++) {
  23415. let times = [];
  23416. let values = [];
  23417. times.push((i + numMorphTargets - 1) % numMorphTargets, i, (i + 1) % numMorphTargets);
  23418. values.push(0, 1, 0);
  23419. const order = getKeyframeOrder(times);
  23420. times = sortedArray(times, 1, order);
  23421. values = sortedArray(values, 1, order); // if there is a key at the first frame, duplicate it as the
  23422. // last frame as well for perfect loop.
  23423. if (!noLoop && times[0] === 0) {
  23424. times.push(numMorphTargets);
  23425. values.push(values[0]);
  23426. }
  23427. tracks.push(new NumberKeyframeTrack('.morphTargetInfluences[' + morphTargetSequence[i].name + ']', times, values).scale(1.0 / fps));
  23428. }
  23429. return new this(name, -1, tracks);
  23430. }
  23431. static findByName(objectOrClipArray, name) {
  23432. let clipArray = objectOrClipArray;
  23433. if (!Array.isArray(objectOrClipArray)) {
  23434. const o = objectOrClipArray;
  23435. clipArray = o.geometry && o.geometry.animations || o.animations;
  23436. }
  23437. for (let i = 0; i < clipArray.length; i++) {
  23438. if (clipArray[i].name === name) {
  23439. return clipArray[i];
  23440. }
  23441. }
  23442. return null;
  23443. }
  23444. static CreateClipsFromMorphTargetSequences(morphTargets, fps, noLoop) {
  23445. const animationToMorphTargets = {}; // tested with https://regex101.com/ on trick sequences
  23446. // such flamingo_flyA_003, flamingo_run1_003, crdeath0059
  23447. const pattern = /^([\w-]*?)([\d]+)$/; // sort morph target names into animation groups based
  23448. // patterns like Walk_001, Walk_002, Run_001, Run_002
  23449. for (let i = 0, il = morphTargets.length; i < il; i++) {
  23450. const morphTarget = morphTargets[i];
  23451. const parts = morphTarget.name.match(pattern);
  23452. if (parts && parts.length > 1) {
  23453. const name = parts[1];
  23454. let animationMorphTargets = animationToMorphTargets[name];
  23455. if (!animationMorphTargets) {
  23456. animationToMorphTargets[name] = animationMorphTargets = [];
  23457. }
  23458. animationMorphTargets.push(morphTarget);
  23459. }
  23460. }
  23461. const clips = [];
  23462. for (const name in animationToMorphTargets) {
  23463. clips.push(this.CreateFromMorphTargetSequence(name, animationToMorphTargets[name], fps, noLoop));
  23464. }
  23465. return clips;
  23466. } // parse the animation.hierarchy format
  23467. static parseAnimation(animation, bones) {
  23468. if (!animation) {
  23469. console.error('THREE.AnimationClip: No animation in JSONLoader data.');
  23470. return null;
  23471. }
  23472. const addNonemptyTrack = function (trackType, trackName, animationKeys, propertyName, destTracks) {
  23473. // only return track if there are actually keys.
  23474. if (animationKeys.length !== 0) {
  23475. const times = [];
  23476. const values = [];
  23477. flattenJSON(animationKeys, times, values, propertyName); // empty keys are filtered out, so check again
  23478. if (times.length !== 0) {
  23479. destTracks.push(new trackType(trackName, times, values));
  23480. }
  23481. }
  23482. };
  23483. const tracks = [];
  23484. const clipName = animation.name || 'default';
  23485. const fps = animation.fps || 30;
  23486. const blendMode = animation.blendMode; // automatic length determination in AnimationClip.
  23487. let duration = animation.length || -1;
  23488. const hierarchyTracks = animation.hierarchy || [];
  23489. for (let h = 0; h < hierarchyTracks.length; h++) {
  23490. const animationKeys = hierarchyTracks[h].keys; // skip empty tracks
  23491. if (!animationKeys || animationKeys.length === 0) continue; // process morph targets
  23492. if (animationKeys[0].morphTargets) {
  23493. // figure out all morph targets used in this track
  23494. const morphTargetNames = {};
  23495. let k;
  23496. for (k = 0; k < animationKeys.length; k++) {
  23497. if (animationKeys[k].morphTargets) {
  23498. for (let m = 0; m < animationKeys[k].morphTargets.length; m++) {
  23499. morphTargetNames[animationKeys[k].morphTargets[m]] = -1;
  23500. }
  23501. }
  23502. } // create a track for each morph target with all zero
  23503. // morphTargetInfluences except for the keys in which
  23504. // the morphTarget is named.
  23505. for (const morphTargetName in morphTargetNames) {
  23506. const times = [];
  23507. const values = [];
  23508. for (let m = 0; m !== animationKeys[k].morphTargets.length; ++m) {
  23509. const animationKey = animationKeys[k];
  23510. times.push(animationKey.time);
  23511. values.push(animationKey.morphTarget === morphTargetName ? 1 : 0);
  23512. }
  23513. tracks.push(new NumberKeyframeTrack('.morphTargetInfluence[' + morphTargetName + ']', times, values));
  23514. }
  23515. duration = morphTargetNames.length * fps;
  23516. } else {
  23517. // ...assume skeletal animation
  23518. const boneName = '.bones[' + bones[h].name + ']';
  23519. addNonemptyTrack(VectorKeyframeTrack, boneName + '.position', animationKeys, 'pos', tracks);
  23520. addNonemptyTrack(QuaternionKeyframeTrack, boneName + '.quaternion', animationKeys, 'rot', tracks);
  23521. addNonemptyTrack(VectorKeyframeTrack, boneName + '.scale', animationKeys, 'scl', tracks);
  23522. }
  23523. }
  23524. if (tracks.length === 0) {
  23525. return null;
  23526. }
  23527. const clip = new this(clipName, duration, tracks, blendMode);
  23528. return clip;
  23529. }
  23530. resetDuration() {
  23531. const tracks = this.tracks;
  23532. let duration = 0;
  23533. for (let i = 0, n = tracks.length; i !== n; ++i) {
  23534. const track = this.tracks[i];
  23535. duration = Math.max(duration, track.times[track.times.length - 1]);
  23536. }
  23537. this.duration = duration;
  23538. return this;
  23539. }
  23540. trim() {
  23541. for (let i = 0; i < this.tracks.length; i++) {
  23542. this.tracks[i].trim(0, this.duration);
  23543. }
  23544. return this;
  23545. }
  23546. validate() {
  23547. let valid = true;
  23548. for (let i = 0; i < this.tracks.length; i++) {
  23549. valid = valid && this.tracks[i].validate();
  23550. }
  23551. return valid;
  23552. }
  23553. optimize() {
  23554. for (let i = 0; i < this.tracks.length; i++) {
  23555. this.tracks[i].optimize();
  23556. }
  23557. return this;
  23558. }
  23559. clone() {
  23560. const tracks = [];
  23561. for (let i = 0; i < this.tracks.length; i++) {
  23562. tracks.push(this.tracks[i].clone());
  23563. }
  23564. return new this.constructor(this.name, this.duration, tracks, this.blendMode);
  23565. }
  23566. toJSON() {
  23567. return this.constructor.toJSON(this);
  23568. }
  23569. }
  23570. function getTrackTypeForValueTypeName(typeName) {
  23571. switch (typeName.toLowerCase()) {
  23572. case 'scalar':
  23573. case 'double':
  23574. case 'float':
  23575. case 'number':
  23576. case 'integer':
  23577. return NumberKeyframeTrack;
  23578. case 'vector':
  23579. case 'vector2':
  23580. case 'vector3':
  23581. case 'vector4':
  23582. return VectorKeyframeTrack;
  23583. case 'color':
  23584. return ColorKeyframeTrack;
  23585. case 'quaternion':
  23586. return QuaternionKeyframeTrack;
  23587. case 'bool':
  23588. case 'boolean':
  23589. return BooleanKeyframeTrack;
  23590. case 'string':
  23591. return StringKeyframeTrack;
  23592. }
  23593. throw new Error('THREE.KeyframeTrack: Unsupported typeName: ' + typeName);
  23594. }
  23595. function parseKeyframeTrack(json) {
  23596. if (json.type === undefined) {
  23597. throw new Error('THREE.KeyframeTrack: track type undefined, can not parse');
  23598. }
  23599. const trackType = getTrackTypeForValueTypeName(json.type);
  23600. if (json.times === undefined) {
  23601. const times = [],
  23602. values = [];
  23603. flattenJSON(json.keys, times, values, 'value');
  23604. json.times = times;
  23605. json.values = values;
  23606. } // derived classes can define a static parse method
  23607. if (trackType.parse !== undefined) {
  23608. return trackType.parse(json);
  23609. } else {
  23610. // by default, we assume a constructor compatible with the base
  23611. return new trackType(json.name, json.times, json.values, json.interpolation);
  23612. }
  23613. }
  23614. const Cache = {
  23615. enabled: false,
  23616. files: {},
  23617. add: function (key, file) {
  23618. if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Adding key:', key );
  23619. this.files[key] = file;
  23620. },
  23621. get: function (key) {
  23622. if (this.enabled === false) return; // console.log( 'THREE.Cache', 'Checking key:', key );
  23623. return this.files[key];
  23624. },
  23625. remove: function (key) {
  23626. delete this.files[key];
  23627. },
  23628. clear: function () {
  23629. this.files = {};
  23630. }
  23631. };
  23632. class LoadingManager {
  23633. constructor(onLoad, onProgress, onError) {
  23634. const scope = this;
  23635. let isLoading = false;
  23636. let itemsLoaded = 0;
  23637. let itemsTotal = 0;
  23638. let urlModifier = undefined;
  23639. const handlers = []; // Refer to #5689 for the reason why we don't set .onStart
  23640. // in the constructor
  23641. this.onStart = undefined;
  23642. this.onLoad = onLoad;
  23643. this.onProgress = onProgress;
  23644. this.onError = onError;
  23645. this.itemStart = function (url) {
  23646. itemsTotal++;
  23647. if (isLoading === false) {
  23648. if (scope.onStart !== undefined) {
  23649. scope.onStart(url, itemsLoaded, itemsTotal);
  23650. }
  23651. }
  23652. isLoading = true;
  23653. };
  23654. this.itemEnd = function (url) {
  23655. itemsLoaded++;
  23656. if (scope.onProgress !== undefined) {
  23657. scope.onProgress(url, itemsLoaded, itemsTotal);
  23658. }
  23659. if (itemsLoaded === itemsTotal) {
  23660. isLoading = false;
  23661. if (scope.onLoad !== undefined) {
  23662. scope.onLoad();
  23663. }
  23664. }
  23665. };
  23666. this.itemError = function (url) {
  23667. if (scope.onError !== undefined) {
  23668. scope.onError(url);
  23669. }
  23670. };
  23671. this.resolveURL = function (url) {
  23672. if (urlModifier) {
  23673. return urlModifier(url);
  23674. }
  23675. return url;
  23676. };
  23677. this.setURLModifier = function (transform) {
  23678. urlModifier = transform;
  23679. return this;
  23680. };
  23681. this.addHandler = function (regex, loader) {
  23682. handlers.push(regex, loader);
  23683. return this;
  23684. };
  23685. this.removeHandler = function (regex) {
  23686. const index = handlers.indexOf(regex);
  23687. if (index !== -1) {
  23688. handlers.splice(index, 2);
  23689. }
  23690. return this;
  23691. };
  23692. this.getHandler = function (file) {
  23693. for (let i = 0, l = handlers.length; i < l; i += 2) {
  23694. const regex = handlers[i];
  23695. const loader = handlers[i + 1];
  23696. if (regex.global) regex.lastIndex = 0; // see #17920
  23697. if (regex.test(file)) {
  23698. return loader;
  23699. }
  23700. }
  23701. return null;
  23702. };
  23703. }
  23704. }
  23705. const DefaultLoadingManager = /*@__PURE__*/new LoadingManager();
  23706. class Loader {
  23707. constructor(manager) {
  23708. this.manager = manager !== undefined ? manager : DefaultLoadingManager;
  23709. this.crossOrigin = 'anonymous';
  23710. this.withCredentials = false;
  23711. this.path = '';
  23712. this.resourcePath = '';
  23713. this.requestHeader = {};
  23714. }
  23715. load() {}
  23716. loadAsync(url, onProgress) {
  23717. const scope = this;
  23718. return new Promise(function (resolve, reject) {
  23719. scope.load(url, resolve, onProgress, reject);
  23720. });
  23721. }
  23722. parse() {}
  23723. setCrossOrigin(crossOrigin) {
  23724. this.crossOrigin = crossOrigin;
  23725. return this;
  23726. }
  23727. setWithCredentials(value) {
  23728. this.withCredentials = value;
  23729. return this;
  23730. }
  23731. setPath(path) {
  23732. this.path = path;
  23733. return this;
  23734. }
  23735. setResourcePath(resourcePath) {
  23736. this.resourcePath = resourcePath;
  23737. return this;
  23738. }
  23739. setRequestHeader(requestHeader) {
  23740. this.requestHeader = requestHeader;
  23741. return this;
  23742. }
  23743. }
  23744. const loading = {};
  23745. class HttpError extends Error {
  23746. constructor(message, response) {
  23747. super(message);
  23748. this.response = response;
  23749. }
  23750. }
  23751. class FileLoader extends Loader {
  23752. constructor(manager) {
  23753. super(manager);
  23754. }
  23755. load(url, onLoad, onProgress, onError) {
  23756. if (url === undefined) url = '';
  23757. if (this.path !== undefined) url = this.path + url;
  23758. url = this.manager.resolveURL(url);
  23759. const cached = Cache.get(url);
  23760. if (cached !== undefined) {
  23761. this.manager.itemStart(url);
  23762. setTimeout(() => {
  23763. if (onLoad) onLoad(cached);
  23764. this.manager.itemEnd(url);
  23765. }, 0);
  23766. return cached;
  23767. } // Check if request is duplicate
  23768. if (loading[url] !== undefined) {
  23769. loading[url].push({
  23770. onLoad: onLoad,
  23771. onProgress: onProgress,
  23772. onError: onError
  23773. });
  23774. return;
  23775. } // Initialise array for duplicate requests
  23776. loading[url] = [];
  23777. loading[url].push({
  23778. onLoad: onLoad,
  23779. onProgress: onProgress,
  23780. onError: onError
  23781. }); // create request
  23782. const req = new Request(url, {
  23783. headers: new Headers(this.requestHeader),
  23784. credentials: this.withCredentials ? 'include' : 'same-origin' // An abort controller could be added within a future PR
  23785. }); // record states ( avoid data race )
  23786. const mimeType = this.mimeType;
  23787. const responseType = this.responseType; // start the fetch
  23788. fetch(req).then(response => {
  23789. if (response.status === 200 || response.status === 0) {
  23790. // Some browsers return HTTP Status 0 when using non-http protocol
  23791. // e.g. 'file://' or 'data://'. Handle as success.
  23792. if (response.status === 0) {
  23793. console.warn('THREE.FileLoader: HTTP Status 0 received.');
  23794. } // Workaround: Checking if response.body === undefined for Alipay browser #23548
  23795. if (typeof ReadableStream === 'undefined' || response.body === undefined || response.body.getReader === undefined) {
  23796. return response;
  23797. }
  23798. const callbacks = loading[url];
  23799. const reader = response.body.getReader();
  23800. const contentLength = response.headers.get('Content-Length');
  23801. const total = contentLength ? parseInt(contentLength) : 0;
  23802. const lengthComputable = total !== 0;
  23803. let loaded = 0; // periodically read data into the new stream tracking while download progress
  23804. const stream = new ReadableStream({
  23805. start(controller) {
  23806. readData();
  23807. function readData() {
  23808. reader.read().then(({
  23809. done,
  23810. value
  23811. }) => {
  23812. if (done) {
  23813. controller.close();
  23814. } else {
  23815. loaded += value.byteLength;
  23816. const event = new ProgressEvent('progress', {
  23817. lengthComputable,
  23818. loaded,
  23819. total
  23820. });
  23821. for (let i = 0, il = callbacks.length; i < il; i++) {
  23822. const callback = callbacks[i];
  23823. if (callback.onProgress) callback.onProgress(event);
  23824. }
  23825. controller.enqueue(value);
  23826. readData();
  23827. }
  23828. });
  23829. }
  23830. }
  23831. });
  23832. return new Response(stream);
  23833. } else {
  23834. throw new HttpError(`fetch for "${response.url}" responded with ${response.status}: ${response.statusText}`, response);
  23835. }
  23836. }).then(response => {
  23837. switch (responseType) {
  23838. case 'arraybuffer':
  23839. return response.arrayBuffer();
  23840. case 'blob':
  23841. return response.blob();
  23842. case 'document':
  23843. return response.text().then(text => {
  23844. const parser = new DOMParser();
  23845. return parser.parseFromString(text, mimeType);
  23846. });
  23847. case 'json':
  23848. return response.json();
  23849. default:
  23850. if (mimeType === undefined) {
  23851. return response.text();
  23852. } else {
  23853. // sniff encoding
  23854. const re = /charset="?([^;"\s]*)"?/i;
  23855. const exec = re.exec(mimeType);
  23856. const label = exec && exec[1] ? exec[1].toLowerCase() : undefined;
  23857. const decoder = new TextDecoder(label);
  23858. return response.arrayBuffer().then(ab => decoder.decode(ab));
  23859. }
  23860. }
  23861. }).then(data => {
  23862. // Add to cache only on HTTP success, so that we do not cache
  23863. // error response bodies as proper responses to requests.
  23864. Cache.add(url, data);
  23865. const callbacks = loading[url];
  23866. delete loading[url];
  23867. for (let i = 0, il = callbacks.length; i < il; i++) {
  23868. const callback = callbacks[i];
  23869. if (callback.onLoad) callback.onLoad(data);
  23870. }
  23871. }).catch(err => {
  23872. // Abort errors and other errors are handled the same
  23873. const callbacks = loading[url];
  23874. if (callbacks === undefined) {
  23875. // When onLoad was called and url was deleted in `loading`
  23876. this.manager.itemError(url);
  23877. throw err;
  23878. }
  23879. delete loading[url];
  23880. for (let i = 0, il = callbacks.length; i < il; i++) {
  23881. const callback = callbacks[i];
  23882. if (callback.onError) callback.onError(err);
  23883. }
  23884. this.manager.itemError(url);
  23885. }).finally(() => {
  23886. this.manager.itemEnd(url);
  23887. });
  23888. this.manager.itemStart(url);
  23889. }
  23890. setResponseType(value) {
  23891. this.responseType = value;
  23892. return this;
  23893. }
  23894. setMimeType(value) {
  23895. this.mimeType = value;
  23896. return this;
  23897. }
  23898. }
  23899. class AnimationLoader extends Loader {
  23900. constructor(manager) {
  23901. super(manager);
  23902. }
  23903. load(url, onLoad, onProgress, onError) {
  23904. const scope = this;
  23905. const loader = new FileLoader(this.manager);
  23906. loader.setPath(this.path);
  23907. loader.setRequestHeader(this.requestHeader);
  23908. loader.setWithCredentials(this.withCredentials);
  23909. loader.load(url, function (text) {
  23910. try {
  23911. onLoad(scope.parse(JSON.parse(text)));
  23912. } catch (e) {
  23913. if (onError) {
  23914. onError(e);
  23915. } else {
  23916. console.error(e);
  23917. }
  23918. scope.manager.itemError(url);
  23919. }
  23920. }, onProgress, onError);
  23921. }
  23922. parse(json) {
  23923. const animations = [];
  23924. for (let i = 0; i < json.length; i++) {
  23925. const clip = AnimationClip.parse(json[i]);
  23926. animations.push(clip);
  23927. }
  23928. return animations;
  23929. }
  23930. }
  23931. /**
  23932. * Abstract Base class to block based textures loader (dds, pvr, ...)
  23933. *
  23934. * Sub classes have to implement the parse() method which will be used in load().
  23935. */
  23936. class CompressedTextureLoader extends Loader {
  23937. constructor(manager) {
  23938. super(manager);
  23939. }
  23940. load(url, onLoad, onProgress, onError) {
  23941. const scope = this;
  23942. const images = [];
  23943. const texture = new CompressedTexture();
  23944. const loader = new FileLoader(this.manager);
  23945. loader.setPath(this.path);
  23946. loader.setResponseType('arraybuffer');
  23947. loader.setRequestHeader(this.requestHeader);
  23948. loader.setWithCredentials(scope.withCredentials);
  23949. let loaded = 0;
  23950. function loadTexture(i) {
  23951. loader.load(url[i], function (buffer) {
  23952. const texDatas = scope.parse(buffer, true);
  23953. images[i] = {
  23954. width: texDatas.width,
  23955. height: texDatas.height,
  23956. format: texDatas.format,
  23957. mipmaps: texDatas.mipmaps
  23958. };
  23959. loaded += 1;
  23960. if (loaded === 6) {
  23961. if (texDatas.mipmapCount === 1) texture.minFilter = LinearFilter;
  23962. texture.image = images;
  23963. texture.format = texDatas.format;
  23964. texture.needsUpdate = true;
  23965. if (onLoad) onLoad(texture);
  23966. }
  23967. }, onProgress, onError);
  23968. }
  23969. if (Array.isArray(url)) {
  23970. for (let i = 0, il = url.length; i < il; ++i) {
  23971. loadTexture(i);
  23972. }
  23973. } else {
  23974. // compressed cubemap texture stored in a single DDS file
  23975. loader.load(url, function (buffer) {
  23976. const texDatas = scope.parse(buffer, true);
  23977. if (texDatas.isCubemap) {
  23978. const faces = texDatas.mipmaps.length / texDatas.mipmapCount;
  23979. for (let f = 0; f < faces; f++) {
  23980. images[f] = {
  23981. mipmaps: []
  23982. };
  23983. for (let i = 0; i < texDatas.mipmapCount; i++) {
  23984. images[f].mipmaps.push(texDatas.mipmaps[f * texDatas.mipmapCount + i]);
  23985. images[f].format = texDatas.format;
  23986. images[f].width = texDatas.width;
  23987. images[f].height = texDatas.height;
  23988. }
  23989. }
  23990. texture.image = images;
  23991. } else {
  23992. texture.image.width = texDatas.width;
  23993. texture.image.height = texDatas.height;
  23994. texture.mipmaps = texDatas.mipmaps;
  23995. }
  23996. if (texDatas.mipmapCount === 1) {
  23997. texture.minFilter = LinearFilter;
  23998. }
  23999. texture.format = texDatas.format;
  24000. texture.needsUpdate = true;
  24001. if (onLoad) onLoad(texture);
  24002. }, onProgress, onError);
  24003. }
  24004. return texture;
  24005. }
  24006. }
  24007. class ImageLoader extends Loader {
  24008. constructor(manager) {
  24009. super(manager);
  24010. }
  24011. load(url, onLoad, onProgress, onError) {
  24012. if (this.path !== undefined) url = this.path + url;
  24013. url = this.manager.resolveURL(url);
  24014. const scope = this;
  24015. const cached = Cache.get(url);
  24016. if (cached !== undefined) {
  24017. scope.manager.itemStart(url);
  24018. setTimeout(function () {
  24019. if (onLoad) onLoad(cached);
  24020. scope.manager.itemEnd(url);
  24021. }, 0);
  24022. return cached;
  24023. }
  24024. const image = createElementNS('img');
  24025. function onImageLoad() {
  24026. removeEventListeners();
  24027. Cache.add(url, this);
  24028. if (onLoad) onLoad(this);
  24029. scope.manager.itemEnd(url);
  24030. }
  24031. function onImageError(event) {
  24032. removeEventListeners();
  24033. if (onError) onError(event);
  24034. scope.manager.itemError(url);
  24035. scope.manager.itemEnd(url);
  24036. }
  24037. function removeEventListeners() {
  24038. image.removeEventListener('load', onImageLoad, false);
  24039. image.removeEventListener('error', onImageError, false);
  24040. }
  24041. image.addEventListener('load', onImageLoad, false);
  24042. image.addEventListener('error', onImageError, false);
  24043. if (url.slice(0, 5) !== 'data:') {
  24044. if (this.crossOrigin !== undefined) image.crossOrigin = this.crossOrigin;
  24045. }
  24046. scope.manager.itemStart(url);
  24047. image.src = url;
  24048. return image;
  24049. }
  24050. }
  24051. class CubeTextureLoader extends Loader {
  24052. constructor(manager) {
  24053. super(manager);
  24054. }
  24055. load(urls, onLoad, onProgress, onError) {
  24056. const texture = new CubeTexture();
  24057. const loader = new ImageLoader(this.manager);
  24058. loader.setCrossOrigin(this.crossOrigin);
  24059. loader.setPath(this.path);
  24060. let loaded = 0;
  24061. function loadTexture(i) {
  24062. loader.load(urls[i], function (image) {
  24063. texture.images[i] = image;
  24064. loaded++;
  24065. if (loaded === 6) {
  24066. texture.needsUpdate = true;
  24067. if (onLoad) onLoad(texture);
  24068. }
  24069. }, undefined, onError);
  24070. }
  24071. for (let i = 0; i < urls.length; ++i) {
  24072. loadTexture(i);
  24073. }
  24074. return texture;
  24075. }
  24076. }
  24077. /**
  24078. * Abstract Base class to load generic binary textures formats (rgbe, hdr, ...)
  24079. *
  24080. * Sub classes have to implement the parse() method which will be used in load().
  24081. */
  24082. class DataTextureLoader extends Loader {
  24083. constructor(manager) {
  24084. super(manager);
  24085. }
  24086. load(url, onLoad, onProgress, onError) {
  24087. const scope = this;
  24088. const texture = new DataTexture();
  24089. const loader = new FileLoader(this.manager);
  24090. loader.setResponseType('arraybuffer');
  24091. loader.setRequestHeader(this.requestHeader);
  24092. loader.setPath(this.path);
  24093. loader.setWithCredentials(scope.withCredentials);
  24094. loader.load(url, function (buffer) {
  24095. const texData = scope.parse(buffer);
  24096. if (!texData) return;
  24097. if (texData.image !== undefined) {
  24098. texture.image = texData.image;
  24099. } else if (texData.data !== undefined) {
  24100. texture.image.width = texData.width;
  24101. texture.image.height = texData.height;
  24102. texture.image.data = texData.data;
  24103. }
  24104. texture.wrapS = texData.wrapS !== undefined ? texData.wrapS : ClampToEdgeWrapping;
  24105. texture.wrapT = texData.wrapT !== undefined ? texData.wrapT : ClampToEdgeWrapping;
  24106. texture.magFilter = texData.magFilter !== undefined ? texData.magFilter : LinearFilter;
  24107. texture.minFilter = texData.minFilter !== undefined ? texData.minFilter : LinearFilter;
  24108. texture.anisotropy = texData.anisotropy !== undefined ? texData.anisotropy : 1;
  24109. if (texData.encoding !== undefined) {
  24110. texture.encoding = texData.encoding;
  24111. }
  24112. if (texData.flipY !== undefined) {
  24113. texture.flipY = texData.flipY;
  24114. }
  24115. if (texData.format !== undefined) {
  24116. texture.format = texData.format;
  24117. }
  24118. if (texData.type !== undefined) {
  24119. texture.type = texData.type;
  24120. }
  24121. if (texData.mipmaps !== undefined) {
  24122. texture.mipmaps = texData.mipmaps;
  24123. texture.minFilter = LinearMipmapLinearFilter; // presumably...
  24124. }
  24125. if (texData.mipmapCount === 1) {
  24126. texture.minFilter = LinearFilter;
  24127. }
  24128. if (texData.generateMipmaps !== undefined) {
  24129. texture.generateMipmaps = texData.generateMipmaps;
  24130. }
  24131. texture.needsUpdate = true;
  24132. if (onLoad) onLoad(texture, texData);
  24133. }, onProgress, onError);
  24134. return texture;
  24135. }
  24136. }
  24137. class TextureLoader extends Loader {
  24138. constructor(manager) {
  24139. super(manager);
  24140. }
  24141. load(url, onLoad, onProgress, onError) {
  24142. const texture = new Texture();
  24143. const loader = new ImageLoader(this.manager);
  24144. loader.setCrossOrigin(this.crossOrigin);
  24145. loader.setPath(this.path);
  24146. loader.load(url, function (image) {
  24147. texture.image = image;
  24148. texture.needsUpdate = true;
  24149. if (onLoad !== undefined) {
  24150. onLoad(texture);
  24151. }
  24152. }, onProgress, onError);
  24153. return texture;
  24154. }
  24155. }
  24156. class Light extends Object3D {
  24157. constructor(color, intensity = 1) {
  24158. super();
  24159. this.isLight = true;
  24160. this.type = 'Light';
  24161. this.color = new Color(color);
  24162. this.intensity = intensity;
  24163. }
  24164. dispose() {// Empty here in base class; some subclasses override.
  24165. }
  24166. copy(source, recursive) {
  24167. super.copy(source, recursive);
  24168. this.color.copy(source.color);
  24169. this.intensity = source.intensity;
  24170. return this;
  24171. }
  24172. toJSON(meta) {
  24173. const data = super.toJSON(meta);
  24174. data.object.color = this.color.getHex();
  24175. data.object.intensity = this.intensity;
  24176. if (this.groundColor !== undefined) data.object.groundColor = this.groundColor.getHex();
  24177. if (this.distance !== undefined) data.object.distance = this.distance;
  24178. if (this.angle !== undefined) data.object.angle = this.angle;
  24179. if (this.decay !== undefined) data.object.decay = this.decay;
  24180. if (this.penumbra !== undefined) data.object.penumbra = this.penumbra;
  24181. if (this.shadow !== undefined) data.object.shadow = this.shadow.toJSON();
  24182. return data;
  24183. }
  24184. }
  24185. class HemisphereLight extends Light {
  24186. constructor(skyColor, groundColor, intensity) {
  24187. super(skyColor, intensity);
  24188. this.isHemisphereLight = true;
  24189. this.type = 'HemisphereLight';
  24190. this.position.copy(Object3D.DefaultUp);
  24191. this.updateMatrix();
  24192. this.groundColor = new Color(groundColor);
  24193. }
  24194. copy(source, recursive) {
  24195. super.copy(source, recursive);
  24196. this.groundColor.copy(source.groundColor);
  24197. return this;
  24198. }
  24199. }
  24200. const _projScreenMatrix$1 = /*@__PURE__*/new Matrix4();
  24201. const _lightPositionWorld$1 = /*@__PURE__*/new Vector3();
  24202. const _lookTarget$1 = /*@__PURE__*/new Vector3();
  24203. class LightShadow {
  24204. constructor(camera) {
  24205. this.camera = camera;
  24206. this.bias = 0;
  24207. this.normalBias = 0;
  24208. this.radius = 1;
  24209. this.blurSamples = 8;
  24210. this.mapSize = new Vector2(512, 512);
  24211. this.map = null;
  24212. this.mapPass = null;
  24213. this.matrix = new Matrix4();
  24214. this.autoUpdate = true;
  24215. this.needsUpdate = false;
  24216. this._frustum = new Frustum();
  24217. this._frameExtents = new Vector2(1, 1);
  24218. this._viewportCount = 1;
  24219. this._viewports = [new Vector4(0, 0, 1, 1)];
  24220. }
  24221. getViewportCount() {
  24222. return this._viewportCount;
  24223. }
  24224. getFrustum() {
  24225. return this._frustum;
  24226. }
  24227. updateMatrices(light) {
  24228. const shadowCamera = this.camera;
  24229. const shadowMatrix = this.matrix;
  24230. _lightPositionWorld$1.setFromMatrixPosition(light.matrixWorld);
  24231. shadowCamera.position.copy(_lightPositionWorld$1);
  24232. _lookTarget$1.setFromMatrixPosition(light.target.matrixWorld);
  24233. shadowCamera.lookAt(_lookTarget$1);
  24234. shadowCamera.updateMatrixWorld();
  24235. _projScreenMatrix$1.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse);
  24236. this._frustum.setFromProjectionMatrix(_projScreenMatrix$1);
  24237. shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0);
  24238. shadowMatrix.multiply(shadowCamera.projectionMatrix);
  24239. shadowMatrix.multiply(shadowCamera.matrixWorldInverse);
  24240. }
  24241. getViewport(viewportIndex) {
  24242. return this._viewports[viewportIndex];
  24243. }
  24244. getFrameExtents() {
  24245. return this._frameExtents;
  24246. }
  24247. dispose() {
  24248. if (this.map) {
  24249. this.map.dispose();
  24250. }
  24251. if (this.mapPass) {
  24252. this.mapPass.dispose();
  24253. }
  24254. }
  24255. copy(source) {
  24256. this.camera = source.camera.clone();
  24257. this.bias = source.bias;
  24258. this.radius = source.radius;
  24259. this.mapSize.copy(source.mapSize);
  24260. return this;
  24261. }
  24262. clone() {
  24263. return new this.constructor().copy(this);
  24264. }
  24265. toJSON() {
  24266. const object = {};
  24267. if (this.bias !== 0) object.bias = this.bias;
  24268. if (this.normalBias !== 0) object.normalBias = this.normalBias;
  24269. if (this.radius !== 1) object.radius = this.radius;
  24270. if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray();
  24271. object.camera = this.camera.toJSON(false).object;
  24272. delete object.camera.matrix;
  24273. return object;
  24274. }
  24275. }
  24276. class SpotLightShadow extends LightShadow {
  24277. constructor() {
  24278. super(new PerspectiveCamera(50, 1, 0.5, 500));
  24279. this.isSpotLightShadow = true;
  24280. this.focus = 1;
  24281. }
  24282. updateMatrices(light) {
  24283. const camera = this.camera;
  24284. const fov = RAD2DEG * 2 * light.angle * this.focus;
  24285. const aspect = this.mapSize.width / this.mapSize.height;
  24286. const far = light.distance || camera.far;
  24287. if (fov !== camera.fov || aspect !== camera.aspect || far !== camera.far) {
  24288. camera.fov = fov;
  24289. camera.aspect = aspect;
  24290. camera.far = far;
  24291. camera.updateProjectionMatrix();
  24292. }
  24293. super.updateMatrices(light);
  24294. }
  24295. copy(source) {
  24296. super.copy(source);
  24297. this.focus = source.focus;
  24298. return this;
  24299. }
  24300. }
  24301. class SpotLight extends Light {
  24302. constructor(color, intensity, distance = 0, angle = Math.PI / 3, penumbra = 0, decay = 1) {
  24303. super(color, intensity);
  24304. this.isSpotLight = true;
  24305. this.type = 'SpotLight';
  24306. this.position.copy(Object3D.DefaultUp);
  24307. this.updateMatrix();
  24308. this.target = new Object3D();
  24309. this.distance = distance;
  24310. this.angle = angle;
  24311. this.penumbra = penumbra;
  24312. this.decay = decay; // for physically correct lights, should be 2.
  24313. this.shadow = new SpotLightShadow();
  24314. }
  24315. get power() {
  24316. // compute the light's luminous power (in lumens) from its intensity (in candela)
  24317. // by convention for a spotlight, luminous power (lm) = π * luminous intensity (cd)
  24318. return this.intensity * Math.PI;
  24319. }
  24320. set power(power) {
  24321. // set the light's intensity (in candela) from the desired luminous power (in lumens)
  24322. this.intensity = power / Math.PI;
  24323. }
  24324. dispose() {
  24325. this.shadow.dispose();
  24326. }
  24327. copy(source, recursive) {
  24328. super.copy(source, recursive);
  24329. this.distance = source.distance;
  24330. this.angle = source.angle;
  24331. this.penumbra = source.penumbra;
  24332. this.decay = source.decay;
  24333. this.target = source.target.clone();
  24334. this.shadow = source.shadow.clone();
  24335. return this;
  24336. }
  24337. }
  24338. const _projScreenMatrix = /*@__PURE__*/new Matrix4();
  24339. const _lightPositionWorld = /*@__PURE__*/new Vector3();
  24340. const _lookTarget = /*@__PURE__*/new Vector3();
  24341. class PointLightShadow extends LightShadow {
  24342. constructor() {
  24343. super(new PerspectiveCamera(90, 1, 0.5, 500));
  24344. this.isPointLightShadow = true;
  24345. this._frameExtents = new Vector2(4, 2);
  24346. this._viewportCount = 6;
  24347. this._viewports = [// These viewports map a cube-map onto a 2D texture with the
  24348. // following orientation:
  24349. //
  24350. // xzXZ
  24351. // y Y
  24352. //
  24353. // X - Positive x direction
  24354. // x - Negative x direction
  24355. // Y - Positive y direction
  24356. // y - Negative y direction
  24357. // Z - Positive z direction
  24358. // z - Negative z direction
  24359. // positive X
  24360. new Vector4(2, 1, 1, 1), // negative X
  24361. new Vector4(0, 1, 1, 1), // positive Z
  24362. new Vector4(3, 1, 1, 1), // negative Z
  24363. new Vector4(1, 1, 1, 1), // positive Y
  24364. new Vector4(3, 0, 1, 1), // negative Y
  24365. new Vector4(1, 0, 1, 1)];
  24366. this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)];
  24367. this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)];
  24368. }
  24369. updateMatrices(light, viewportIndex = 0) {
  24370. const camera = this.camera;
  24371. const shadowMatrix = this.matrix;
  24372. const far = light.distance || camera.far;
  24373. if (far !== camera.far) {
  24374. camera.far = far;
  24375. camera.updateProjectionMatrix();
  24376. }
  24377. _lightPositionWorld.setFromMatrixPosition(light.matrixWorld);
  24378. camera.position.copy(_lightPositionWorld);
  24379. _lookTarget.copy(camera.position);
  24380. _lookTarget.add(this._cubeDirections[viewportIndex]);
  24381. camera.up.copy(this._cubeUps[viewportIndex]);
  24382. camera.lookAt(_lookTarget);
  24383. camera.updateMatrixWorld();
  24384. shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z);
  24385. _projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
  24386. this._frustum.setFromProjectionMatrix(_projScreenMatrix);
  24387. }
  24388. }
  24389. class PointLight extends Light {
  24390. constructor(color, intensity, distance = 0, decay = 1) {
  24391. super(color, intensity);
  24392. this.isPointLight = true;
  24393. this.type = 'PointLight';
  24394. this.distance = distance;
  24395. this.decay = decay; // for physically correct lights, should be 2.
  24396. this.shadow = new PointLightShadow();
  24397. }
  24398. get power() {
  24399. // compute the light's luminous power (in lumens) from its intensity (in candela)
  24400. // for an isotropic light source, luminous power (lm) = 4 π luminous intensity (cd)
  24401. return this.intensity * 4 * Math.PI;
  24402. }
  24403. set power(power) {
  24404. // set the light's intensity (in candela) from the desired luminous power (in lumens)
  24405. this.intensity = power / (4 * Math.PI);
  24406. }
  24407. dispose() {
  24408. this.shadow.dispose();
  24409. }
  24410. copy(source, recursive) {
  24411. super.copy(source, recursive);
  24412. this.distance = source.distance;
  24413. this.decay = source.decay;
  24414. this.shadow = source.shadow.clone();
  24415. return this;
  24416. }
  24417. }
  24418. class DirectionalLightShadow extends LightShadow {
  24419. constructor() {
  24420. super(new OrthographicCamera(-5, 5, 5, -5, 0.5, 500));
  24421. this.isDirectionalLightShadow = true;
  24422. }
  24423. }
  24424. class DirectionalLight extends Light {
  24425. constructor(color, intensity) {
  24426. super(color, intensity);
  24427. this.isDirectionalLight = true;
  24428. this.type = 'DirectionalLight';
  24429. this.position.copy(Object3D.DefaultUp);
  24430. this.updateMatrix();
  24431. this.target = new Object3D();
  24432. this.shadow = new DirectionalLightShadow();
  24433. }
  24434. dispose() {
  24435. this.shadow.dispose();
  24436. }
  24437. copy(source) {
  24438. super.copy(source);
  24439. this.target = source.target.clone();
  24440. this.shadow = source.shadow.clone();
  24441. return this;
  24442. }
  24443. }
  24444. class AmbientLight extends Light {
  24445. constructor(color, intensity) {
  24446. super(color, intensity);
  24447. this.isAmbientLight = true;
  24448. this.type = 'AmbientLight';
  24449. }
  24450. }
  24451. class RectAreaLight extends Light {
  24452. constructor(color, intensity, width = 10, height = 10) {
  24453. super(color, intensity);
  24454. this.isRectAreaLight = true;
  24455. this.type = 'RectAreaLight';
  24456. this.width = width;
  24457. this.height = height;
  24458. }
  24459. get power() {
  24460. // compute the light's luminous power (in lumens) from its intensity (in nits)
  24461. return this.intensity * this.width * this.height * Math.PI;
  24462. }
  24463. set power(power) {
  24464. // set the light's intensity (in nits) from the desired luminous power (in lumens)
  24465. this.intensity = power / (this.width * this.height * Math.PI);
  24466. }
  24467. copy(source) {
  24468. super.copy(source);
  24469. this.width = source.width;
  24470. this.height = source.height;
  24471. return this;
  24472. }
  24473. toJSON(meta) {
  24474. const data = super.toJSON(meta);
  24475. data.object.width = this.width;
  24476. data.object.height = this.height;
  24477. return data;
  24478. }
  24479. }
  24480. /**
  24481. * Primary reference:
  24482. * https://graphics.stanford.edu/papers/envmap/envmap.pdf
  24483. *
  24484. * Secondary reference:
  24485. * https://www.ppsloan.org/publications/StupidSH36.pdf
  24486. */
  24487. // 3-band SH defined by 9 coefficients
  24488. class SphericalHarmonics3 {
  24489. constructor() {
  24490. this.isSphericalHarmonics3 = true;
  24491. this.coefficients = [];
  24492. for (let i = 0; i < 9; i++) {
  24493. this.coefficients.push(new Vector3());
  24494. }
  24495. }
  24496. set(coefficients) {
  24497. for (let i = 0; i < 9; i++) {
  24498. this.coefficients[i].copy(coefficients[i]);
  24499. }
  24500. return this;
  24501. }
  24502. zero() {
  24503. for (let i = 0; i < 9; i++) {
  24504. this.coefficients[i].set(0, 0, 0);
  24505. }
  24506. return this;
  24507. } // get the radiance in the direction of the normal
  24508. // target is a Vector3
  24509. getAt(normal, target) {
  24510. // normal is assumed to be unit length
  24511. const x = normal.x,
  24512. y = normal.y,
  24513. z = normal.z;
  24514. const coeff = this.coefficients; // band 0
  24515. target.copy(coeff[0]).multiplyScalar(0.282095); // band 1
  24516. target.addScaledVector(coeff[1], 0.488603 * y);
  24517. target.addScaledVector(coeff[2], 0.488603 * z);
  24518. target.addScaledVector(coeff[3], 0.488603 * x); // band 2
  24519. target.addScaledVector(coeff[4], 1.092548 * (x * y));
  24520. target.addScaledVector(coeff[5], 1.092548 * (y * z));
  24521. target.addScaledVector(coeff[6], 0.315392 * (3.0 * z * z - 1.0));
  24522. target.addScaledVector(coeff[7], 1.092548 * (x * z));
  24523. target.addScaledVector(coeff[8], 0.546274 * (x * x - y * y));
  24524. return target;
  24525. } // get the irradiance (radiance convolved with cosine lobe) in the direction of the normal
  24526. // target is a Vector3
  24527. // https://graphics.stanford.edu/papers/envmap/envmap.pdf
  24528. getIrradianceAt(normal, target) {
  24529. // normal is assumed to be unit length
  24530. const x = normal.x,
  24531. y = normal.y,
  24532. z = normal.z;
  24533. const coeff = this.coefficients; // band 0
  24534. target.copy(coeff[0]).multiplyScalar(0.886227); // π * 0.282095
  24535. // band 1
  24536. target.addScaledVector(coeff[1], 2.0 * 0.511664 * y); // ( 2 * π / 3 ) * 0.488603
  24537. target.addScaledVector(coeff[2], 2.0 * 0.511664 * z);
  24538. target.addScaledVector(coeff[3], 2.0 * 0.511664 * x); // band 2
  24539. target.addScaledVector(coeff[4], 2.0 * 0.429043 * x * y); // ( π / 4 ) * 1.092548
  24540. target.addScaledVector(coeff[5], 2.0 * 0.429043 * y * z);
  24541. target.addScaledVector(coeff[6], 0.743125 * z * z - 0.247708); // ( π / 4 ) * 0.315392 * 3
  24542. target.addScaledVector(coeff[7], 2.0 * 0.429043 * x * z);
  24543. target.addScaledVector(coeff[8], 0.429043 * (x * x - y * y)); // ( π / 4 ) * 0.546274
  24544. return target;
  24545. }
  24546. add(sh) {
  24547. for (let i = 0; i < 9; i++) {
  24548. this.coefficients[i].add(sh.coefficients[i]);
  24549. }
  24550. return this;
  24551. }
  24552. addScaledSH(sh, s) {
  24553. for (let i = 0; i < 9; i++) {
  24554. this.coefficients[i].addScaledVector(sh.coefficients[i], s);
  24555. }
  24556. return this;
  24557. }
  24558. scale(s) {
  24559. for (let i = 0; i < 9; i++) {
  24560. this.coefficients[i].multiplyScalar(s);
  24561. }
  24562. return this;
  24563. }
  24564. lerp(sh, alpha) {
  24565. for (let i = 0; i < 9; i++) {
  24566. this.coefficients[i].lerp(sh.coefficients[i], alpha);
  24567. }
  24568. return this;
  24569. }
  24570. equals(sh) {
  24571. for (let i = 0; i < 9; i++) {
  24572. if (!this.coefficients[i].equals(sh.coefficients[i])) {
  24573. return false;
  24574. }
  24575. }
  24576. return true;
  24577. }
  24578. copy(sh) {
  24579. return this.set(sh.coefficients);
  24580. }
  24581. clone() {
  24582. return new this.constructor().copy(this);
  24583. }
  24584. fromArray(array, offset = 0) {
  24585. const coefficients = this.coefficients;
  24586. for (let i = 0; i < 9; i++) {
  24587. coefficients[i].fromArray(array, offset + i * 3);
  24588. }
  24589. return this;
  24590. }
  24591. toArray(array = [], offset = 0) {
  24592. const coefficients = this.coefficients;
  24593. for (let i = 0; i < 9; i++) {
  24594. coefficients[i].toArray(array, offset + i * 3);
  24595. }
  24596. return array;
  24597. } // evaluate the basis functions
  24598. // shBasis is an Array[ 9 ]
  24599. static getBasisAt(normal, shBasis) {
  24600. // normal is assumed to be unit length
  24601. const x = normal.x,
  24602. y = normal.y,
  24603. z = normal.z; // band 0
  24604. shBasis[0] = 0.282095; // band 1
  24605. shBasis[1] = 0.488603 * y;
  24606. shBasis[2] = 0.488603 * z;
  24607. shBasis[3] = 0.488603 * x; // band 2
  24608. shBasis[4] = 1.092548 * x * y;
  24609. shBasis[5] = 1.092548 * y * z;
  24610. shBasis[6] = 0.315392 * (3 * z * z - 1);
  24611. shBasis[7] = 1.092548 * x * z;
  24612. shBasis[8] = 0.546274 * (x * x - y * y);
  24613. }
  24614. }
  24615. class LightProbe extends Light {
  24616. constructor(sh = new SphericalHarmonics3(), intensity = 1) {
  24617. super(undefined, intensity);
  24618. this.isLightProbe = true;
  24619. this.sh = sh;
  24620. }
  24621. copy(source) {
  24622. super.copy(source);
  24623. this.sh.copy(source.sh);
  24624. return this;
  24625. }
  24626. fromJSON(json) {
  24627. this.intensity = json.intensity; // TODO: Move this bit to Light.fromJSON();
  24628. this.sh.fromArray(json.sh);
  24629. return this;
  24630. }
  24631. toJSON(meta) {
  24632. const data = super.toJSON(meta);
  24633. data.object.sh = this.sh.toArray();
  24634. return data;
  24635. }
  24636. }
  24637. class MaterialLoader extends Loader {
  24638. constructor(manager) {
  24639. super(manager);
  24640. this.textures = {};
  24641. }
  24642. load(url, onLoad, onProgress, onError) {
  24643. const scope = this;
  24644. const loader = new FileLoader(scope.manager);
  24645. loader.setPath(scope.path);
  24646. loader.setRequestHeader(scope.requestHeader);
  24647. loader.setWithCredentials(scope.withCredentials);
  24648. loader.load(url, function (text) {
  24649. try {
  24650. onLoad(scope.parse(JSON.parse(text)));
  24651. } catch (e) {
  24652. if (onError) {
  24653. onError(e);
  24654. } else {
  24655. console.error(e);
  24656. }
  24657. scope.manager.itemError(url);
  24658. }
  24659. }, onProgress, onError);
  24660. }
  24661. parse(json) {
  24662. const textures = this.textures;
  24663. function getTexture(name) {
  24664. if (textures[name] === undefined) {
  24665. console.warn('THREE.MaterialLoader: Undefined texture', name);
  24666. }
  24667. return textures[name];
  24668. }
  24669. const material = MaterialLoader.createMaterialFromType(json.type);
  24670. if (json.uuid !== undefined) material.uuid = json.uuid;
  24671. if (json.name !== undefined) material.name = json.name;
  24672. if (json.color !== undefined && material.color !== undefined) material.color.setHex(json.color);
  24673. if (json.roughness !== undefined) material.roughness = json.roughness;
  24674. if (json.metalness !== undefined) material.metalness = json.metalness;
  24675. if (json.sheen !== undefined) material.sheen = json.sheen;
  24676. if (json.sheenColor !== undefined) material.sheenColor = new Color().setHex(json.sheenColor);
  24677. if (json.sheenRoughness !== undefined) material.sheenRoughness = json.sheenRoughness;
  24678. if (json.emissive !== undefined && material.emissive !== undefined) material.emissive.setHex(json.emissive);
  24679. if (json.specular !== undefined && material.specular !== undefined) material.specular.setHex(json.specular);
  24680. if (json.specularIntensity !== undefined) material.specularIntensity = json.specularIntensity;
  24681. if (json.specularColor !== undefined && material.specularColor !== undefined) material.specularColor.setHex(json.specularColor);
  24682. if (json.shininess !== undefined) material.shininess = json.shininess;
  24683. if (json.clearcoat !== undefined) material.clearcoat = json.clearcoat;
  24684. if (json.clearcoatRoughness !== undefined) material.clearcoatRoughness = json.clearcoatRoughness;
  24685. if (json.iridescence !== undefined) material.iridescence = json.iridescence;
  24686. if (json.iridescenceIOR !== undefined) material.iridescenceIOR = json.iridescenceIOR;
  24687. if (json.iridescenceThicknessRange !== undefined) material.iridescenceThicknessRange = json.iridescenceThicknessRange;
  24688. if (json.transmission !== undefined) material.transmission = json.transmission;
  24689. if (json.thickness !== undefined) material.thickness = json.thickness;
  24690. if (json.attenuationDistance !== undefined) material.attenuationDistance = json.attenuationDistance;
  24691. if (json.attenuationColor !== undefined && material.attenuationColor !== undefined) material.attenuationColor.setHex(json.attenuationColor);
  24692. if (json.fog !== undefined) material.fog = json.fog;
  24693. if (json.flatShading !== undefined) material.flatShading = json.flatShading;
  24694. if (json.blending !== undefined) material.blending = json.blending;
  24695. if (json.combine !== undefined) material.combine = json.combine;
  24696. if (json.side !== undefined) material.side = json.side;
  24697. if (json.shadowSide !== undefined) material.shadowSide = json.shadowSide;
  24698. if (json.opacity !== undefined) material.opacity = json.opacity;
  24699. if (json.transparent !== undefined) material.transparent = json.transparent;
  24700. if (json.alphaTest !== undefined) material.alphaTest = json.alphaTest;
  24701. if (json.depthTest !== undefined) material.depthTest = json.depthTest;
  24702. if (json.depthWrite !== undefined) material.depthWrite = json.depthWrite;
  24703. if (json.colorWrite !== undefined) material.colorWrite = json.colorWrite;
  24704. if (json.stencilWrite !== undefined) material.stencilWrite = json.stencilWrite;
  24705. if (json.stencilWriteMask !== undefined) material.stencilWriteMask = json.stencilWriteMask;
  24706. if (json.stencilFunc !== undefined) material.stencilFunc = json.stencilFunc;
  24707. if (json.stencilRef !== undefined) material.stencilRef = json.stencilRef;
  24708. if (json.stencilFuncMask !== undefined) material.stencilFuncMask = json.stencilFuncMask;
  24709. if (json.stencilFail !== undefined) material.stencilFail = json.stencilFail;
  24710. if (json.stencilZFail !== undefined) material.stencilZFail = json.stencilZFail;
  24711. if (json.stencilZPass !== undefined) material.stencilZPass = json.stencilZPass;
  24712. if (json.wireframe !== undefined) material.wireframe = json.wireframe;
  24713. if (json.wireframeLinewidth !== undefined) material.wireframeLinewidth = json.wireframeLinewidth;
  24714. if (json.wireframeLinecap !== undefined) material.wireframeLinecap = json.wireframeLinecap;
  24715. if (json.wireframeLinejoin !== undefined) material.wireframeLinejoin = json.wireframeLinejoin;
  24716. if (json.rotation !== undefined) material.rotation = json.rotation;
  24717. if (json.linewidth !== 1) material.linewidth = json.linewidth;
  24718. if (json.dashSize !== undefined) material.dashSize = json.dashSize;
  24719. if (json.gapSize !== undefined) material.gapSize = json.gapSize;
  24720. if (json.scale !== undefined) material.scale = json.scale;
  24721. if (json.polygonOffset !== undefined) material.polygonOffset = json.polygonOffset;
  24722. if (json.polygonOffsetFactor !== undefined) material.polygonOffsetFactor = json.polygonOffsetFactor;
  24723. if (json.polygonOffsetUnits !== undefined) material.polygonOffsetUnits = json.polygonOffsetUnits;
  24724. if (json.dithering !== undefined) material.dithering = json.dithering;
  24725. if (json.alphaToCoverage !== undefined) material.alphaToCoverage = json.alphaToCoverage;
  24726. if (json.premultipliedAlpha !== undefined) material.premultipliedAlpha = json.premultipliedAlpha;
  24727. if (json.visible !== undefined) material.visible = json.visible;
  24728. if (json.toneMapped !== undefined) material.toneMapped = json.toneMapped;
  24729. if (json.userData !== undefined) material.userData = json.userData;
  24730. if (json.vertexColors !== undefined) {
  24731. if (typeof json.vertexColors === 'number') {
  24732. material.vertexColors = json.vertexColors > 0 ? true : false;
  24733. } else {
  24734. material.vertexColors = json.vertexColors;
  24735. }
  24736. } // Shader Material
  24737. if (json.uniforms !== undefined) {
  24738. for (const name in json.uniforms) {
  24739. const uniform = json.uniforms[name];
  24740. material.uniforms[name] = {};
  24741. switch (uniform.type) {
  24742. case 't':
  24743. material.uniforms[name].value = getTexture(uniform.value);
  24744. break;
  24745. case 'c':
  24746. material.uniforms[name].value = new Color().setHex(uniform.value);
  24747. break;
  24748. case 'v2':
  24749. material.uniforms[name].value = new Vector2().fromArray(uniform.value);
  24750. break;
  24751. case 'v3':
  24752. material.uniforms[name].value = new Vector3().fromArray(uniform.value);
  24753. break;
  24754. case 'v4':
  24755. material.uniforms[name].value = new Vector4().fromArray(uniform.value);
  24756. break;
  24757. case 'm3':
  24758. material.uniforms[name].value = new Matrix3().fromArray(uniform.value);
  24759. break;
  24760. case 'm4':
  24761. material.uniforms[name].value = new Matrix4().fromArray(uniform.value);
  24762. break;
  24763. default:
  24764. material.uniforms[name].value = uniform.value;
  24765. }
  24766. }
  24767. }
  24768. if (json.defines !== undefined) material.defines = json.defines;
  24769. if (json.vertexShader !== undefined) material.vertexShader = json.vertexShader;
  24770. if (json.fragmentShader !== undefined) material.fragmentShader = json.fragmentShader;
  24771. if (json.extensions !== undefined) {
  24772. for (const key in json.extensions) {
  24773. material.extensions[key] = json.extensions[key];
  24774. }
  24775. } // Deprecated
  24776. if (json.shading !== undefined) material.flatShading = json.shading === 1; // THREE.FlatShading
  24777. // for PointsMaterial
  24778. if (json.size !== undefined) material.size = json.size;
  24779. if (json.sizeAttenuation !== undefined) material.sizeAttenuation = json.sizeAttenuation; // maps
  24780. if (json.map !== undefined) material.map = getTexture(json.map);
  24781. if (json.matcap !== undefined) material.matcap = getTexture(json.matcap);
  24782. if (json.alphaMap !== undefined) material.alphaMap = getTexture(json.alphaMap);
  24783. if (json.bumpMap !== undefined) material.bumpMap = getTexture(json.bumpMap);
  24784. if (json.bumpScale !== undefined) material.bumpScale = json.bumpScale;
  24785. if (json.normalMap !== undefined) material.normalMap = getTexture(json.normalMap);
  24786. if (json.normalMapType !== undefined) material.normalMapType = json.normalMapType;
  24787. if (json.normalScale !== undefined) {
  24788. let normalScale = json.normalScale;
  24789. if (Array.isArray(normalScale) === false) {
  24790. // Blender exporter used to export a scalar. See #7459
  24791. normalScale = [normalScale, normalScale];
  24792. }
  24793. material.normalScale = new Vector2().fromArray(normalScale);
  24794. }
  24795. if (json.displacementMap !== undefined) material.displacementMap = getTexture(json.displacementMap);
  24796. if (json.displacementScale !== undefined) material.displacementScale = json.displacementScale;
  24797. if (json.displacementBias !== undefined) material.displacementBias = json.displacementBias;
  24798. if (json.roughnessMap !== undefined) material.roughnessMap = getTexture(json.roughnessMap);
  24799. if (json.metalnessMap !== undefined) material.metalnessMap = getTexture(json.metalnessMap);
  24800. if (json.emissiveMap !== undefined) material.emissiveMap = getTexture(json.emissiveMap);
  24801. if (json.emissiveIntensity !== undefined) material.emissiveIntensity = json.emissiveIntensity;
  24802. if (json.specularMap !== undefined) material.specularMap = getTexture(json.specularMap);
  24803. if (json.specularIntensityMap !== undefined) material.specularIntensityMap = getTexture(json.specularIntensityMap);
  24804. if (json.specularColorMap !== undefined) material.specularColorMap = getTexture(json.specularColorMap);
  24805. if (json.envMap !== undefined) material.envMap = getTexture(json.envMap);
  24806. if (json.envMapIntensity !== undefined) material.envMapIntensity = json.envMapIntensity;
  24807. if (json.reflectivity !== undefined) material.reflectivity = json.reflectivity;
  24808. if (json.refractionRatio !== undefined) material.refractionRatio = json.refractionRatio;
  24809. if (json.lightMap !== undefined) material.lightMap = getTexture(json.lightMap);
  24810. if (json.lightMapIntensity !== undefined) material.lightMapIntensity = json.lightMapIntensity;
  24811. if (json.aoMap !== undefined) material.aoMap = getTexture(json.aoMap);
  24812. if (json.aoMapIntensity !== undefined) material.aoMapIntensity = json.aoMapIntensity;
  24813. if (json.gradientMap !== undefined) material.gradientMap = getTexture(json.gradientMap);
  24814. if (json.clearcoatMap !== undefined) material.clearcoatMap = getTexture(json.clearcoatMap);
  24815. if (json.clearcoatRoughnessMap !== undefined) material.clearcoatRoughnessMap = getTexture(json.clearcoatRoughnessMap);
  24816. if (json.clearcoatNormalMap !== undefined) material.clearcoatNormalMap = getTexture(json.clearcoatNormalMap);
  24817. if (json.clearcoatNormalScale !== undefined) material.clearcoatNormalScale = new Vector2().fromArray(json.clearcoatNormalScale);
  24818. if (json.iridescenceMap !== undefined) material.iridescenceMap = getTexture(json.iridescenceMap);
  24819. if (json.iridescenceThicknessMap !== undefined) material.iridescenceThicknessMap = getTexture(json.iridescenceThicknessMap);
  24820. if (json.transmissionMap !== undefined) material.transmissionMap = getTexture(json.transmissionMap);
  24821. if (json.thicknessMap !== undefined) material.thicknessMap = getTexture(json.thicknessMap);
  24822. if (json.sheenColorMap !== undefined) material.sheenColorMap = getTexture(json.sheenColorMap);
  24823. if (json.sheenRoughnessMap !== undefined) material.sheenRoughnessMap = getTexture(json.sheenRoughnessMap);
  24824. return material;
  24825. }
  24826. setTextures(value) {
  24827. this.textures = value;
  24828. return this;
  24829. }
  24830. static createMaterialFromType(type) {
  24831. const materialLib = {
  24832. ShadowMaterial,
  24833. SpriteMaterial,
  24834. RawShaderMaterial,
  24835. ShaderMaterial,
  24836. PointsMaterial,
  24837. MeshPhysicalMaterial,
  24838. MeshStandardMaterial,
  24839. MeshPhongMaterial,
  24840. MeshToonMaterial,
  24841. MeshNormalMaterial,
  24842. MeshLambertMaterial,
  24843. MeshDepthMaterial,
  24844. MeshDistanceMaterial,
  24845. MeshBasicMaterial,
  24846. MeshMatcapMaterial,
  24847. LineDashedMaterial,
  24848. LineBasicMaterial,
  24849. Material
  24850. };
  24851. return new materialLib[type]();
  24852. }
  24853. }
  24854. class LoaderUtils {
  24855. static decodeText(array) {
  24856. if (typeof TextDecoder !== 'undefined') {
  24857. return new TextDecoder().decode(array);
  24858. } // Avoid the String.fromCharCode.apply(null, array) shortcut, which
  24859. // throws a "maximum call stack size exceeded" error for large arrays.
  24860. let s = '';
  24861. for (let i = 0, il = array.length; i < il; i++) {
  24862. // Implicitly assumes little-endian.
  24863. s += String.fromCharCode(array[i]);
  24864. }
  24865. try {
  24866. // merges multi-byte utf-8 characters.
  24867. return decodeURIComponent(escape(s));
  24868. } catch (e) {
  24869. // see #16358
  24870. return s;
  24871. }
  24872. }
  24873. static extractUrlBase(url) {
  24874. const index = url.lastIndexOf('/');
  24875. if (index === -1) return './';
  24876. return url.slice(0, index + 1);
  24877. }
  24878. static resolveURL(url, path) {
  24879. // Invalid URL
  24880. if (typeof url !== 'string' || url === '') return ''; // Host Relative URL
  24881. if (/^https?:\/\//i.test(path) && /^\//.test(url)) {
  24882. path = path.replace(/(^https?:\/\/[^\/]+).*/i, '$1');
  24883. } // Absolute URL http://,https://,//
  24884. if (/^(https?:)?\/\//i.test(url)) return url; // Data URI
  24885. if (/^data:.*,.*$/i.test(url)) return url; // Blob URL
  24886. if (/^blob:.*$/i.test(url)) return url; // Relative URL
  24887. return path + url;
  24888. }
  24889. }
  24890. class InstancedBufferGeometry extends BufferGeometry {
  24891. constructor() {
  24892. super();
  24893. this.isInstancedBufferGeometry = true;
  24894. this.type = 'InstancedBufferGeometry';
  24895. this.instanceCount = Infinity;
  24896. }
  24897. copy(source) {
  24898. super.copy(source);
  24899. this.instanceCount = source.instanceCount;
  24900. return this;
  24901. }
  24902. clone() {
  24903. return new this.constructor().copy(this);
  24904. }
  24905. toJSON() {
  24906. const data = super.toJSON(this);
  24907. data.instanceCount = this.instanceCount;
  24908. data.isInstancedBufferGeometry = true;
  24909. return data;
  24910. }
  24911. }
  24912. class BufferGeometryLoader extends Loader {
  24913. constructor(manager) {
  24914. super(manager);
  24915. }
  24916. load(url, onLoad, onProgress, onError) {
  24917. const scope = this;
  24918. const loader = new FileLoader(scope.manager);
  24919. loader.setPath(scope.path);
  24920. loader.setRequestHeader(scope.requestHeader);
  24921. loader.setWithCredentials(scope.withCredentials);
  24922. loader.load(url, function (text) {
  24923. try {
  24924. onLoad(scope.parse(JSON.parse(text)));
  24925. } catch (e) {
  24926. if (onError) {
  24927. onError(e);
  24928. } else {
  24929. console.error(e);
  24930. }
  24931. scope.manager.itemError(url);
  24932. }
  24933. }, onProgress, onError);
  24934. }
  24935. parse(json) {
  24936. const interleavedBufferMap = {};
  24937. const arrayBufferMap = {};
  24938. function getInterleavedBuffer(json, uuid) {
  24939. if (interleavedBufferMap[uuid] !== undefined) return interleavedBufferMap[uuid];
  24940. const interleavedBuffers = json.interleavedBuffers;
  24941. const interleavedBuffer = interleavedBuffers[uuid];
  24942. const buffer = getArrayBuffer(json, interleavedBuffer.buffer);
  24943. const array = getTypedArray(interleavedBuffer.type, buffer);
  24944. const ib = new InterleavedBuffer(array, interleavedBuffer.stride);
  24945. ib.uuid = interleavedBuffer.uuid;
  24946. interleavedBufferMap[uuid] = ib;
  24947. return ib;
  24948. }
  24949. function getArrayBuffer(json, uuid) {
  24950. if (arrayBufferMap[uuid] !== undefined) return arrayBufferMap[uuid];
  24951. const arrayBuffers = json.arrayBuffers;
  24952. const arrayBuffer = arrayBuffers[uuid];
  24953. const ab = new Uint32Array(arrayBuffer).buffer;
  24954. arrayBufferMap[uuid] = ab;
  24955. return ab;
  24956. }
  24957. const geometry = json.isInstancedBufferGeometry ? new InstancedBufferGeometry() : new BufferGeometry();
  24958. const index = json.data.index;
  24959. if (index !== undefined) {
  24960. const typedArray = getTypedArray(index.type, index.array);
  24961. geometry.setIndex(new BufferAttribute(typedArray, 1));
  24962. }
  24963. const attributes = json.data.attributes;
  24964. for (const key in attributes) {
  24965. const attribute = attributes[key];
  24966. let bufferAttribute;
  24967. if (attribute.isInterleavedBufferAttribute) {
  24968. const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data);
  24969. bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized);
  24970. } else {
  24971. const typedArray = getTypedArray(attribute.type, attribute.array);
  24972. const bufferAttributeConstr = attribute.isInstancedBufferAttribute ? InstancedBufferAttribute : BufferAttribute;
  24973. bufferAttribute = new bufferAttributeConstr(typedArray, attribute.itemSize, attribute.normalized);
  24974. }
  24975. if (attribute.name !== undefined) bufferAttribute.name = attribute.name;
  24976. if (attribute.usage !== undefined) bufferAttribute.setUsage(attribute.usage);
  24977. if (attribute.updateRange !== undefined) {
  24978. bufferAttribute.updateRange.offset = attribute.updateRange.offset;
  24979. bufferAttribute.updateRange.count = attribute.updateRange.count;
  24980. }
  24981. geometry.setAttribute(key, bufferAttribute);
  24982. }
  24983. const morphAttributes = json.data.morphAttributes;
  24984. if (morphAttributes) {
  24985. for (const key in morphAttributes) {
  24986. const attributeArray = morphAttributes[key];
  24987. const array = [];
  24988. for (let i = 0, il = attributeArray.length; i < il; i++) {
  24989. const attribute = attributeArray[i];
  24990. let bufferAttribute;
  24991. if (attribute.isInterleavedBufferAttribute) {
  24992. const interleavedBuffer = getInterleavedBuffer(json.data, attribute.data);
  24993. bufferAttribute = new InterleavedBufferAttribute(interleavedBuffer, attribute.itemSize, attribute.offset, attribute.normalized);
  24994. } else {
  24995. const typedArray = getTypedArray(attribute.type, attribute.array);
  24996. bufferAttribute = new BufferAttribute(typedArray, attribute.itemSize, attribute.normalized);
  24997. }
  24998. if (attribute.name !== undefined) bufferAttribute.name = attribute.name;
  24999. array.push(bufferAttribute);
  25000. }
  25001. geometry.morphAttributes[key] = array;
  25002. }
  25003. }
  25004. const morphTargetsRelative = json.data.morphTargetsRelative;
  25005. if (morphTargetsRelative) {
  25006. geometry.morphTargetsRelative = true;
  25007. }
  25008. const groups = json.data.groups || json.data.drawcalls || json.data.offsets;
  25009. if (groups !== undefined) {
  25010. for (let i = 0, n = groups.length; i !== n; ++i) {
  25011. const group = groups[i];
  25012. geometry.addGroup(group.start, group.count, group.materialIndex);
  25013. }
  25014. }
  25015. const boundingSphere = json.data.boundingSphere;
  25016. if (boundingSphere !== undefined) {
  25017. const center = new Vector3();
  25018. if (boundingSphere.center !== undefined) {
  25019. center.fromArray(boundingSphere.center);
  25020. }
  25021. geometry.boundingSphere = new Sphere(center, boundingSphere.radius);
  25022. }
  25023. if (json.name) geometry.name = json.name;
  25024. if (json.userData) geometry.userData = json.userData;
  25025. return geometry;
  25026. }
  25027. }
  25028. class ObjectLoader extends Loader {
  25029. constructor(manager) {
  25030. super(manager);
  25031. }
  25032. load(url, onLoad, onProgress, onError) {
  25033. const scope = this;
  25034. const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path;
  25035. this.resourcePath = this.resourcePath || path;
  25036. const loader = new FileLoader(this.manager);
  25037. loader.setPath(this.path);
  25038. loader.setRequestHeader(this.requestHeader);
  25039. loader.setWithCredentials(this.withCredentials);
  25040. loader.load(url, function (text) {
  25041. let json = null;
  25042. try {
  25043. json = JSON.parse(text);
  25044. } catch (error) {
  25045. if (onError !== undefined) onError(error);
  25046. console.error('THREE:ObjectLoader: Can\'t parse ' + url + '.', error.message);
  25047. return;
  25048. }
  25049. const metadata = json.metadata;
  25050. if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') {
  25051. console.error('THREE.ObjectLoader: Can\'t load ' + url);
  25052. return;
  25053. }
  25054. scope.parse(json, onLoad);
  25055. }, onProgress, onError);
  25056. }
  25057. async loadAsync(url, onProgress) {
  25058. const scope = this;
  25059. const path = this.path === '' ? LoaderUtils.extractUrlBase(url) : this.path;
  25060. this.resourcePath = this.resourcePath || path;
  25061. const loader = new FileLoader(this.manager);
  25062. loader.setPath(this.path);
  25063. loader.setRequestHeader(this.requestHeader);
  25064. loader.setWithCredentials(this.withCredentials);
  25065. const text = await loader.loadAsync(url, onProgress);
  25066. const json = JSON.parse(text);
  25067. const metadata = json.metadata;
  25068. if (metadata === undefined || metadata.type === undefined || metadata.type.toLowerCase() === 'geometry') {
  25069. throw new Error('THREE.ObjectLoader: Can\'t load ' + url);
  25070. }
  25071. return await scope.parseAsync(json);
  25072. }
  25073. parse(json, onLoad) {
  25074. const animations = this.parseAnimations(json.animations);
  25075. const shapes = this.parseShapes(json.shapes);
  25076. const geometries = this.parseGeometries(json.geometries, shapes);
  25077. const images = this.parseImages(json.images, function () {
  25078. if (onLoad !== undefined) onLoad(object);
  25079. });
  25080. const textures = this.parseTextures(json.textures, images);
  25081. const materials = this.parseMaterials(json.materials, textures);
  25082. const object = this.parseObject(json.object, geometries, materials, textures, animations);
  25083. const skeletons = this.parseSkeletons(json.skeletons, object);
  25084. this.bindSkeletons(object, skeletons); //
  25085. if (onLoad !== undefined) {
  25086. let hasImages = false;
  25087. for (const uuid in images) {
  25088. if (images[uuid].data instanceof HTMLImageElement) {
  25089. hasImages = true;
  25090. break;
  25091. }
  25092. }
  25093. if (hasImages === false) onLoad(object);
  25094. }
  25095. return object;
  25096. }
  25097. async parseAsync(json) {
  25098. const animations = this.parseAnimations(json.animations);
  25099. const shapes = this.parseShapes(json.shapes);
  25100. const geometries = this.parseGeometries(json.geometries, shapes);
  25101. const images = await this.parseImagesAsync(json.images);
  25102. const textures = this.parseTextures(json.textures, images);
  25103. const materials = this.parseMaterials(json.materials, textures);
  25104. const object = this.parseObject(json.object, geometries, materials, textures, animations);
  25105. const skeletons = this.parseSkeletons(json.skeletons, object);
  25106. this.bindSkeletons(object, skeletons);
  25107. return object;
  25108. }
  25109. parseShapes(json) {
  25110. const shapes = {};
  25111. if (json !== undefined) {
  25112. for (let i = 0, l = json.length; i < l; i++) {
  25113. const shape = new Shape().fromJSON(json[i]);
  25114. shapes[shape.uuid] = shape;
  25115. }
  25116. }
  25117. return shapes;
  25118. }
  25119. parseSkeletons(json, object) {
  25120. const skeletons = {};
  25121. const bones = {}; // generate bone lookup table
  25122. object.traverse(function (child) {
  25123. if (child.isBone) bones[child.uuid] = child;
  25124. }); // create skeletons
  25125. if (json !== undefined) {
  25126. for (let i = 0, l = json.length; i < l; i++) {
  25127. const skeleton = new Skeleton().fromJSON(json[i], bones);
  25128. skeletons[skeleton.uuid] = skeleton;
  25129. }
  25130. }
  25131. return skeletons;
  25132. }
  25133. parseGeometries(json, shapes) {
  25134. const geometries = {};
  25135. if (json !== undefined) {
  25136. const bufferGeometryLoader = new BufferGeometryLoader();
  25137. for (let i = 0, l = json.length; i < l; i++) {
  25138. let geometry;
  25139. const data = json[i];
  25140. switch (data.type) {
  25141. case 'BufferGeometry':
  25142. case 'InstancedBufferGeometry':
  25143. geometry = bufferGeometryLoader.parse(data);
  25144. break;
  25145. case 'Geometry':
  25146. console.error('THREE.ObjectLoader: The legacy Geometry type is no longer supported.');
  25147. break;
  25148. default:
  25149. if (data.type in Geometries) {
  25150. geometry = Geometries[data.type].fromJSON(data, shapes);
  25151. } else {
  25152. console.warn(`THREE.ObjectLoader: Unsupported geometry type "${data.type}"`);
  25153. }
  25154. }
  25155. geometry.uuid = data.uuid;
  25156. if (data.name !== undefined) geometry.name = data.name;
  25157. if (geometry.isBufferGeometry === true && data.userData !== undefined) geometry.userData = data.userData;
  25158. geometries[data.uuid] = geometry;
  25159. }
  25160. }
  25161. return geometries;
  25162. }
  25163. parseMaterials(json, textures) {
  25164. const cache = {}; // MultiMaterial
  25165. const materials = {};
  25166. if (json !== undefined) {
  25167. const loader = new MaterialLoader();
  25168. loader.setTextures(textures);
  25169. for (let i = 0, l = json.length; i < l; i++) {
  25170. const data = json[i];
  25171. if (data.type === 'MultiMaterial') {
  25172. // Deprecated
  25173. const array = [];
  25174. for (let j = 0; j < data.materials.length; j++) {
  25175. const material = data.materials[j];
  25176. if (cache[material.uuid] === undefined) {
  25177. cache[material.uuid] = loader.parse(material);
  25178. }
  25179. array.push(cache[material.uuid]);
  25180. }
  25181. materials[data.uuid] = array;
  25182. } else {
  25183. if (cache[data.uuid] === undefined) {
  25184. cache[data.uuid] = loader.parse(data);
  25185. }
  25186. materials[data.uuid] = cache[data.uuid];
  25187. }
  25188. }
  25189. }
  25190. return materials;
  25191. }
  25192. parseAnimations(json) {
  25193. const animations = {};
  25194. if (json !== undefined) {
  25195. for (let i = 0; i < json.length; i++) {
  25196. const data = json[i];
  25197. const clip = AnimationClip.parse(data);
  25198. animations[clip.uuid] = clip;
  25199. }
  25200. }
  25201. return animations;
  25202. }
  25203. parseImages(json, onLoad) {
  25204. const scope = this;
  25205. const images = {};
  25206. let loader;
  25207. function loadImage(url) {
  25208. scope.manager.itemStart(url);
  25209. return loader.load(url, function () {
  25210. scope.manager.itemEnd(url);
  25211. }, undefined, function () {
  25212. scope.manager.itemError(url);
  25213. scope.manager.itemEnd(url);
  25214. });
  25215. }
  25216. function deserializeImage(image) {
  25217. if (typeof image === 'string') {
  25218. const url = image;
  25219. const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url;
  25220. return loadImage(path);
  25221. } else {
  25222. if (image.data) {
  25223. return {
  25224. data: getTypedArray(image.type, image.data),
  25225. width: image.width,
  25226. height: image.height
  25227. };
  25228. } else {
  25229. return null;
  25230. }
  25231. }
  25232. }
  25233. if (json !== undefined && json.length > 0) {
  25234. const manager = new LoadingManager(onLoad);
  25235. loader = new ImageLoader(manager);
  25236. loader.setCrossOrigin(this.crossOrigin);
  25237. for (let i = 0, il = json.length; i < il; i++) {
  25238. const image = json[i];
  25239. const url = image.url;
  25240. if (Array.isArray(url)) {
  25241. // load array of images e.g CubeTexture
  25242. const imageArray = [];
  25243. for (let j = 0, jl = url.length; j < jl; j++) {
  25244. const currentUrl = url[j];
  25245. const deserializedImage = deserializeImage(currentUrl);
  25246. if (deserializedImage !== null) {
  25247. if (deserializedImage instanceof HTMLImageElement) {
  25248. imageArray.push(deserializedImage);
  25249. } else {
  25250. // special case: handle array of data textures for cube textures
  25251. imageArray.push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height));
  25252. }
  25253. }
  25254. }
  25255. images[image.uuid] = new Source(imageArray);
  25256. } else {
  25257. // load single image
  25258. const deserializedImage = deserializeImage(image.url);
  25259. images[image.uuid] = new Source(deserializedImage);
  25260. }
  25261. }
  25262. }
  25263. return images;
  25264. }
  25265. async parseImagesAsync(json) {
  25266. const scope = this;
  25267. const images = {};
  25268. let loader;
  25269. async function deserializeImage(image) {
  25270. if (typeof image === 'string') {
  25271. const url = image;
  25272. const path = /^(\/\/)|([a-z]+:(\/\/)?)/i.test(url) ? url : scope.resourcePath + url;
  25273. return await loader.loadAsync(path);
  25274. } else {
  25275. if (image.data) {
  25276. return {
  25277. data: getTypedArray(image.type, image.data),
  25278. width: image.width,
  25279. height: image.height
  25280. };
  25281. } else {
  25282. return null;
  25283. }
  25284. }
  25285. }
  25286. if (json !== undefined && json.length > 0) {
  25287. loader = new ImageLoader(this.manager);
  25288. loader.setCrossOrigin(this.crossOrigin);
  25289. for (let i = 0, il = json.length; i < il; i++) {
  25290. const image = json[i];
  25291. const url = image.url;
  25292. if (Array.isArray(url)) {
  25293. // load array of images e.g CubeTexture
  25294. const imageArray = [];
  25295. for (let j = 0, jl = url.length; j < jl; j++) {
  25296. const currentUrl = url[j];
  25297. const deserializedImage = await deserializeImage(currentUrl);
  25298. if (deserializedImage !== null) {
  25299. if (deserializedImage instanceof HTMLImageElement) {
  25300. imageArray.push(deserializedImage);
  25301. } else {
  25302. // special case: handle array of data textures for cube textures
  25303. imageArray.push(new DataTexture(deserializedImage.data, deserializedImage.width, deserializedImage.height));
  25304. }
  25305. }
  25306. }
  25307. images[image.uuid] = new Source(imageArray);
  25308. } else {
  25309. // load single image
  25310. const deserializedImage = await deserializeImage(image.url);
  25311. images[image.uuid] = new Source(deserializedImage);
  25312. }
  25313. }
  25314. }
  25315. return images;
  25316. }
  25317. parseTextures(json, images) {
  25318. function parseConstant(value, type) {
  25319. if (typeof value === 'number') return value;
  25320. console.warn('THREE.ObjectLoader.parseTexture: Constant should be in numeric form.', value);
  25321. return type[value];
  25322. }
  25323. const textures = {};
  25324. if (json !== undefined) {
  25325. for (let i = 0, l = json.length; i < l; i++) {
  25326. const data = json[i];
  25327. if (data.image === undefined) {
  25328. console.warn('THREE.ObjectLoader: No "image" specified for', data.uuid);
  25329. }
  25330. if (images[data.image] === undefined) {
  25331. console.warn('THREE.ObjectLoader: Undefined image', data.image);
  25332. }
  25333. const source = images[data.image];
  25334. const image = source.data;
  25335. let texture;
  25336. if (Array.isArray(image)) {
  25337. texture = new CubeTexture();
  25338. if (image.length === 6) texture.needsUpdate = true;
  25339. } else {
  25340. if (image && image.data) {
  25341. texture = new DataTexture();
  25342. } else {
  25343. texture = new Texture();
  25344. }
  25345. if (image) texture.needsUpdate = true; // textures can have undefined image data
  25346. }
  25347. texture.source = source;
  25348. texture.uuid = data.uuid;
  25349. if (data.name !== undefined) texture.name = data.name;
  25350. if (data.mapping !== undefined) texture.mapping = parseConstant(data.mapping, TEXTURE_MAPPING);
  25351. if (data.offset !== undefined) texture.offset.fromArray(data.offset);
  25352. if (data.repeat !== undefined) texture.repeat.fromArray(data.repeat);
  25353. if (data.center !== undefined) texture.center.fromArray(data.center);
  25354. if (data.rotation !== undefined) texture.rotation = data.rotation;
  25355. if (data.wrap !== undefined) {
  25356. texture.wrapS = parseConstant(data.wrap[0], TEXTURE_WRAPPING);
  25357. texture.wrapT = parseConstant(data.wrap[1], TEXTURE_WRAPPING);
  25358. }
  25359. if (data.format !== undefined) texture.format = data.format;
  25360. if (data.type !== undefined) texture.type = data.type;
  25361. if (data.encoding !== undefined) texture.encoding = data.encoding;
  25362. if (data.minFilter !== undefined) texture.minFilter = parseConstant(data.minFilter, TEXTURE_FILTER);
  25363. if (data.magFilter !== undefined) texture.magFilter = parseConstant(data.magFilter, TEXTURE_FILTER);
  25364. if (data.anisotropy !== undefined) texture.anisotropy = data.anisotropy;
  25365. if (data.flipY !== undefined) texture.flipY = data.flipY;
  25366. if (data.premultiplyAlpha !== undefined) texture.premultiplyAlpha = data.premultiplyAlpha;
  25367. if (data.unpackAlignment !== undefined) texture.unpackAlignment = data.unpackAlignment;
  25368. if (data.userData !== undefined) texture.userData = data.userData;
  25369. textures[data.uuid] = texture;
  25370. }
  25371. }
  25372. return textures;
  25373. }
  25374. parseObject(data, geometries, materials, textures, animations) {
  25375. let object;
  25376. function getGeometry(name) {
  25377. if (geometries[name] === undefined) {
  25378. console.warn('THREE.ObjectLoader: Undefined geometry', name);
  25379. }
  25380. return geometries[name];
  25381. }
  25382. function getMaterial(name) {
  25383. if (name === undefined) return undefined;
  25384. if (Array.isArray(name)) {
  25385. const array = [];
  25386. for (let i = 0, l = name.length; i < l; i++) {
  25387. const uuid = name[i];
  25388. if (materials[uuid] === undefined) {
  25389. console.warn('THREE.ObjectLoader: Undefined material', uuid);
  25390. }
  25391. array.push(materials[uuid]);
  25392. }
  25393. return array;
  25394. }
  25395. if (materials[name] === undefined) {
  25396. console.warn('THREE.ObjectLoader: Undefined material', name);
  25397. }
  25398. return materials[name];
  25399. }
  25400. function getTexture(uuid) {
  25401. if (textures[uuid] === undefined) {
  25402. console.warn('THREE.ObjectLoader: Undefined texture', uuid);
  25403. }
  25404. return textures[uuid];
  25405. }
  25406. let geometry, material;
  25407. switch (data.type) {
  25408. case 'Scene':
  25409. object = new Scene();
  25410. if (data.background !== undefined) {
  25411. if (Number.isInteger(data.background)) {
  25412. object.background = new Color(data.background);
  25413. } else {
  25414. object.background = getTexture(data.background);
  25415. }
  25416. }
  25417. if (data.environment !== undefined) {
  25418. object.environment = getTexture(data.environment);
  25419. }
  25420. if (data.fog !== undefined) {
  25421. if (data.fog.type === 'Fog') {
  25422. object.fog = new Fog(data.fog.color, data.fog.near, data.fog.far);
  25423. } else if (data.fog.type === 'FogExp2') {
  25424. object.fog = new FogExp2(data.fog.color, data.fog.density);
  25425. }
  25426. }
  25427. break;
  25428. case 'PerspectiveCamera':
  25429. object = new PerspectiveCamera(data.fov, data.aspect, data.near, data.far);
  25430. if (data.focus !== undefined) object.focus = data.focus;
  25431. if (data.zoom !== undefined) object.zoom = data.zoom;
  25432. if (data.filmGauge !== undefined) object.filmGauge = data.filmGauge;
  25433. if (data.filmOffset !== undefined) object.filmOffset = data.filmOffset;
  25434. if (data.view !== undefined) object.view = Object.assign({}, data.view);
  25435. break;
  25436. case 'OrthographicCamera':
  25437. object = new OrthographicCamera(data.left, data.right, data.top, data.bottom, data.near, data.far);
  25438. if (data.zoom !== undefined) object.zoom = data.zoom;
  25439. if (data.view !== undefined) object.view = Object.assign({}, data.view);
  25440. break;
  25441. case 'AmbientLight':
  25442. object = new AmbientLight(data.color, data.intensity);
  25443. break;
  25444. case 'DirectionalLight':
  25445. object = new DirectionalLight(data.color, data.intensity);
  25446. break;
  25447. case 'PointLight':
  25448. object = new PointLight(data.color, data.intensity, data.distance, data.decay);
  25449. break;
  25450. case 'RectAreaLight':
  25451. object = new RectAreaLight(data.color, data.intensity, data.width, data.height);
  25452. break;
  25453. case 'SpotLight':
  25454. object = new SpotLight(data.color, data.intensity, data.distance, data.angle, data.penumbra, data.decay);
  25455. break;
  25456. case 'HemisphereLight':
  25457. object = new HemisphereLight(data.color, data.groundColor, data.intensity);
  25458. break;
  25459. case 'LightProbe':
  25460. object = new LightProbe().fromJSON(data);
  25461. break;
  25462. case 'SkinnedMesh':
  25463. geometry = getGeometry(data.geometry);
  25464. material = getMaterial(data.material);
  25465. object = new SkinnedMesh(geometry, material);
  25466. if (data.bindMode !== undefined) object.bindMode = data.bindMode;
  25467. if (data.bindMatrix !== undefined) object.bindMatrix.fromArray(data.bindMatrix);
  25468. if (data.skeleton !== undefined) object.skeleton = data.skeleton;
  25469. break;
  25470. case 'Mesh':
  25471. geometry = getGeometry(data.geometry);
  25472. material = getMaterial(data.material);
  25473. object = new Mesh(geometry, material);
  25474. break;
  25475. case 'InstancedMesh':
  25476. geometry = getGeometry(data.geometry);
  25477. material = getMaterial(data.material);
  25478. const count = data.count;
  25479. const instanceMatrix = data.instanceMatrix;
  25480. const instanceColor = data.instanceColor;
  25481. object = new InstancedMesh(geometry, material, count);
  25482. object.instanceMatrix = new InstancedBufferAttribute(new Float32Array(instanceMatrix.array), 16);
  25483. if (instanceColor !== undefined) object.instanceColor = new InstancedBufferAttribute(new Float32Array(instanceColor.array), instanceColor.itemSize);
  25484. break;
  25485. case 'LOD':
  25486. object = new LOD();
  25487. break;
  25488. case 'Line':
  25489. object = new Line(getGeometry(data.geometry), getMaterial(data.material));
  25490. break;
  25491. case 'LineLoop':
  25492. object = new LineLoop(getGeometry(data.geometry), getMaterial(data.material));
  25493. break;
  25494. case 'LineSegments':
  25495. object = new LineSegments(getGeometry(data.geometry), getMaterial(data.material));
  25496. break;
  25497. case 'PointCloud':
  25498. case 'Points':
  25499. object = new Points(getGeometry(data.geometry), getMaterial(data.material));
  25500. break;
  25501. case 'Sprite':
  25502. object = new Sprite(getMaterial(data.material));
  25503. break;
  25504. case 'Group':
  25505. object = new Group();
  25506. break;
  25507. case 'Bone':
  25508. object = new Bone();
  25509. break;
  25510. default:
  25511. object = new Object3D();
  25512. }
  25513. object.uuid = data.uuid;
  25514. if (data.name !== undefined) object.name = data.name;
  25515. if (data.matrix !== undefined) {
  25516. object.matrix.fromArray(data.matrix);
  25517. if (data.matrixAutoUpdate !== undefined) object.matrixAutoUpdate = data.matrixAutoUpdate;
  25518. if (object.matrixAutoUpdate) object.matrix.decompose(object.position, object.quaternion, object.scale);
  25519. } else {
  25520. if (data.position !== undefined) object.position.fromArray(data.position);
  25521. if (data.rotation !== undefined) object.rotation.fromArray(data.rotation);
  25522. if (data.quaternion !== undefined) object.quaternion.fromArray(data.quaternion);
  25523. if (data.scale !== undefined) object.scale.fromArray(data.scale);
  25524. }
  25525. if (data.castShadow !== undefined) object.castShadow = data.castShadow;
  25526. if (data.receiveShadow !== undefined) object.receiveShadow = data.receiveShadow;
  25527. if (data.shadow) {
  25528. if (data.shadow.bias !== undefined) object.shadow.bias = data.shadow.bias;
  25529. if (data.shadow.normalBias !== undefined) object.shadow.normalBias = data.shadow.normalBias;
  25530. if (data.shadow.radius !== undefined) object.shadow.radius = data.shadow.radius;
  25531. if (data.shadow.mapSize !== undefined) object.shadow.mapSize.fromArray(data.shadow.mapSize);
  25532. if (data.shadow.camera !== undefined) object.shadow.camera = this.parseObject(data.shadow.camera);
  25533. }
  25534. if (data.visible !== undefined) object.visible = data.visible;
  25535. if (data.frustumCulled !== undefined) object.frustumCulled = data.frustumCulled;
  25536. if (data.renderOrder !== undefined) object.renderOrder = data.renderOrder;
  25537. if (data.userData !== undefined) object.userData = data.userData;
  25538. if (data.layers !== undefined) object.layers.mask = data.layers;
  25539. if (data.children !== undefined) {
  25540. const children = data.children;
  25541. for (let i = 0; i < children.length; i++) {
  25542. object.add(this.parseObject(children[i], geometries, materials, textures, animations));
  25543. }
  25544. }
  25545. if (data.animations !== undefined) {
  25546. const objectAnimations = data.animations;
  25547. for (let i = 0; i < objectAnimations.length; i++) {
  25548. const uuid = objectAnimations[i];
  25549. object.animations.push(animations[uuid]);
  25550. }
  25551. }
  25552. if (data.type === 'LOD') {
  25553. if (data.autoUpdate !== undefined) object.autoUpdate = data.autoUpdate;
  25554. const levels = data.levels;
  25555. for (let l = 0; l < levels.length; l++) {
  25556. const level = levels[l];
  25557. const child = object.getObjectByProperty('uuid', level.object);
  25558. if (child !== undefined) {
  25559. object.addLevel(child, level.distance);
  25560. }
  25561. }
  25562. }
  25563. return object;
  25564. }
  25565. bindSkeletons(object, skeletons) {
  25566. if (Object.keys(skeletons).length === 0) return;
  25567. object.traverse(function (child) {
  25568. if (child.isSkinnedMesh === true && child.skeleton !== undefined) {
  25569. const skeleton = skeletons[child.skeleton];
  25570. if (skeleton === undefined) {
  25571. console.warn('THREE.ObjectLoader: No skeleton found with UUID:', child.skeleton);
  25572. } else {
  25573. child.bind(skeleton, child.bindMatrix);
  25574. }
  25575. }
  25576. });
  25577. }
  25578. }
  25579. const TEXTURE_MAPPING = {
  25580. UVMapping: UVMapping,
  25581. CubeReflectionMapping: CubeReflectionMapping,
  25582. CubeRefractionMapping: CubeRefractionMapping,
  25583. EquirectangularReflectionMapping: EquirectangularReflectionMapping,
  25584. EquirectangularRefractionMapping: EquirectangularRefractionMapping,
  25585. CubeUVReflectionMapping: CubeUVReflectionMapping
  25586. };
  25587. const TEXTURE_WRAPPING = {
  25588. RepeatWrapping: RepeatWrapping,
  25589. ClampToEdgeWrapping: ClampToEdgeWrapping,
  25590. MirroredRepeatWrapping: MirroredRepeatWrapping
  25591. };
  25592. const TEXTURE_FILTER = {
  25593. NearestFilter: NearestFilter,
  25594. NearestMipmapNearestFilter: NearestMipmapNearestFilter,
  25595. NearestMipmapLinearFilter: NearestMipmapLinearFilter,
  25596. LinearFilter: LinearFilter,
  25597. LinearMipmapNearestFilter: LinearMipmapNearestFilter,
  25598. LinearMipmapLinearFilter: LinearMipmapLinearFilter
  25599. };
  25600. class ImageBitmapLoader extends Loader {
  25601. constructor(manager) {
  25602. super(manager);
  25603. this.isImageBitmapLoader = true;
  25604. if (typeof createImageBitmap === 'undefined') {
  25605. console.warn('THREE.ImageBitmapLoader: createImageBitmap() not supported.');
  25606. }
  25607. if (typeof fetch === 'undefined') {
  25608. console.warn('THREE.ImageBitmapLoader: fetch() not supported.');
  25609. }
  25610. this.options = {
  25611. premultiplyAlpha: 'none'
  25612. };
  25613. }
  25614. setOptions(options) {
  25615. this.options = options;
  25616. return this;
  25617. }
  25618. load(url, onLoad, onProgress, onError) {
  25619. if (url === undefined) url = '';
  25620. if (this.path !== undefined) url = this.path + url;
  25621. url = this.manager.resolveURL(url);
  25622. const scope = this;
  25623. const cached = Cache.get(url);
  25624. if (cached !== undefined) {
  25625. scope.manager.itemStart(url);
  25626. setTimeout(function () {
  25627. if (onLoad) onLoad(cached);
  25628. scope.manager.itemEnd(url);
  25629. }, 0);
  25630. return cached;
  25631. }
  25632. const fetchOptions = {};
  25633. fetchOptions.credentials = this.crossOrigin === 'anonymous' ? 'same-origin' : 'include';
  25634. fetchOptions.headers = this.requestHeader;
  25635. fetch(url, fetchOptions).then(function (res) {
  25636. return res.blob();
  25637. }).then(function (blob) {
  25638. return createImageBitmap(blob, Object.assign(scope.options, {
  25639. colorSpaceConversion: 'none'
  25640. }));
  25641. }).then(function (imageBitmap) {
  25642. Cache.add(url, imageBitmap);
  25643. if (onLoad) onLoad(imageBitmap);
  25644. scope.manager.itemEnd(url);
  25645. }).catch(function (e) {
  25646. if (onError) onError(e);
  25647. scope.manager.itemError(url);
  25648. scope.manager.itemEnd(url);
  25649. });
  25650. scope.manager.itemStart(url);
  25651. }
  25652. }
  25653. let _context;
  25654. const AudioContext = {
  25655. getContext: function () {
  25656. if (_context === undefined) {
  25657. _context = new (window.AudioContext || window.webkitAudioContext)();
  25658. }
  25659. return _context;
  25660. },
  25661. setContext: function (value) {
  25662. _context = value;
  25663. }
  25664. };
  25665. class AudioLoader extends Loader {
  25666. constructor(manager) {
  25667. super(manager);
  25668. }
  25669. load(url, onLoad, onProgress, onError) {
  25670. const scope = this;
  25671. const loader = new FileLoader(this.manager);
  25672. loader.setResponseType('arraybuffer');
  25673. loader.setPath(this.path);
  25674. loader.setRequestHeader(this.requestHeader);
  25675. loader.setWithCredentials(this.withCredentials);
  25676. loader.load(url, function (buffer) {
  25677. try {
  25678. // Create a copy of the buffer. The `decodeAudioData` method
  25679. // detaches the buffer when complete, preventing reuse.
  25680. const bufferCopy = buffer.slice(0);
  25681. const context = AudioContext.getContext();
  25682. context.decodeAudioData(bufferCopy, function (audioBuffer) {
  25683. onLoad(audioBuffer);
  25684. });
  25685. } catch (e) {
  25686. if (onError) {
  25687. onError(e);
  25688. } else {
  25689. console.error(e);
  25690. }
  25691. scope.manager.itemError(url);
  25692. }
  25693. }, onProgress, onError);
  25694. }
  25695. }
  25696. class HemisphereLightProbe extends LightProbe {
  25697. constructor(skyColor, groundColor, intensity = 1) {
  25698. super(undefined, intensity);
  25699. this.isHemisphereLightProbe = true;
  25700. const color1 = new Color().set(skyColor);
  25701. const color2 = new Color().set(groundColor);
  25702. const sky = new Vector3(color1.r, color1.g, color1.b);
  25703. const ground = new Vector3(color2.r, color2.g, color2.b); // without extra factor of PI in the shader, should = 1 / Math.sqrt( Math.PI );
  25704. const c0 = Math.sqrt(Math.PI);
  25705. const c1 = c0 * Math.sqrt(0.75);
  25706. this.sh.coefficients[0].copy(sky).add(ground).multiplyScalar(c0);
  25707. this.sh.coefficients[1].copy(sky).sub(ground).multiplyScalar(c1);
  25708. }
  25709. }
  25710. class AmbientLightProbe extends LightProbe {
  25711. constructor(color, intensity = 1) {
  25712. super(undefined, intensity);
  25713. this.isAmbientLightProbe = true;
  25714. const color1 = new Color().set(color); // without extra factor of PI in the shader, would be 2 / Math.sqrt( Math.PI );
  25715. this.sh.coefficients[0].set(color1.r, color1.g, color1.b).multiplyScalar(2 * Math.sqrt(Math.PI));
  25716. }
  25717. }
  25718. const _eyeRight = /*@__PURE__*/new Matrix4();
  25719. const _eyeLeft = /*@__PURE__*/new Matrix4();
  25720. const _projectionMatrix = /*@__PURE__*/new Matrix4();
  25721. class StereoCamera {
  25722. constructor() {
  25723. this.type = 'StereoCamera';
  25724. this.aspect = 1;
  25725. this.eyeSep = 0.064;
  25726. this.cameraL = new PerspectiveCamera();
  25727. this.cameraL.layers.enable(1);
  25728. this.cameraL.matrixAutoUpdate = false;
  25729. this.cameraR = new PerspectiveCamera();
  25730. this.cameraR.layers.enable(2);
  25731. this.cameraR.matrixAutoUpdate = false;
  25732. this._cache = {
  25733. focus: null,
  25734. fov: null,
  25735. aspect: null,
  25736. near: null,
  25737. far: null,
  25738. zoom: null,
  25739. eyeSep: null
  25740. };
  25741. }
  25742. update(camera) {
  25743. const cache = this._cache;
  25744. const needsUpdate = cache.focus !== camera.focus || cache.fov !== camera.fov || cache.aspect !== camera.aspect * this.aspect || cache.near !== camera.near || cache.far !== camera.far || cache.zoom !== camera.zoom || cache.eyeSep !== this.eyeSep;
  25745. if (needsUpdate) {
  25746. cache.focus = camera.focus;
  25747. cache.fov = camera.fov;
  25748. cache.aspect = camera.aspect * this.aspect;
  25749. cache.near = camera.near;
  25750. cache.far = camera.far;
  25751. cache.zoom = camera.zoom;
  25752. cache.eyeSep = this.eyeSep; // Off-axis stereoscopic effect based on
  25753. // http://paulbourke.net/stereographics/stereorender/
  25754. _projectionMatrix.copy(camera.projectionMatrix);
  25755. const eyeSepHalf = cache.eyeSep / 2;
  25756. const eyeSepOnProjection = eyeSepHalf * cache.near / cache.focus;
  25757. const ymax = cache.near * Math.tan(DEG2RAD * cache.fov * 0.5) / cache.zoom;
  25758. let xmin, xmax; // translate xOffset
  25759. _eyeLeft.elements[12] = -eyeSepHalf;
  25760. _eyeRight.elements[12] = eyeSepHalf; // for left eye
  25761. xmin = -ymax * cache.aspect + eyeSepOnProjection;
  25762. xmax = ymax * cache.aspect + eyeSepOnProjection;
  25763. _projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin);
  25764. _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin);
  25765. this.cameraL.projectionMatrix.copy(_projectionMatrix); // for right eye
  25766. xmin = -ymax * cache.aspect - eyeSepOnProjection;
  25767. xmax = ymax * cache.aspect - eyeSepOnProjection;
  25768. _projectionMatrix.elements[0] = 2 * cache.near / (xmax - xmin);
  25769. _projectionMatrix.elements[8] = (xmax + xmin) / (xmax - xmin);
  25770. this.cameraR.projectionMatrix.copy(_projectionMatrix);
  25771. }
  25772. this.cameraL.matrixWorld.copy(camera.matrixWorld).multiply(_eyeLeft);
  25773. this.cameraR.matrixWorld.copy(camera.matrixWorld).multiply(_eyeRight);
  25774. }
  25775. }
  25776. class Clock {
  25777. constructor(autoStart = true) {
  25778. this.autoStart = autoStart;
  25779. this.startTime = 0;
  25780. this.oldTime = 0;
  25781. this.elapsedTime = 0;
  25782. this.running = false;
  25783. }
  25784. start() {
  25785. this.startTime = now();
  25786. this.oldTime = this.startTime;
  25787. this.elapsedTime = 0;
  25788. this.running = true;
  25789. }
  25790. stop() {
  25791. this.getElapsedTime();
  25792. this.running = false;
  25793. this.autoStart = false;
  25794. }
  25795. getElapsedTime() {
  25796. this.getDelta();
  25797. return this.elapsedTime;
  25798. }
  25799. getDelta() {
  25800. let diff = 0;
  25801. if (this.autoStart && !this.running) {
  25802. this.start();
  25803. return 0;
  25804. }
  25805. if (this.running) {
  25806. const newTime = now();
  25807. diff = (newTime - this.oldTime) / 1000;
  25808. this.oldTime = newTime;
  25809. this.elapsedTime += diff;
  25810. }
  25811. return diff;
  25812. }
  25813. }
  25814. function now() {
  25815. return (typeof performance === 'undefined' ? Date : performance).now(); // see #10732
  25816. }
  25817. const _position$1 = /*@__PURE__*/new Vector3();
  25818. const _quaternion$1 = /*@__PURE__*/new Quaternion();
  25819. const _scale$1 = /*@__PURE__*/new Vector3();
  25820. const _orientation$1 = /*@__PURE__*/new Vector3();
  25821. class AudioListener extends Object3D {
  25822. constructor() {
  25823. super();
  25824. this.type = 'AudioListener';
  25825. this.context = AudioContext.getContext();
  25826. this.gain = this.context.createGain();
  25827. this.gain.connect(this.context.destination);
  25828. this.filter = null;
  25829. this.timeDelta = 0; // private
  25830. this._clock = new Clock();
  25831. }
  25832. getInput() {
  25833. return this.gain;
  25834. }
  25835. removeFilter() {
  25836. if (this.filter !== null) {
  25837. this.gain.disconnect(this.filter);
  25838. this.filter.disconnect(this.context.destination);
  25839. this.gain.connect(this.context.destination);
  25840. this.filter = null;
  25841. }
  25842. return this;
  25843. }
  25844. getFilter() {
  25845. return this.filter;
  25846. }
  25847. setFilter(value) {
  25848. if (this.filter !== null) {
  25849. this.gain.disconnect(this.filter);
  25850. this.filter.disconnect(this.context.destination);
  25851. } else {
  25852. this.gain.disconnect(this.context.destination);
  25853. }
  25854. this.filter = value;
  25855. this.gain.connect(this.filter);
  25856. this.filter.connect(this.context.destination);
  25857. return this;
  25858. }
  25859. getMasterVolume() {
  25860. return this.gain.gain.value;
  25861. }
  25862. setMasterVolume(value) {
  25863. this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01);
  25864. return this;
  25865. }
  25866. updateMatrixWorld(force) {
  25867. super.updateMatrixWorld(force);
  25868. const listener = this.context.listener;
  25869. const up = this.up;
  25870. this.timeDelta = this._clock.getDelta();
  25871. this.matrixWorld.decompose(_position$1, _quaternion$1, _scale$1);
  25872. _orientation$1.set(0, 0, -1).applyQuaternion(_quaternion$1);
  25873. if (listener.positionX) {
  25874. // code path for Chrome (see #14393)
  25875. const endTime = this.context.currentTime + this.timeDelta;
  25876. listener.positionX.linearRampToValueAtTime(_position$1.x, endTime);
  25877. listener.positionY.linearRampToValueAtTime(_position$1.y, endTime);
  25878. listener.positionZ.linearRampToValueAtTime(_position$1.z, endTime);
  25879. listener.forwardX.linearRampToValueAtTime(_orientation$1.x, endTime);
  25880. listener.forwardY.linearRampToValueAtTime(_orientation$1.y, endTime);
  25881. listener.forwardZ.linearRampToValueAtTime(_orientation$1.z, endTime);
  25882. listener.upX.linearRampToValueAtTime(up.x, endTime);
  25883. listener.upY.linearRampToValueAtTime(up.y, endTime);
  25884. listener.upZ.linearRampToValueAtTime(up.z, endTime);
  25885. } else {
  25886. listener.setPosition(_position$1.x, _position$1.y, _position$1.z);
  25887. listener.setOrientation(_orientation$1.x, _orientation$1.y, _orientation$1.z, up.x, up.y, up.z);
  25888. }
  25889. }
  25890. }
  25891. class Audio extends Object3D {
  25892. constructor(listener) {
  25893. super();
  25894. this.type = 'Audio';
  25895. this.listener = listener;
  25896. this.context = listener.context;
  25897. this.gain = this.context.createGain();
  25898. this.gain.connect(listener.getInput());
  25899. this.autoplay = false;
  25900. this.buffer = null;
  25901. this.detune = 0;
  25902. this.loop = false;
  25903. this.loopStart = 0;
  25904. this.loopEnd = 0;
  25905. this.offset = 0;
  25906. this.duration = undefined;
  25907. this.playbackRate = 1;
  25908. this.isPlaying = false;
  25909. this.hasPlaybackControl = true;
  25910. this.source = null;
  25911. this.sourceType = 'empty';
  25912. this._startedAt = 0;
  25913. this._progress = 0;
  25914. this._connected = false;
  25915. this.filters = [];
  25916. }
  25917. getOutput() {
  25918. return this.gain;
  25919. }
  25920. setNodeSource(audioNode) {
  25921. this.hasPlaybackControl = false;
  25922. this.sourceType = 'audioNode';
  25923. this.source = audioNode;
  25924. this.connect();
  25925. return this;
  25926. }
  25927. setMediaElementSource(mediaElement) {
  25928. this.hasPlaybackControl = false;
  25929. this.sourceType = 'mediaNode';
  25930. this.source = this.context.createMediaElementSource(mediaElement);
  25931. this.connect();
  25932. return this;
  25933. }
  25934. setMediaStreamSource(mediaStream) {
  25935. this.hasPlaybackControl = false;
  25936. this.sourceType = 'mediaStreamNode';
  25937. this.source = this.context.createMediaStreamSource(mediaStream);
  25938. this.connect();
  25939. return this;
  25940. }
  25941. setBuffer(audioBuffer) {
  25942. this.buffer = audioBuffer;
  25943. this.sourceType = 'buffer';
  25944. if (this.autoplay) this.play();
  25945. return this;
  25946. }
  25947. play(delay = 0) {
  25948. if (this.isPlaying === true) {
  25949. console.warn('THREE.Audio: Audio is already playing.');
  25950. return;
  25951. }
  25952. if (this.hasPlaybackControl === false) {
  25953. console.warn('THREE.Audio: this Audio has no playback control.');
  25954. return;
  25955. }
  25956. this._startedAt = this.context.currentTime + delay;
  25957. const source = this.context.createBufferSource();
  25958. source.buffer = this.buffer;
  25959. source.loop = this.loop;
  25960. source.loopStart = this.loopStart;
  25961. source.loopEnd = this.loopEnd;
  25962. source.onended = this.onEnded.bind(this);
  25963. source.start(this._startedAt, this._progress + this.offset, this.duration);
  25964. this.isPlaying = true;
  25965. this.source = source;
  25966. this.setDetune(this.detune);
  25967. this.setPlaybackRate(this.playbackRate);
  25968. return this.connect();
  25969. }
  25970. pause() {
  25971. if (this.hasPlaybackControl === false) {
  25972. console.warn('THREE.Audio: this Audio has no playback control.');
  25973. return;
  25974. }
  25975. if (this.isPlaying === true) {
  25976. // update current progress
  25977. this._progress += Math.max(this.context.currentTime - this._startedAt, 0) * this.playbackRate;
  25978. if (this.loop === true) {
  25979. // ensure _progress does not exceed duration with looped audios
  25980. this._progress = this._progress % (this.duration || this.buffer.duration);
  25981. }
  25982. this.source.stop();
  25983. this.source.onended = null;
  25984. this.isPlaying = false;
  25985. }
  25986. return this;
  25987. }
  25988. stop() {
  25989. if (this.hasPlaybackControl === false) {
  25990. console.warn('THREE.Audio: this Audio has no playback control.');
  25991. return;
  25992. }
  25993. this._progress = 0;
  25994. this.source.stop();
  25995. this.source.onended = null;
  25996. this.isPlaying = false;
  25997. return this;
  25998. }
  25999. connect() {
  26000. if (this.filters.length > 0) {
  26001. this.source.connect(this.filters[0]);
  26002. for (let i = 1, l = this.filters.length; i < l; i++) {
  26003. this.filters[i - 1].connect(this.filters[i]);
  26004. }
  26005. this.filters[this.filters.length - 1].connect(this.getOutput());
  26006. } else {
  26007. this.source.connect(this.getOutput());
  26008. }
  26009. this._connected = true;
  26010. return this;
  26011. }
  26012. disconnect() {
  26013. if (this.filters.length > 0) {
  26014. this.source.disconnect(this.filters[0]);
  26015. for (let i = 1, l = this.filters.length; i < l; i++) {
  26016. this.filters[i - 1].disconnect(this.filters[i]);
  26017. }
  26018. this.filters[this.filters.length - 1].disconnect(this.getOutput());
  26019. } else {
  26020. this.source.disconnect(this.getOutput());
  26021. }
  26022. this._connected = false;
  26023. return this;
  26024. }
  26025. getFilters() {
  26026. return this.filters;
  26027. }
  26028. setFilters(value) {
  26029. if (!value) value = [];
  26030. if (this._connected === true) {
  26031. this.disconnect();
  26032. this.filters = value.slice();
  26033. this.connect();
  26034. } else {
  26035. this.filters = value.slice();
  26036. }
  26037. return this;
  26038. }
  26039. setDetune(value) {
  26040. this.detune = value;
  26041. if (this.source.detune === undefined) return; // only set detune when available
  26042. if (this.isPlaying === true) {
  26043. this.source.detune.setTargetAtTime(this.detune, this.context.currentTime, 0.01);
  26044. }
  26045. return this;
  26046. }
  26047. getDetune() {
  26048. return this.detune;
  26049. }
  26050. getFilter() {
  26051. return this.getFilters()[0];
  26052. }
  26053. setFilter(filter) {
  26054. return this.setFilters(filter ? [filter] : []);
  26055. }
  26056. setPlaybackRate(value) {
  26057. if (this.hasPlaybackControl === false) {
  26058. console.warn('THREE.Audio: this Audio has no playback control.');
  26059. return;
  26060. }
  26061. this.playbackRate = value;
  26062. if (this.isPlaying === true) {
  26063. this.source.playbackRate.setTargetAtTime(this.playbackRate, this.context.currentTime, 0.01);
  26064. }
  26065. return this;
  26066. }
  26067. getPlaybackRate() {
  26068. return this.playbackRate;
  26069. }
  26070. onEnded() {
  26071. this.isPlaying = false;
  26072. }
  26073. getLoop() {
  26074. if (this.hasPlaybackControl === false) {
  26075. console.warn('THREE.Audio: this Audio has no playback control.');
  26076. return false;
  26077. }
  26078. return this.loop;
  26079. }
  26080. setLoop(value) {
  26081. if (this.hasPlaybackControl === false) {
  26082. console.warn('THREE.Audio: this Audio has no playback control.');
  26083. return;
  26084. }
  26085. this.loop = value;
  26086. if (this.isPlaying === true) {
  26087. this.source.loop = this.loop;
  26088. }
  26089. return this;
  26090. }
  26091. setLoopStart(value) {
  26092. this.loopStart = value;
  26093. return this;
  26094. }
  26095. setLoopEnd(value) {
  26096. this.loopEnd = value;
  26097. return this;
  26098. }
  26099. getVolume() {
  26100. return this.gain.gain.value;
  26101. }
  26102. setVolume(value) {
  26103. this.gain.gain.setTargetAtTime(value, this.context.currentTime, 0.01);
  26104. return this;
  26105. }
  26106. }
  26107. const _position = /*@__PURE__*/new Vector3();
  26108. const _quaternion = /*@__PURE__*/new Quaternion();
  26109. const _scale = /*@__PURE__*/new Vector3();
  26110. const _orientation = /*@__PURE__*/new Vector3();
  26111. class PositionalAudio extends Audio {
  26112. constructor(listener) {
  26113. super(listener);
  26114. this.panner = this.context.createPanner();
  26115. this.panner.panningModel = 'HRTF';
  26116. this.panner.connect(this.gain);
  26117. }
  26118. disconnect() {
  26119. super.disconnect();
  26120. this.panner.disconnect(this.gain);
  26121. }
  26122. getOutput() {
  26123. return this.panner;
  26124. }
  26125. getRefDistance() {
  26126. return this.panner.refDistance;
  26127. }
  26128. setRefDistance(value) {
  26129. this.panner.refDistance = value;
  26130. return this;
  26131. }
  26132. getRolloffFactor() {
  26133. return this.panner.rolloffFactor;
  26134. }
  26135. setRolloffFactor(value) {
  26136. this.panner.rolloffFactor = value;
  26137. return this;
  26138. }
  26139. getDistanceModel() {
  26140. return this.panner.distanceModel;
  26141. }
  26142. setDistanceModel(value) {
  26143. this.panner.distanceModel = value;
  26144. return this;
  26145. }
  26146. getMaxDistance() {
  26147. return this.panner.maxDistance;
  26148. }
  26149. setMaxDistance(value) {
  26150. this.panner.maxDistance = value;
  26151. return this;
  26152. }
  26153. setDirectionalCone(coneInnerAngle, coneOuterAngle, coneOuterGain) {
  26154. this.panner.coneInnerAngle = coneInnerAngle;
  26155. this.panner.coneOuterAngle = coneOuterAngle;
  26156. this.panner.coneOuterGain = coneOuterGain;
  26157. return this;
  26158. }
  26159. updateMatrixWorld(force) {
  26160. super.updateMatrixWorld(force);
  26161. if (this.hasPlaybackControl === true && this.isPlaying === false) return;
  26162. this.matrixWorld.decompose(_position, _quaternion, _scale);
  26163. _orientation.set(0, 0, 1).applyQuaternion(_quaternion);
  26164. const panner = this.panner;
  26165. if (panner.positionX) {
  26166. // code path for Chrome and Firefox (see #14393)
  26167. const endTime = this.context.currentTime + this.listener.timeDelta;
  26168. panner.positionX.linearRampToValueAtTime(_position.x, endTime);
  26169. panner.positionY.linearRampToValueAtTime(_position.y, endTime);
  26170. panner.positionZ.linearRampToValueAtTime(_position.z, endTime);
  26171. panner.orientationX.linearRampToValueAtTime(_orientation.x, endTime);
  26172. panner.orientationY.linearRampToValueAtTime(_orientation.y, endTime);
  26173. panner.orientationZ.linearRampToValueAtTime(_orientation.z, endTime);
  26174. } else {
  26175. panner.setPosition(_position.x, _position.y, _position.z);
  26176. panner.setOrientation(_orientation.x, _orientation.y, _orientation.z);
  26177. }
  26178. }
  26179. }
  26180. class AudioAnalyser {
  26181. constructor(audio, fftSize = 2048) {
  26182. this.analyser = audio.context.createAnalyser();
  26183. this.analyser.fftSize = fftSize;
  26184. this.data = new Uint8Array(this.analyser.frequencyBinCount);
  26185. audio.getOutput().connect(this.analyser);
  26186. }
  26187. getFrequencyData() {
  26188. this.analyser.getByteFrequencyData(this.data);
  26189. return this.data;
  26190. }
  26191. getAverageFrequency() {
  26192. let value = 0;
  26193. const data = this.getFrequencyData();
  26194. for (let i = 0; i < data.length; i++) {
  26195. value += data[i];
  26196. }
  26197. return value / data.length;
  26198. }
  26199. }
  26200. class PropertyMixer {
  26201. constructor(binding, typeName, valueSize) {
  26202. this.binding = binding;
  26203. this.valueSize = valueSize;
  26204. let mixFunction, mixFunctionAdditive, setIdentity; // buffer layout: [ incoming | accu0 | accu1 | orig | addAccu | (optional work) ]
  26205. //
  26206. // interpolators can use .buffer as their .result
  26207. // the data then goes to 'incoming'
  26208. //
  26209. // 'accu0' and 'accu1' are used frame-interleaved for
  26210. // the cumulative result and are compared to detect
  26211. // changes
  26212. //
  26213. // 'orig' stores the original state of the property
  26214. //
  26215. // 'add' is used for additive cumulative results
  26216. //
  26217. // 'work' is optional and is only present for quaternion types. It is used
  26218. // to store intermediate quaternion multiplication results
  26219. switch (typeName) {
  26220. case 'quaternion':
  26221. mixFunction = this._slerp;
  26222. mixFunctionAdditive = this._slerpAdditive;
  26223. setIdentity = this._setAdditiveIdentityQuaternion;
  26224. this.buffer = new Float64Array(valueSize * 6);
  26225. this._workIndex = 5;
  26226. break;
  26227. case 'string':
  26228. case 'bool':
  26229. mixFunction = this._select; // Use the regular mix function and for additive on these types,
  26230. // additive is not relevant for non-numeric types
  26231. mixFunctionAdditive = this._select;
  26232. setIdentity = this._setAdditiveIdentityOther;
  26233. this.buffer = new Array(valueSize * 5);
  26234. break;
  26235. default:
  26236. mixFunction = this._lerp;
  26237. mixFunctionAdditive = this._lerpAdditive;
  26238. setIdentity = this._setAdditiveIdentityNumeric;
  26239. this.buffer = new Float64Array(valueSize * 5);
  26240. }
  26241. this._mixBufferRegion = mixFunction;
  26242. this._mixBufferRegionAdditive = mixFunctionAdditive;
  26243. this._setIdentity = setIdentity;
  26244. this._origIndex = 3;
  26245. this._addIndex = 4;
  26246. this.cumulativeWeight = 0;
  26247. this.cumulativeWeightAdditive = 0;
  26248. this.useCount = 0;
  26249. this.referenceCount = 0;
  26250. } // accumulate data in the 'incoming' region into 'accu<i>'
  26251. accumulate(accuIndex, weight) {
  26252. // note: happily accumulating nothing when weight = 0, the caller knows
  26253. // the weight and shouldn't have made the call in the first place
  26254. const buffer = this.buffer,
  26255. stride = this.valueSize,
  26256. offset = accuIndex * stride + stride;
  26257. let currentWeight = this.cumulativeWeight;
  26258. if (currentWeight === 0) {
  26259. // accuN := incoming * weight
  26260. for (let i = 0; i !== stride; ++i) {
  26261. buffer[offset + i] = buffer[i];
  26262. }
  26263. currentWeight = weight;
  26264. } else {
  26265. // accuN := accuN + incoming * weight
  26266. currentWeight += weight;
  26267. const mix = weight / currentWeight;
  26268. this._mixBufferRegion(buffer, offset, 0, mix, stride);
  26269. }
  26270. this.cumulativeWeight = currentWeight;
  26271. } // accumulate data in the 'incoming' region into 'add'
  26272. accumulateAdditive(weight) {
  26273. const buffer = this.buffer,
  26274. stride = this.valueSize,
  26275. offset = stride * this._addIndex;
  26276. if (this.cumulativeWeightAdditive === 0) {
  26277. // add = identity
  26278. this._setIdentity();
  26279. } // add := add + incoming * weight
  26280. this._mixBufferRegionAdditive(buffer, offset, 0, weight, stride);
  26281. this.cumulativeWeightAdditive += weight;
  26282. } // apply the state of 'accu<i>' to the binding when accus differ
  26283. apply(accuIndex) {
  26284. const stride = this.valueSize,
  26285. buffer = this.buffer,
  26286. offset = accuIndex * stride + stride,
  26287. weight = this.cumulativeWeight,
  26288. weightAdditive = this.cumulativeWeightAdditive,
  26289. binding = this.binding;
  26290. this.cumulativeWeight = 0;
  26291. this.cumulativeWeightAdditive = 0;
  26292. if (weight < 1) {
  26293. // accuN := accuN + original * ( 1 - cumulativeWeight )
  26294. const originalValueOffset = stride * this._origIndex;
  26295. this._mixBufferRegion(buffer, offset, originalValueOffset, 1 - weight, stride);
  26296. }
  26297. if (weightAdditive > 0) {
  26298. // accuN := accuN + additive accuN
  26299. this._mixBufferRegionAdditive(buffer, offset, this._addIndex * stride, 1, stride);
  26300. }
  26301. for (let i = stride, e = stride + stride; i !== e; ++i) {
  26302. if (buffer[i] !== buffer[i + stride]) {
  26303. // value has changed -> update scene graph
  26304. binding.setValue(buffer, offset);
  26305. break;
  26306. }
  26307. }
  26308. } // remember the state of the bound property and copy it to both accus
  26309. saveOriginalState() {
  26310. const binding = this.binding;
  26311. const buffer = this.buffer,
  26312. stride = this.valueSize,
  26313. originalValueOffset = stride * this._origIndex;
  26314. binding.getValue(buffer, originalValueOffset); // accu[0..1] := orig -- initially detect changes against the original
  26315. for (let i = stride, e = originalValueOffset; i !== e; ++i) {
  26316. buffer[i] = buffer[originalValueOffset + i % stride];
  26317. } // Add to identity for additive
  26318. this._setIdentity();
  26319. this.cumulativeWeight = 0;
  26320. this.cumulativeWeightAdditive = 0;
  26321. } // apply the state previously taken via 'saveOriginalState' to the binding
  26322. restoreOriginalState() {
  26323. const originalValueOffset = this.valueSize * 3;
  26324. this.binding.setValue(this.buffer, originalValueOffset);
  26325. }
  26326. _setAdditiveIdentityNumeric() {
  26327. const startIndex = this._addIndex * this.valueSize;
  26328. const endIndex = startIndex + this.valueSize;
  26329. for (let i = startIndex; i < endIndex; i++) {
  26330. this.buffer[i] = 0;
  26331. }
  26332. }
  26333. _setAdditiveIdentityQuaternion() {
  26334. this._setAdditiveIdentityNumeric();
  26335. this.buffer[this._addIndex * this.valueSize + 3] = 1;
  26336. }
  26337. _setAdditiveIdentityOther() {
  26338. const startIndex = this._origIndex * this.valueSize;
  26339. const targetIndex = this._addIndex * this.valueSize;
  26340. for (let i = 0; i < this.valueSize; i++) {
  26341. this.buffer[targetIndex + i] = this.buffer[startIndex + i];
  26342. }
  26343. } // mix functions
  26344. _select(buffer, dstOffset, srcOffset, t, stride) {
  26345. if (t >= 0.5) {
  26346. for (let i = 0; i !== stride; ++i) {
  26347. buffer[dstOffset + i] = buffer[srcOffset + i];
  26348. }
  26349. }
  26350. }
  26351. _slerp(buffer, dstOffset, srcOffset, t) {
  26352. Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, srcOffset, t);
  26353. }
  26354. _slerpAdditive(buffer, dstOffset, srcOffset, t, stride) {
  26355. const workOffset = this._workIndex * stride; // Store result in intermediate buffer offset
  26356. Quaternion.multiplyQuaternionsFlat(buffer, workOffset, buffer, dstOffset, buffer, srcOffset); // Slerp to the intermediate result
  26357. Quaternion.slerpFlat(buffer, dstOffset, buffer, dstOffset, buffer, workOffset, t);
  26358. }
  26359. _lerp(buffer, dstOffset, srcOffset, t, stride) {
  26360. const s = 1 - t;
  26361. for (let i = 0; i !== stride; ++i) {
  26362. const j = dstOffset + i;
  26363. buffer[j] = buffer[j] * s + buffer[srcOffset + i] * t;
  26364. }
  26365. }
  26366. _lerpAdditive(buffer, dstOffset, srcOffset, t, stride) {
  26367. for (let i = 0; i !== stride; ++i) {
  26368. const j = dstOffset + i;
  26369. buffer[j] = buffer[j] + buffer[srcOffset + i] * t;
  26370. }
  26371. }
  26372. }
  26373. // Characters [].:/ are reserved for track binding syntax.
  26374. const _RESERVED_CHARS_RE = '\\[\\]\\.:\\/';
  26375. const _reservedRe = new RegExp('[' + _RESERVED_CHARS_RE + ']', 'g'); // Attempts to allow node names from any language. ES5's `\w` regexp matches
  26376. // only latin characters, and the unicode \p{L} is not yet supported. So
  26377. // instead, we exclude reserved characters and match everything else.
  26378. const _wordChar = '[^' + _RESERVED_CHARS_RE + ']';
  26379. const _wordCharOrDot = '[^' + _RESERVED_CHARS_RE.replace('\\.', '') + ']'; // Parent directories, delimited by '/' or ':'. Currently unused, but must
  26380. // be matched to parse the rest of the track name.
  26381. const _directoryRe = /*@__PURE__*/ /((?:WC+[\/:])*)/.source.replace('WC', _wordChar); // Target node. May contain word characters (a-zA-Z0-9_) and '.' or '-'.
  26382. const _nodeRe = /*@__PURE__*/ /(WCOD+)?/.source.replace('WCOD', _wordCharOrDot); // Object on target node, and accessor. May not contain reserved
  26383. // characters. Accessor may contain any character except closing bracket.
  26384. const _objectRe = /*@__PURE__*/ /(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace('WC', _wordChar); // Property and accessor. May not contain reserved characters. Accessor may
  26385. // contain any non-bracket characters.
  26386. const _propertyRe = /*@__PURE__*/ /\.(WC+)(?:\[(.+)\])?/.source.replace('WC', _wordChar);
  26387. const _trackRe = new RegExp('' + '^' + _directoryRe + _nodeRe + _objectRe + _propertyRe + '$');
  26388. const _supportedObjectNames = ['material', 'materials', 'bones'];
  26389. class Composite {
  26390. constructor(targetGroup, path, optionalParsedPath) {
  26391. const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path);
  26392. this._targetGroup = targetGroup;
  26393. this._bindings = targetGroup.subscribe_(path, parsedPath);
  26394. }
  26395. getValue(array, offset) {
  26396. this.bind(); // bind all binding
  26397. const firstValidIndex = this._targetGroup.nCachedObjects_,
  26398. binding = this._bindings[firstValidIndex]; // and only call .getValue on the first
  26399. if (binding !== undefined) binding.getValue(array, offset);
  26400. }
  26401. setValue(array, offset) {
  26402. const bindings = this._bindings;
  26403. for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) {
  26404. bindings[i].setValue(array, offset);
  26405. }
  26406. }
  26407. bind() {
  26408. const bindings = this._bindings;
  26409. for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) {
  26410. bindings[i].bind();
  26411. }
  26412. }
  26413. unbind() {
  26414. const bindings = this._bindings;
  26415. for (let i = this._targetGroup.nCachedObjects_, n = bindings.length; i !== n; ++i) {
  26416. bindings[i].unbind();
  26417. }
  26418. }
  26419. } // Note: This class uses a State pattern on a per-method basis:
  26420. // 'bind' sets 'this.getValue' / 'setValue' and shadows the
  26421. // prototype version of these methods with one that represents
  26422. // the bound state. When the property is not found, the methods
  26423. // become no-ops.
  26424. class PropertyBinding {
  26425. constructor(rootNode, path, parsedPath) {
  26426. this.path = path;
  26427. this.parsedPath = parsedPath || PropertyBinding.parseTrackName(path);
  26428. this.node = PropertyBinding.findNode(rootNode, this.parsedPath.nodeName) || rootNode;
  26429. this.rootNode = rootNode; // initial state of these methods that calls 'bind'
  26430. this.getValue = this._getValue_unbound;
  26431. this.setValue = this._setValue_unbound;
  26432. }
  26433. static create(root, path, parsedPath) {
  26434. if (!(root && root.isAnimationObjectGroup)) {
  26435. return new PropertyBinding(root, path, parsedPath);
  26436. } else {
  26437. return new PropertyBinding.Composite(root, path, parsedPath);
  26438. }
  26439. }
  26440. /**
  26441. * Replaces spaces with underscores and removes unsupported characters from
  26442. * node names, to ensure compatibility with parseTrackName().
  26443. *
  26444. * @param {string} name Node name to be sanitized.
  26445. * @return {string}
  26446. */
  26447. static sanitizeNodeName(name) {
  26448. return name.replace(/\s/g, '_').replace(_reservedRe, '');
  26449. }
  26450. static parseTrackName(trackName) {
  26451. const matches = _trackRe.exec(trackName);
  26452. if (matches === null) {
  26453. throw new Error('PropertyBinding: Cannot parse trackName: ' + trackName);
  26454. }
  26455. const results = {
  26456. // directoryName: matches[ 1 ], // (tschw) currently unused
  26457. nodeName: matches[2],
  26458. objectName: matches[3],
  26459. objectIndex: matches[4],
  26460. propertyName: matches[5],
  26461. // required
  26462. propertyIndex: matches[6]
  26463. };
  26464. const lastDot = results.nodeName && results.nodeName.lastIndexOf('.');
  26465. if (lastDot !== undefined && lastDot !== -1) {
  26466. const objectName = results.nodeName.substring(lastDot + 1); // Object names must be checked against an allowlist. Otherwise, there
  26467. // is no way to parse 'foo.bar.baz': 'baz' must be a property, but
  26468. // 'bar' could be the objectName, or part of a nodeName (which can
  26469. // include '.' characters).
  26470. if (_supportedObjectNames.indexOf(objectName) !== -1) {
  26471. results.nodeName = results.nodeName.substring(0, lastDot);
  26472. results.objectName = objectName;
  26473. }
  26474. }
  26475. if (results.propertyName === null || results.propertyName.length === 0) {
  26476. throw new Error('PropertyBinding: can not parse propertyName from trackName: ' + trackName);
  26477. }
  26478. return results;
  26479. }
  26480. static findNode(root, nodeName) {
  26481. if (nodeName === undefined || nodeName === '' || nodeName === '.' || nodeName === -1 || nodeName === root.name || nodeName === root.uuid) {
  26482. return root;
  26483. } // search into skeleton bones.
  26484. if (root.skeleton) {
  26485. const bone = root.skeleton.getBoneByName(nodeName);
  26486. if (bone !== undefined) {
  26487. return bone;
  26488. }
  26489. } // search into node subtree.
  26490. if (root.children) {
  26491. const searchNodeSubtree = function (children) {
  26492. for (let i = 0; i < children.length; i++) {
  26493. const childNode = children[i];
  26494. if (childNode.name === nodeName || childNode.uuid === nodeName) {
  26495. return childNode;
  26496. }
  26497. const result = searchNodeSubtree(childNode.children);
  26498. if (result) return result;
  26499. }
  26500. return null;
  26501. };
  26502. const subTreeNode = searchNodeSubtree(root.children);
  26503. if (subTreeNode) {
  26504. return subTreeNode;
  26505. }
  26506. }
  26507. return null;
  26508. } // these are used to "bind" a nonexistent property
  26509. _getValue_unavailable() {}
  26510. _setValue_unavailable() {} // Getters
  26511. _getValue_direct(buffer, offset) {
  26512. buffer[offset] = this.targetObject[this.propertyName];
  26513. }
  26514. _getValue_array(buffer, offset) {
  26515. const source = this.resolvedProperty;
  26516. for (let i = 0, n = source.length; i !== n; ++i) {
  26517. buffer[offset++] = source[i];
  26518. }
  26519. }
  26520. _getValue_arrayElement(buffer, offset) {
  26521. buffer[offset] = this.resolvedProperty[this.propertyIndex];
  26522. }
  26523. _getValue_toArray(buffer, offset) {
  26524. this.resolvedProperty.toArray(buffer, offset);
  26525. } // Direct
  26526. _setValue_direct(buffer, offset) {
  26527. this.targetObject[this.propertyName] = buffer[offset];
  26528. }
  26529. _setValue_direct_setNeedsUpdate(buffer, offset) {
  26530. this.targetObject[this.propertyName] = buffer[offset];
  26531. this.targetObject.needsUpdate = true;
  26532. }
  26533. _setValue_direct_setMatrixWorldNeedsUpdate(buffer, offset) {
  26534. this.targetObject[this.propertyName] = buffer[offset];
  26535. this.targetObject.matrixWorldNeedsUpdate = true;
  26536. } // EntireArray
  26537. _setValue_array(buffer, offset) {
  26538. const dest = this.resolvedProperty;
  26539. for (let i = 0, n = dest.length; i !== n; ++i) {
  26540. dest[i] = buffer[offset++];
  26541. }
  26542. }
  26543. _setValue_array_setNeedsUpdate(buffer, offset) {
  26544. const dest = this.resolvedProperty;
  26545. for (let i = 0, n = dest.length; i !== n; ++i) {
  26546. dest[i] = buffer[offset++];
  26547. }
  26548. this.targetObject.needsUpdate = true;
  26549. }
  26550. _setValue_array_setMatrixWorldNeedsUpdate(buffer, offset) {
  26551. const dest = this.resolvedProperty;
  26552. for (let i = 0, n = dest.length; i !== n; ++i) {
  26553. dest[i] = buffer[offset++];
  26554. }
  26555. this.targetObject.matrixWorldNeedsUpdate = true;
  26556. } // ArrayElement
  26557. _setValue_arrayElement(buffer, offset) {
  26558. this.resolvedProperty[this.propertyIndex] = buffer[offset];
  26559. }
  26560. _setValue_arrayElement_setNeedsUpdate(buffer, offset) {
  26561. this.resolvedProperty[this.propertyIndex] = buffer[offset];
  26562. this.targetObject.needsUpdate = true;
  26563. }
  26564. _setValue_arrayElement_setMatrixWorldNeedsUpdate(buffer, offset) {
  26565. this.resolvedProperty[this.propertyIndex] = buffer[offset];
  26566. this.targetObject.matrixWorldNeedsUpdate = true;
  26567. } // HasToFromArray
  26568. _setValue_fromArray(buffer, offset) {
  26569. this.resolvedProperty.fromArray(buffer, offset);
  26570. }
  26571. _setValue_fromArray_setNeedsUpdate(buffer, offset) {
  26572. this.resolvedProperty.fromArray(buffer, offset);
  26573. this.targetObject.needsUpdate = true;
  26574. }
  26575. _setValue_fromArray_setMatrixWorldNeedsUpdate(buffer, offset) {
  26576. this.resolvedProperty.fromArray(buffer, offset);
  26577. this.targetObject.matrixWorldNeedsUpdate = true;
  26578. }
  26579. _getValue_unbound(targetArray, offset) {
  26580. this.bind();
  26581. this.getValue(targetArray, offset);
  26582. }
  26583. _setValue_unbound(sourceArray, offset) {
  26584. this.bind();
  26585. this.setValue(sourceArray, offset);
  26586. } // create getter / setter pair for a property in the scene graph
  26587. bind() {
  26588. let targetObject = this.node;
  26589. const parsedPath = this.parsedPath;
  26590. const objectName = parsedPath.objectName;
  26591. const propertyName = parsedPath.propertyName;
  26592. let propertyIndex = parsedPath.propertyIndex;
  26593. if (!targetObject) {
  26594. targetObject = PropertyBinding.findNode(this.rootNode, parsedPath.nodeName) || this.rootNode;
  26595. this.node = targetObject;
  26596. } // set fail state so we can just 'return' on error
  26597. this.getValue = this._getValue_unavailable;
  26598. this.setValue = this._setValue_unavailable; // ensure there is a value node
  26599. if (!targetObject) {
  26600. console.error('THREE.PropertyBinding: Trying to update node for track: ' + this.path + ' but it wasn\'t found.');
  26601. return;
  26602. }
  26603. if (objectName) {
  26604. let objectIndex = parsedPath.objectIndex; // special cases were we need to reach deeper into the hierarchy to get the face materials....
  26605. switch (objectName) {
  26606. case 'materials':
  26607. if (!targetObject.material) {
  26608. console.error('THREE.PropertyBinding: Can not bind to material as node does not have a material.', this);
  26609. return;
  26610. }
  26611. if (!targetObject.material.materials) {
  26612. console.error('THREE.PropertyBinding: Can not bind to material.materials as node.material does not have a materials array.', this);
  26613. return;
  26614. }
  26615. targetObject = targetObject.material.materials;
  26616. break;
  26617. case 'bones':
  26618. if (!targetObject.skeleton) {
  26619. console.error('THREE.PropertyBinding: Can not bind to bones as node does not have a skeleton.', this);
  26620. return;
  26621. } // potential future optimization: skip this if propertyIndex is already an integer
  26622. // and convert the integer string to a true integer.
  26623. targetObject = targetObject.skeleton.bones; // support resolving morphTarget names into indices.
  26624. for (let i = 0; i < targetObject.length; i++) {
  26625. if (targetObject[i].name === objectIndex) {
  26626. objectIndex = i;
  26627. break;
  26628. }
  26629. }
  26630. break;
  26631. default:
  26632. if (targetObject[objectName] === undefined) {
  26633. console.error('THREE.PropertyBinding: Can not bind to objectName of node undefined.', this);
  26634. return;
  26635. }
  26636. targetObject = targetObject[objectName];
  26637. }
  26638. if (objectIndex !== undefined) {
  26639. if (targetObject[objectIndex] === undefined) {
  26640. console.error('THREE.PropertyBinding: Trying to bind to objectIndex of objectName, but is undefined.', this, targetObject);
  26641. return;
  26642. }
  26643. targetObject = targetObject[objectIndex];
  26644. }
  26645. } // resolve property
  26646. const nodeProperty = targetObject[propertyName];
  26647. if (nodeProperty === undefined) {
  26648. const nodeName = parsedPath.nodeName;
  26649. console.error('THREE.PropertyBinding: Trying to update property for track: ' + nodeName + '.' + propertyName + ' but it wasn\'t found.', targetObject);
  26650. return;
  26651. } // determine versioning scheme
  26652. let versioning = this.Versioning.None;
  26653. this.targetObject = targetObject;
  26654. if (targetObject.needsUpdate !== undefined) {
  26655. // material
  26656. versioning = this.Versioning.NeedsUpdate;
  26657. } else if (targetObject.matrixWorldNeedsUpdate !== undefined) {
  26658. // node transform
  26659. versioning = this.Versioning.MatrixWorldNeedsUpdate;
  26660. } // determine how the property gets bound
  26661. let bindingType = this.BindingType.Direct;
  26662. if (propertyIndex !== undefined) {
  26663. // access a sub element of the property array (only primitives are supported right now)
  26664. if (propertyName === 'morphTargetInfluences') {
  26665. // potential optimization, skip this if propertyIndex is already an integer, and convert the integer string to a true integer.
  26666. // support resolving morphTarget names into indices.
  26667. if (!targetObject.geometry) {
  26668. console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.', this);
  26669. return;
  26670. }
  26671. if (!targetObject.geometry.morphAttributes) {
  26672. console.error('THREE.PropertyBinding: Can not bind to morphTargetInfluences because node does not have a geometry.morphAttributes.', this);
  26673. return;
  26674. }
  26675. if (targetObject.morphTargetDictionary[propertyIndex] !== undefined) {
  26676. propertyIndex = targetObject.morphTargetDictionary[propertyIndex];
  26677. }
  26678. }
  26679. bindingType = this.BindingType.ArrayElement;
  26680. this.resolvedProperty = nodeProperty;
  26681. this.propertyIndex = propertyIndex;
  26682. } else if (nodeProperty.fromArray !== undefined && nodeProperty.toArray !== undefined) {
  26683. // must use copy for Object3D.Euler/Quaternion
  26684. bindingType = this.BindingType.HasFromToArray;
  26685. this.resolvedProperty = nodeProperty;
  26686. } else if (Array.isArray(nodeProperty)) {
  26687. bindingType = this.BindingType.EntireArray;
  26688. this.resolvedProperty = nodeProperty;
  26689. } else {
  26690. this.propertyName = propertyName;
  26691. } // select getter / setter
  26692. this.getValue = this.GetterByBindingType[bindingType];
  26693. this.setValue = this.SetterByBindingTypeAndVersioning[bindingType][versioning];
  26694. }
  26695. unbind() {
  26696. this.node = null; // back to the prototype version of getValue / setValue
  26697. // note: avoiding to mutate the shape of 'this' via 'delete'
  26698. this.getValue = this._getValue_unbound;
  26699. this.setValue = this._setValue_unbound;
  26700. }
  26701. }
  26702. PropertyBinding.Composite = Composite;
  26703. PropertyBinding.prototype.BindingType = {
  26704. Direct: 0,
  26705. EntireArray: 1,
  26706. ArrayElement: 2,
  26707. HasFromToArray: 3
  26708. };
  26709. PropertyBinding.prototype.Versioning = {
  26710. None: 0,
  26711. NeedsUpdate: 1,
  26712. MatrixWorldNeedsUpdate: 2
  26713. };
  26714. PropertyBinding.prototype.GetterByBindingType = [PropertyBinding.prototype._getValue_direct, PropertyBinding.prototype._getValue_array, PropertyBinding.prototype._getValue_arrayElement, PropertyBinding.prototype._getValue_toArray];
  26715. PropertyBinding.prototype.SetterByBindingTypeAndVersioning = [[// Direct
  26716. PropertyBinding.prototype._setValue_direct, PropertyBinding.prototype._setValue_direct_setNeedsUpdate, PropertyBinding.prototype._setValue_direct_setMatrixWorldNeedsUpdate], [// EntireArray
  26717. PropertyBinding.prototype._setValue_array, PropertyBinding.prototype._setValue_array_setNeedsUpdate, PropertyBinding.prototype._setValue_array_setMatrixWorldNeedsUpdate], [// ArrayElement
  26718. PropertyBinding.prototype._setValue_arrayElement, PropertyBinding.prototype._setValue_arrayElement_setNeedsUpdate, PropertyBinding.prototype._setValue_arrayElement_setMatrixWorldNeedsUpdate], [// HasToFromArray
  26719. PropertyBinding.prototype._setValue_fromArray, PropertyBinding.prototype._setValue_fromArray_setNeedsUpdate, PropertyBinding.prototype._setValue_fromArray_setMatrixWorldNeedsUpdate]];
  26720. /**
  26721. *
  26722. * A group of objects that receives a shared animation state.
  26723. *
  26724. * Usage:
  26725. *
  26726. * - Add objects you would otherwise pass as 'root' to the
  26727. * constructor or the .clipAction method of AnimationMixer.
  26728. *
  26729. * - Instead pass this object as 'root'.
  26730. *
  26731. * - You can also add and remove objects later when the mixer
  26732. * is running.
  26733. *
  26734. * Note:
  26735. *
  26736. * Objects of this class appear as one object to the mixer,
  26737. * so cache control of the individual objects must be done
  26738. * on the group.
  26739. *
  26740. * Limitation:
  26741. *
  26742. * - The animated properties must be compatible among the
  26743. * all objects in the group.
  26744. *
  26745. * - A single property can either be controlled through a
  26746. * target group or directly, but not both.
  26747. */
  26748. class AnimationObjectGroup {
  26749. constructor() {
  26750. this.isAnimationObjectGroup = true;
  26751. this.uuid = generateUUID(); // cached objects followed by the active ones
  26752. this._objects = Array.prototype.slice.call(arguments);
  26753. this.nCachedObjects_ = 0; // threshold
  26754. // note: read by PropertyBinding.Composite
  26755. const indices = {};
  26756. this._indicesByUUID = indices; // for bookkeeping
  26757. for (let i = 0, n = arguments.length; i !== n; ++i) {
  26758. indices[arguments[i].uuid] = i;
  26759. }
  26760. this._paths = []; // inside: string
  26761. this._parsedPaths = []; // inside: { we don't care, here }
  26762. this._bindings = []; // inside: Array< PropertyBinding >
  26763. this._bindingsIndicesByPath = {}; // inside: indices in these arrays
  26764. const scope = this;
  26765. this.stats = {
  26766. objects: {
  26767. get total() {
  26768. return scope._objects.length;
  26769. },
  26770. get inUse() {
  26771. return this.total - scope.nCachedObjects_;
  26772. }
  26773. },
  26774. get bindingsPerObject() {
  26775. return scope._bindings.length;
  26776. }
  26777. };
  26778. }
  26779. add() {
  26780. const objects = this._objects,
  26781. indicesByUUID = this._indicesByUUID,
  26782. paths = this._paths,
  26783. parsedPaths = this._parsedPaths,
  26784. bindings = this._bindings,
  26785. nBindings = bindings.length;
  26786. let knownObject = undefined,
  26787. nObjects = objects.length,
  26788. nCachedObjects = this.nCachedObjects_;
  26789. for (let i = 0, n = arguments.length; i !== n; ++i) {
  26790. const object = arguments[i],
  26791. uuid = object.uuid;
  26792. let index = indicesByUUID[uuid];
  26793. if (index === undefined) {
  26794. // unknown object -> add it to the ACTIVE region
  26795. index = nObjects++;
  26796. indicesByUUID[uuid] = index;
  26797. objects.push(object); // accounting is done, now do the same for all bindings
  26798. for (let j = 0, m = nBindings; j !== m; ++j) {
  26799. bindings[j].push(new PropertyBinding(object, paths[j], parsedPaths[j]));
  26800. }
  26801. } else if (index < nCachedObjects) {
  26802. knownObject = objects[index]; // move existing object to the ACTIVE region
  26803. const firstActiveIndex = --nCachedObjects,
  26804. lastCachedObject = objects[firstActiveIndex];
  26805. indicesByUUID[lastCachedObject.uuid] = index;
  26806. objects[index] = lastCachedObject;
  26807. indicesByUUID[uuid] = firstActiveIndex;
  26808. objects[firstActiveIndex] = object; // accounting is done, now do the same for all bindings
  26809. for (let j = 0, m = nBindings; j !== m; ++j) {
  26810. const bindingsForPath = bindings[j],
  26811. lastCached = bindingsForPath[firstActiveIndex];
  26812. let binding = bindingsForPath[index];
  26813. bindingsForPath[index] = lastCached;
  26814. if (binding === undefined) {
  26815. // since we do not bother to create new bindings
  26816. // for objects that are cached, the binding may
  26817. // or may not exist
  26818. binding = new PropertyBinding(object, paths[j], parsedPaths[j]);
  26819. }
  26820. bindingsForPath[firstActiveIndex] = binding;
  26821. }
  26822. } else if (objects[index] !== knownObject) {
  26823. console.error('THREE.AnimationObjectGroup: Different objects with the same UUID ' + 'detected. Clean the caches or recreate your infrastructure when reloading scenes.');
  26824. } // else the object is already where we want it to be
  26825. } // for arguments
  26826. this.nCachedObjects_ = nCachedObjects;
  26827. }
  26828. remove() {
  26829. const objects = this._objects,
  26830. indicesByUUID = this._indicesByUUID,
  26831. bindings = this._bindings,
  26832. nBindings = bindings.length;
  26833. let nCachedObjects = this.nCachedObjects_;
  26834. for (let i = 0, n = arguments.length; i !== n; ++i) {
  26835. const object = arguments[i],
  26836. uuid = object.uuid,
  26837. index = indicesByUUID[uuid];
  26838. if (index !== undefined && index >= nCachedObjects) {
  26839. // move existing object into the CACHED region
  26840. const lastCachedIndex = nCachedObjects++,
  26841. firstActiveObject = objects[lastCachedIndex];
  26842. indicesByUUID[firstActiveObject.uuid] = index;
  26843. objects[index] = firstActiveObject;
  26844. indicesByUUID[uuid] = lastCachedIndex;
  26845. objects[lastCachedIndex] = object; // accounting is done, now do the same for all bindings
  26846. for (let j = 0, m = nBindings; j !== m; ++j) {
  26847. const bindingsForPath = bindings[j],
  26848. firstActive = bindingsForPath[lastCachedIndex],
  26849. binding = bindingsForPath[index];
  26850. bindingsForPath[index] = firstActive;
  26851. bindingsForPath[lastCachedIndex] = binding;
  26852. }
  26853. }
  26854. } // for arguments
  26855. this.nCachedObjects_ = nCachedObjects;
  26856. } // remove & forget
  26857. uncache() {
  26858. const objects = this._objects,
  26859. indicesByUUID = this._indicesByUUID,
  26860. bindings = this._bindings,
  26861. nBindings = bindings.length;
  26862. let nCachedObjects = this.nCachedObjects_,
  26863. nObjects = objects.length;
  26864. for (let i = 0, n = arguments.length; i !== n; ++i) {
  26865. const object = arguments[i],
  26866. uuid = object.uuid,
  26867. index = indicesByUUID[uuid];
  26868. if (index !== undefined) {
  26869. delete indicesByUUID[uuid];
  26870. if (index < nCachedObjects) {
  26871. // object is cached, shrink the CACHED region
  26872. const firstActiveIndex = --nCachedObjects,
  26873. lastCachedObject = objects[firstActiveIndex],
  26874. lastIndex = --nObjects,
  26875. lastObject = objects[lastIndex]; // last cached object takes this object's place
  26876. indicesByUUID[lastCachedObject.uuid] = index;
  26877. objects[index] = lastCachedObject; // last object goes to the activated slot and pop
  26878. indicesByUUID[lastObject.uuid] = firstActiveIndex;
  26879. objects[firstActiveIndex] = lastObject;
  26880. objects.pop(); // accounting is done, now do the same for all bindings
  26881. for (let j = 0, m = nBindings; j !== m; ++j) {
  26882. const bindingsForPath = bindings[j],
  26883. lastCached = bindingsForPath[firstActiveIndex],
  26884. last = bindingsForPath[lastIndex];
  26885. bindingsForPath[index] = lastCached;
  26886. bindingsForPath[firstActiveIndex] = last;
  26887. bindingsForPath.pop();
  26888. }
  26889. } else {
  26890. // object is active, just swap with the last and pop
  26891. const lastIndex = --nObjects,
  26892. lastObject = objects[lastIndex];
  26893. if (lastIndex > 0) {
  26894. indicesByUUID[lastObject.uuid] = index;
  26895. }
  26896. objects[index] = lastObject;
  26897. objects.pop(); // accounting is done, now do the same for all bindings
  26898. for (let j = 0, m = nBindings; j !== m; ++j) {
  26899. const bindingsForPath = bindings[j];
  26900. bindingsForPath[index] = bindingsForPath[lastIndex];
  26901. bindingsForPath.pop();
  26902. }
  26903. } // cached or active
  26904. } // if object is known
  26905. } // for arguments
  26906. this.nCachedObjects_ = nCachedObjects;
  26907. } // Internal interface used by befriended PropertyBinding.Composite:
  26908. subscribe_(path, parsedPath) {
  26909. // returns an array of bindings for the given path that is changed
  26910. // according to the contained objects in the group
  26911. const indicesByPath = this._bindingsIndicesByPath;
  26912. let index = indicesByPath[path];
  26913. const bindings = this._bindings;
  26914. if (index !== undefined) return bindings[index];
  26915. const paths = this._paths,
  26916. parsedPaths = this._parsedPaths,
  26917. objects = this._objects,
  26918. nObjects = objects.length,
  26919. nCachedObjects = this.nCachedObjects_,
  26920. bindingsForPath = new Array(nObjects);
  26921. index = bindings.length;
  26922. indicesByPath[path] = index;
  26923. paths.push(path);
  26924. parsedPaths.push(parsedPath);
  26925. bindings.push(bindingsForPath);
  26926. for (let i = nCachedObjects, n = objects.length; i !== n; ++i) {
  26927. const object = objects[i];
  26928. bindingsForPath[i] = new PropertyBinding(object, path, parsedPath);
  26929. }
  26930. return bindingsForPath;
  26931. }
  26932. unsubscribe_(path) {
  26933. // tells the group to forget about a property path and no longer
  26934. // update the array previously obtained with 'subscribe_'
  26935. const indicesByPath = this._bindingsIndicesByPath,
  26936. index = indicesByPath[path];
  26937. if (index !== undefined) {
  26938. const paths = this._paths,
  26939. parsedPaths = this._parsedPaths,
  26940. bindings = this._bindings,
  26941. lastBindingsIndex = bindings.length - 1,
  26942. lastBindings = bindings[lastBindingsIndex],
  26943. lastBindingsPath = path[lastBindingsIndex];
  26944. indicesByPath[lastBindingsPath] = index;
  26945. bindings[index] = lastBindings;
  26946. bindings.pop();
  26947. parsedPaths[index] = parsedPaths[lastBindingsIndex];
  26948. parsedPaths.pop();
  26949. paths[index] = paths[lastBindingsIndex];
  26950. paths.pop();
  26951. }
  26952. }
  26953. }
  26954. class AnimationAction {
  26955. constructor(mixer, clip, localRoot = null, blendMode = clip.blendMode) {
  26956. this._mixer = mixer;
  26957. this._clip = clip;
  26958. this._localRoot = localRoot;
  26959. this.blendMode = blendMode;
  26960. const tracks = clip.tracks,
  26961. nTracks = tracks.length,
  26962. interpolants = new Array(nTracks);
  26963. const interpolantSettings = {
  26964. endingStart: ZeroCurvatureEnding,
  26965. endingEnd: ZeroCurvatureEnding
  26966. };
  26967. for (let i = 0; i !== nTracks; ++i) {
  26968. const interpolant = tracks[i].createInterpolant(null);
  26969. interpolants[i] = interpolant;
  26970. interpolant.settings = interpolantSettings;
  26971. }
  26972. this._interpolantSettings = interpolantSettings;
  26973. this._interpolants = interpolants; // bound by the mixer
  26974. // inside: PropertyMixer (managed by the mixer)
  26975. this._propertyBindings = new Array(nTracks);
  26976. this._cacheIndex = null; // for the memory manager
  26977. this._byClipCacheIndex = null; // for the memory manager
  26978. this._timeScaleInterpolant = null;
  26979. this._weightInterpolant = null;
  26980. this.loop = LoopRepeat;
  26981. this._loopCount = -1; // global mixer time when the action is to be started
  26982. // it's set back to 'null' upon start of the action
  26983. this._startTime = null; // scaled local time of the action
  26984. // gets clamped or wrapped to 0..clip.duration according to loop
  26985. this.time = 0;
  26986. this.timeScale = 1;
  26987. this._effectiveTimeScale = 1;
  26988. this.weight = 1;
  26989. this._effectiveWeight = 1;
  26990. this.repetitions = Infinity; // no. of repetitions when looping
  26991. this.paused = false; // true -> zero effective time scale
  26992. this.enabled = true; // false -> zero effective weight
  26993. this.clampWhenFinished = false; // keep feeding the last frame?
  26994. this.zeroSlopeAtStart = true; // for smooth interpolation w/o separate
  26995. this.zeroSlopeAtEnd = true; // clips for start, loop and end
  26996. } // State & Scheduling
  26997. play() {
  26998. this._mixer._activateAction(this);
  26999. return this;
  27000. }
  27001. stop() {
  27002. this._mixer._deactivateAction(this);
  27003. return this.reset();
  27004. }
  27005. reset() {
  27006. this.paused = false;
  27007. this.enabled = true;
  27008. this.time = 0; // restart clip
  27009. this._loopCount = -1; // forget previous loops
  27010. this._startTime = null; // forget scheduling
  27011. return this.stopFading().stopWarping();
  27012. }
  27013. isRunning() {
  27014. return this.enabled && !this.paused && this.timeScale !== 0 && this._startTime === null && this._mixer._isActiveAction(this);
  27015. } // return true when play has been called
  27016. isScheduled() {
  27017. return this._mixer._isActiveAction(this);
  27018. }
  27019. startAt(time) {
  27020. this._startTime = time;
  27021. return this;
  27022. }
  27023. setLoop(mode, repetitions) {
  27024. this.loop = mode;
  27025. this.repetitions = repetitions;
  27026. return this;
  27027. } // Weight
  27028. // set the weight stopping any scheduled fading
  27029. // although .enabled = false yields an effective weight of zero, this
  27030. // method does *not* change .enabled, because it would be confusing
  27031. setEffectiveWeight(weight) {
  27032. this.weight = weight; // note: same logic as when updated at runtime
  27033. this._effectiveWeight = this.enabled ? weight : 0;
  27034. return this.stopFading();
  27035. } // return the weight considering fading and .enabled
  27036. getEffectiveWeight() {
  27037. return this._effectiveWeight;
  27038. }
  27039. fadeIn(duration) {
  27040. return this._scheduleFading(duration, 0, 1);
  27041. }
  27042. fadeOut(duration) {
  27043. return this._scheduleFading(duration, 1, 0);
  27044. }
  27045. crossFadeFrom(fadeOutAction, duration, warp) {
  27046. fadeOutAction.fadeOut(duration);
  27047. this.fadeIn(duration);
  27048. if (warp) {
  27049. const fadeInDuration = this._clip.duration,
  27050. fadeOutDuration = fadeOutAction._clip.duration,
  27051. startEndRatio = fadeOutDuration / fadeInDuration,
  27052. endStartRatio = fadeInDuration / fadeOutDuration;
  27053. fadeOutAction.warp(1.0, startEndRatio, duration);
  27054. this.warp(endStartRatio, 1.0, duration);
  27055. }
  27056. return this;
  27057. }
  27058. crossFadeTo(fadeInAction, duration, warp) {
  27059. return fadeInAction.crossFadeFrom(this, duration, warp);
  27060. }
  27061. stopFading() {
  27062. const weightInterpolant = this._weightInterpolant;
  27063. if (weightInterpolant !== null) {
  27064. this._weightInterpolant = null;
  27065. this._mixer._takeBackControlInterpolant(weightInterpolant);
  27066. }
  27067. return this;
  27068. } // Time Scale Control
  27069. // set the time scale stopping any scheduled warping
  27070. // although .paused = true yields an effective time scale of zero, this
  27071. // method does *not* change .paused, because it would be confusing
  27072. setEffectiveTimeScale(timeScale) {
  27073. this.timeScale = timeScale;
  27074. this._effectiveTimeScale = this.paused ? 0 : timeScale;
  27075. return this.stopWarping();
  27076. } // return the time scale considering warping and .paused
  27077. getEffectiveTimeScale() {
  27078. return this._effectiveTimeScale;
  27079. }
  27080. setDuration(duration) {
  27081. this.timeScale = this._clip.duration / duration;
  27082. return this.stopWarping();
  27083. }
  27084. syncWith(action) {
  27085. this.time = action.time;
  27086. this.timeScale = action.timeScale;
  27087. return this.stopWarping();
  27088. }
  27089. halt(duration) {
  27090. return this.warp(this._effectiveTimeScale, 0, duration);
  27091. }
  27092. warp(startTimeScale, endTimeScale, duration) {
  27093. const mixer = this._mixer,
  27094. now = mixer.time,
  27095. timeScale = this.timeScale;
  27096. let interpolant = this._timeScaleInterpolant;
  27097. if (interpolant === null) {
  27098. interpolant = mixer._lendControlInterpolant();
  27099. this._timeScaleInterpolant = interpolant;
  27100. }
  27101. const times = interpolant.parameterPositions,
  27102. values = interpolant.sampleValues;
  27103. times[0] = now;
  27104. times[1] = now + duration;
  27105. values[0] = startTimeScale / timeScale;
  27106. values[1] = endTimeScale / timeScale;
  27107. return this;
  27108. }
  27109. stopWarping() {
  27110. const timeScaleInterpolant = this._timeScaleInterpolant;
  27111. if (timeScaleInterpolant !== null) {
  27112. this._timeScaleInterpolant = null;
  27113. this._mixer._takeBackControlInterpolant(timeScaleInterpolant);
  27114. }
  27115. return this;
  27116. } // Object Accessors
  27117. getMixer() {
  27118. return this._mixer;
  27119. }
  27120. getClip() {
  27121. return this._clip;
  27122. }
  27123. getRoot() {
  27124. return this._localRoot || this._mixer._root;
  27125. } // Interna
  27126. _update(time, deltaTime, timeDirection, accuIndex) {
  27127. // called by the mixer
  27128. if (!this.enabled) {
  27129. // call ._updateWeight() to update ._effectiveWeight
  27130. this._updateWeight(time);
  27131. return;
  27132. }
  27133. const startTime = this._startTime;
  27134. if (startTime !== null) {
  27135. // check for scheduled start of action
  27136. const timeRunning = (time - startTime) * timeDirection;
  27137. if (timeRunning < 0 || timeDirection === 0) {
  27138. return; // yet to come / don't decide when delta = 0
  27139. } // start
  27140. this._startTime = null; // unschedule
  27141. deltaTime = timeDirection * timeRunning;
  27142. } // apply time scale and advance time
  27143. deltaTime *= this._updateTimeScale(time);
  27144. const clipTime = this._updateTime(deltaTime); // note: _updateTime may disable the action resulting in
  27145. // an effective weight of 0
  27146. const weight = this._updateWeight(time);
  27147. if (weight > 0) {
  27148. const interpolants = this._interpolants;
  27149. const propertyMixers = this._propertyBindings;
  27150. switch (this.blendMode) {
  27151. case AdditiveAnimationBlendMode:
  27152. for (let j = 0, m = interpolants.length; j !== m; ++j) {
  27153. interpolants[j].evaluate(clipTime);
  27154. propertyMixers[j].accumulateAdditive(weight);
  27155. }
  27156. break;
  27157. case NormalAnimationBlendMode:
  27158. default:
  27159. for (let j = 0, m = interpolants.length; j !== m; ++j) {
  27160. interpolants[j].evaluate(clipTime);
  27161. propertyMixers[j].accumulate(accuIndex, weight);
  27162. }
  27163. }
  27164. }
  27165. }
  27166. _updateWeight(time) {
  27167. let weight = 0;
  27168. if (this.enabled) {
  27169. weight = this.weight;
  27170. const interpolant = this._weightInterpolant;
  27171. if (interpolant !== null) {
  27172. const interpolantValue = interpolant.evaluate(time)[0];
  27173. weight *= interpolantValue;
  27174. if (time > interpolant.parameterPositions[1]) {
  27175. this.stopFading();
  27176. if (interpolantValue === 0) {
  27177. // faded out, disable
  27178. this.enabled = false;
  27179. }
  27180. }
  27181. }
  27182. }
  27183. this._effectiveWeight = weight;
  27184. return weight;
  27185. }
  27186. _updateTimeScale(time) {
  27187. let timeScale = 0;
  27188. if (!this.paused) {
  27189. timeScale = this.timeScale;
  27190. const interpolant = this._timeScaleInterpolant;
  27191. if (interpolant !== null) {
  27192. const interpolantValue = interpolant.evaluate(time)[0];
  27193. timeScale *= interpolantValue;
  27194. if (time > interpolant.parameterPositions[1]) {
  27195. this.stopWarping();
  27196. if (timeScale === 0) {
  27197. // motion has halted, pause
  27198. this.paused = true;
  27199. } else {
  27200. // warp done - apply final time scale
  27201. this.timeScale = timeScale;
  27202. }
  27203. }
  27204. }
  27205. }
  27206. this._effectiveTimeScale = timeScale;
  27207. return timeScale;
  27208. }
  27209. _updateTime(deltaTime) {
  27210. const duration = this._clip.duration;
  27211. const loop = this.loop;
  27212. let time = this.time + deltaTime;
  27213. let loopCount = this._loopCount;
  27214. const pingPong = loop === LoopPingPong;
  27215. if (deltaTime === 0) {
  27216. if (loopCount === -1) return time;
  27217. return pingPong && (loopCount & 1) === 1 ? duration - time : time;
  27218. }
  27219. if (loop === LoopOnce) {
  27220. if (loopCount === -1) {
  27221. // just started
  27222. this._loopCount = 0;
  27223. this._setEndings(true, true, false);
  27224. }
  27225. handle_stop: {
  27226. if (time >= duration) {
  27227. time = duration;
  27228. } else if (time < 0) {
  27229. time = 0;
  27230. } else {
  27231. this.time = time;
  27232. break handle_stop;
  27233. }
  27234. if (this.clampWhenFinished) this.paused = true;else this.enabled = false;
  27235. this.time = time;
  27236. this._mixer.dispatchEvent({
  27237. type: 'finished',
  27238. action: this,
  27239. direction: deltaTime < 0 ? -1 : 1
  27240. });
  27241. }
  27242. } else {
  27243. // repetitive Repeat or PingPong
  27244. if (loopCount === -1) {
  27245. // just started
  27246. if (deltaTime >= 0) {
  27247. loopCount = 0;
  27248. this._setEndings(true, this.repetitions === 0, pingPong);
  27249. } else {
  27250. // when looping in reverse direction, the initial
  27251. // transition through zero counts as a repetition,
  27252. // so leave loopCount at -1
  27253. this._setEndings(this.repetitions === 0, true, pingPong);
  27254. }
  27255. }
  27256. if (time >= duration || time < 0) {
  27257. // wrap around
  27258. const loopDelta = Math.floor(time / duration); // signed
  27259. time -= duration * loopDelta;
  27260. loopCount += Math.abs(loopDelta);
  27261. const pending = this.repetitions - loopCount;
  27262. if (pending <= 0) {
  27263. // have to stop (switch state, clamp time, fire event)
  27264. if (this.clampWhenFinished) this.paused = true;else this.enabled = false;
  27265. time = deltaTime > 0 ? duration : 0;
  27266. this.time = time;
  27267. this._mixer.dispatchEvent({
  27268. type: 'finished',
  27269. action: this,
  27270. direction: deltaTime > 0 ? 1 : -1
  27271. });
  27272. } else {
  27273. // keep running
  27274. if (pending === 1) {
  27275. // entering the last round
  27276. const atStart = deltaTime < 0;
  27277. this._setEndings(atStart, !atStart, pingPong);
  27278. } else {
  27279. this._setEndings(false, false, pingPong);
  27280. }
  27281. this._loopCount = loopCount;
  27282. this.time = time;
  27283. this._mixer.dispatchEvent({
  27284. type: 'loop',
  27285. action: this,
  27286. loopDelta: loopDelta
  27287. });
  27288. }
  27289. } else {
  27290. this.time = time;
  27291. }
  27292. if (pingPong && (loopCount & 1) === 1) {
  27293. // invert time for the "pong round"
  27294. return duration - time;
  27295. }
  27296. }
  27297. return time;
  27298. }
  27299. _setEndings(atStart, atEnd, pingPong) {
  27300. const settings = this._interpolantSettings;
  27301. if (pingPong) {
  27302. settings.endingStart = ZeroSlopeEnding;
  27303. settings.endingEnd = ZeroSlopeEnding;
  27304. } else {
  27305. // assuming for LoopOnce atStart == atEnd == true
  27306. if (atStart) {
  27307. settings.endingStart = this.zeroSlopeAtStart ? ZeroSlopeEnding : ZeroCurvatureEnding;
  27308. } else {
  27309. settings.endingStart = WrapAroundEnding;
  27310. }
  27311. if (atEnd) {
  27312. settings.endingEnd = this.zeroSlopeAtEnd ? ZeroSlopeEnding : ZeroCurvatureEnding;
  27313. } else {
  27314. settings.endingEnd = WrapAroundEnding;
  27315. }
  27316. }
  27317. }
  27318. _scheduleFading(duration, weightNow, weightThen) {
  27319. const mixer = this._mixer,
  27320. now = mixer.time;
  27321. let interpolant = this._weightInterpolant;
  27322. if (interpolant === null) {
  27323. interpolant = mixer._lendControlInterpolant();
  27324. this._weightInterpolant = interpolant;
  27325. }
  27326. const times = interpolant.parameterPositions,
  27327. values = interpolant.sampleValues;
  27328. times[0] = now;
  27329. values[0] = weightNow;
  27330. times[1] = now + duration;
  27331. values[1] = weightThen;
  27332. return this;
  27333. }
  27334. }
  27335. const _controlInterpolantsResultBuffer = new Float32Array(1);
  27336. class AnimationMixer extends EventDispatcher {
  27337. constructor(root) {
  27338. super();
  27339. this._root = root;
  27340. this._initMemoryManager();
  27341. this._accuIndex = 0;
  27342. this.time = 0;
  27343. this.timeScale = 1.0;
  27344. }
  27345. _bindAction(action, prototypeAction) {
  27346. const root = action._localRoot || this._root,
  27347. tracks = action._clip.tracks,
  27348. nTracks = tracks.length,
  27349. bindings = action._propertyBindings,
  27350. interpolants = action._interpolants,
  27351. rootUuid = root.uuid,
  27352. bindingsByRoot = this._bindingsByRootAndName;
  27353. let bindingsByName = bindingsByRoot[rootUuid];
  27354. if (bindingsByName === undefined) {
  27355. bindingsByName = {};
  27356. bindingsByRoot[rootUuid] = bindingsByName;
  27357. }
  27358. for (let i = 0; i !== nTracks; ++i) {
  27359. const track = tracks[i],
  27360. trackName = track.name;
  27361. let binding = bindingsByName[trackName];
  27362. if (binding !== undefined) {
  27363. ++binding.referenceCount;
  27364. bindings[i] = binding;
  27365. } else {
  27366. binding = bindings[i];
  27367. if (binding !== undefined) {
  27368. // existing binding, make sure the cache knows
  27369. if (binding._cacheIndex === null) {
  27370. ++binding.referenceCount;
  27371. this._addInactiveBinding(binding, rootUuid, trackName);
  27372. }
  27373. continue;
  27374. }
  27375. const path = prototypeAction && prototypeAction._propertyBindings[i].binding.parsedPath;
  27376. binding = new PropertyMixer(PropertyBinding.create(root, trackName, path), track.ValueTypeName, track.getValueSize());
  27377. ++binding.referenceCount;
  27378. this._addInactiveBinding(binding, rootUuid, trackName);
  27379. bindings[i] = binding;
  27380. }
  27381. interpolants[i].resultBuffer = binding.buffer;
  27382. }
  27383. }
  27384. _activateAction(action) {
  27385. if (!this._isActiveAction(action)) {
  27386. if (action._cacheIndex === null) {
  27387. // this action has been forgotten by the cache, but the user
  27388. // appears to be still using it -> rebind
  27389. const rootUuid = (action._localRoot || this._root).uuid,
  27390. clipUuid = action._clip.uuid,
  27391. actionsForClip = this._actionsByClip[clipUuid];
  27392. this._bindAction(action, actionsForClip && actionsForClip.knownActions[0]);
  27393. this._addInactiveAction(action, clipUuid, rootUuid);
  27394. }
  27395. const bindings = action._propertyBindings; // increment reference counts / sort out state
  27396. for (let i = 0, n = bindings.length; i !== n; ++i) {
  27397. const binding = bindings[i];
  27398. if (binding.useCount++ === 0) {
  27399. this._lendBinding(binding);
  27400. binding.saveOriginalState();
  27401. }
  27402. }
  27403. this._lendAction(action);
  27404. }
  27405. }
  27406. _deactivateAction(action) {
  27407. if (this._isActiveAction(action)) {
  27408. const bindings = action._propertyBindings; // decrement reference counts / sort out state
  27409. for (let i = 0, n = bindings.length; i !== n; ++i) {
  27410. const binding = bindings[i];
  27411. if (--binding.useCount === 0) {
  27412. binding.restoreOriginalState();
  27413. this._takeBackBinding(binding);
  27414. }
  27415. }
  27416. this._takeBackAction(action);
  27417. }
  27418. } // Memory manager
  27419. _initMemoryManager() {
  27420. this._actions = []; // 'nActiveActions' followed by inactive ones
  27421. this._nActiveActions = 0;
  27422. this._actionsByClip = {}; // inside:
  27423. // {
  27424. // knownActions: Array< AnimationAction > - used as prototypes
  27425. // actionByRoot: AnimationAction - lookup
  27426. // }
  27427. this._bindings = []; // 'nActiveBindings' followed by inactive ones
  27428. this._nActiveBindings = 0;
  27429. this._bindingsByRootAndName = {}; // inside: Map< name, PropertyMixer >
  27430. this._controlInterpolants = []; // same game as above
  27431. this._nActiveControlInterpolants = 0;
  27432. const scope = this;
  27433. this.stats = {
  27434. actions: {
  27435. get total() {
  27436. return scope._actions.length;
  27437. },
  27438. get inUse() {
  27439. return scope._nActiveActions;
  27440. }
  27441. },
  27442. bindings: {
  27443. get total() {
  27444. return scope._bindings.length;
  27445. },
  27446. get inUse() {
  27447. return scope._nActiveBindings;
  27448. }
  27449. },
  27450. controlInterpolants: {
  27451. get total() {
  27452. return scope._controlInterpolants.length;
  27453. },
  27454. get inUse() {
  27455. return scope._nActiveControlInterpolants;
  27456. }
  27457. }
  27458. };
  27459. } // Memory management for AnimationAction objects
  27460. _isActiveAction(action) {
  27461. const index = action._cacheIndex;
  27462. return index !== null && index < this._nActiveActions;
  27463. }
  27464. _addInactiveAction(action, clipUuid, rootUuid) {
  27465. const actions = this._actions,
  27466. actionsByClip = this._actionsByClip;
  27467. let actionsForClip = actionsByClip[clipUuid];
  27468. if (actionsForClip === undefined) {
  27469. actionsForClip = {
  27470. knownActions: [action],
  27471. actionByRoot: {}
  27472. };
  27473. action._byClipCacheIndex = 0;
  27474. actionsByClip[clipUuid] = actionsForClip;
  27475. } else {
  27476. const knownActions = actionsForClip.knownActions;
  27477. action._byClipCacheIndex = knownActions.length;
  27478. knownActions.push(action);
  27479. }
  27480. action._cacheIndex = actions.length;
  27481. actions.push(action);
  27482. actionsForClip.actionByRoot[rootUuid] = action;
  27483. }
  27484. _removeInactiveAction(action) {
  27485. const actions = this._actions,
  27486. lastInactiveAction = actions[actions.length - 1],
  27487. cacheIndex = action._cacheIndex;
  27488. lastInactiveAction._cacheIndex = cacheIndex;
  27489. actions[cacheIndex] = lastInactiveAction;
  27490. actions.pop();
  27491. action._cacheIndex = null;
  27492. const clipUuid = action._clip.uuid,
  27493. actionsByClip = this._actionsByClip,
  27494. actionsForClip = actionsByClip[clipUuid],
  27495. knownActionsForClip = actionsForClip.knownActions,
  27496. lastKnownAction = knownActionsForClip[knownActionsForClip.length - 1],
  27497. byClipCacheIndex = action._byClipCacheIndex;
  27498. lastKnownAction._byClipCacheIndex = byClipCacheIndex;
  27499. knownActionsForClip[byClipCacheIndex] = lastKnownAction;
  27500. knownActionsForClip.pop();
  27501. action._byClipCacheIndex = null;
  27502. const actionByRoot = actionsForClip.actionByRoot,
  27503. rootUuid = (action._localRoot || this._root).uuid;
  27504. delete actionByRoot[rootUuid];
  27505. if (knownActionsForClip.length === 0) {
  27506. delete actionsByClip[clipUuid];
  27507. }
  27508. this._removeInactiveBindingsForAction(action);
  27509. }
  27510. _removeInactiveBindingsForAction(action) {
  27511. const bindings = action._propertyBindings;
  27512. for (let i = 0, n = bindings.length; i !== n; ++i) {
  27513. const binding = bindings[i];
  27514. if (--binding.referenceCount === 0) {
  27515. this._removeInactiveBinding(binding);
  27516. }
  27517. }
  27518. }
  27519. _lendAction(action) {
  27520. // [ active actions | inactive actions ]
  27521. // [ active actions >| inactive actions ]
  27522. // s a
  27523. // <-swap->
  27524. // a s
  27525. const actions = this._actions,
  27526. prevIndex = action._cacheIndex,
  27527. lastActiveIndex = this._nActiveActions++,
  27528. firstInactiveAction = actions[lastActiveIndex];
  27529. action._cacheIndex = lastActiveIndex;
  27530. actions[lastActiveIndex] = action;
  27531. firstInactiveAction._cacheIndex = prevIndex;
  27532. actions[prevIndex] = firstInactiveAction;
  27533. }
  27534. _takeBackAction(action) {
  27535. // [ active actions | inactive actions ]
  27536. // [ active actions |< inactive actions ]
  27537. // a s
  27538. // <-swap->
  27539. // s a
  27540. const actions = this._actions,
  27541. prevIndex = action._cacheIndex,
  27542. firstInactiveIndex = --this._nActiveActions,
  27543. lastActiveAction = actions[firstInactiveIndex];
  27544. action._cacheIndex = firstInactiveIndex;
  27545. actions[firstInactiveIndex] = action;
  27546. lastActiveAction._cacheIndex = prevIndex;
  27547. actions[prevIndex] = lastActiveAction;
  27548. } // Memory management for PropertyMixer objects
  27549. _addInactiveBinding(binding, rootUuid, trackName) {
  27550. const bindingsByRoot = this._bindingsByRootAndName,
  27551. bindings = this._bindings;
  27552. let bindingByName = bindingsByRoot[rootUuid];
  27553. if (bindingByName === undefined) {
  27554. bindingByName = {};
  27555. bindingsByRoot[rootUuid] = bindingByName;
  27556. }
  27557. bindingByName[trackName] = binding;
  27558. binding._cacheIndex = bindings.length;
  27559. bindings.push(binding);
  27560. }
  27561. _removeInactiveBinding(binding) {
  27562. const bindings = this._bindings,
  27563. propBinding = binding.binding,
  27564. rootUuid = propBinding.rootNode.uuid,
  27565. trackName = propBinding.path,
  27566. bindingsByRoot = this._bindingsByRootAndName,
  27567. bindingByName = bindingsByRoot[rootUuid],
  27568. lastInactiveBinding = bindings[bindings.length - 1],
  27569. cacheIndex = binding._cacheIndex;
  27570. lastInactiveBinding._cacheIndex = cacheIndex;
  27571. bindings[cacheIndex] = lastInactiveBinding;
  27572. bindings.pop();
  27573. delete bindingByName[trackName];
  27574. if (Object.keys(bindingByName).length === 0) {
  27575. delete bindingsByRoot[rootUuid];
  27576. }
  27577. }
  27578. _lendBinding(binding) {
  27579. const bindings = this._bindings,
  27580. prevIndex = binding._cacheIndex,
  27581. lastActiveIndex = this._nActiveBindings++,
  27582. firstInactiveBinding = bindings[lastActiveIndex];
  27583. binding._cacheIndex = lastActiveIndex;
  27584. bindings[lastActiveIndex] = binding;
  27585. firstInactiveBinding._cacheIndex = prevIndex;
  27586. bindings[prevIndex] = firstInactiveBinding;
  27587. }
  27588. _takeBackBinding(binding) {
  27589. const bindings = this._bindings,
  27590. prevIndex = binding._cacheIndex,
  27591. firstInactiveIndex = --this._nActiveBindings,
  27592. lastActiveBinding = bindings[firstInactiveIndex];
  27593. binding._cacheIndex = firstInactiveIndex;
  27594. bindings[firstInactiveIndex] = binding;
  27595. lastActiveBinding._cacheIndex = prevIndex;
  27596. bindings[prevIndex] = lastActiveBinding;
  27597. } // Memory management of Interpolants for weight and time scale
  27598. _lendControlInterpolant() {
  27599. const interpolants = this._controlInterpolants,
  27600. lastActiveIndex = this._nActiveControlInterpolants++;
  27601. let interpolant = interpolants[lastActiveIndex];
  27602. if (interpolant === undefined) {
  27603. interpolant = new LinearInterpolant(new Float32Array(2), new Float32Array(2), 1, _controlInterpolantsResultBuffer);
  27604. interpolant.__cacheIndex = lastActiveIndex;
  27605. interpolants[lastActiveIndex] = interpolant;
  27606. }
  27607. return interpolant;
  27608. }
  27609. _takeBackControlInterpolant(interpolant) {
  27610. const interpolants = this._controlInterpolants,
  27611. prevIndex = interpolant.__cacheIndex,
  27612. firstInactiveIndex = --this._nActiveControlInterpolants,
  27613. lastActiveInterpolant = interpolants[firstInactiveIndex];
  27614. interpolant.__cacheIndex = firstInactiveIndex;
  27615. interpolants[firstInactiveIndex] = interpolant;
  27616. lastActiveInterpolant.__cacheIndex = prevIndex;
  27617. interpolants[prevIndex] = lastActiveInterpolant;
  27618. } // return an action for a clip optionally using a custom root target
  27619. // object (this method allocates a lot of dynamic memory in case a
  27620. // previously unknown clip/root combination is specified)
  27621. clipAction(clip, optionalRoot, blendMode) {
  27622. const root = optionalRoot || this._root,
  27623. rootUuid = root.uuid;
  27624. let clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip;
  27625. const clipUuid = clipObject !== null ? clipObject.uuid : clip;
  27626. const actionsForClip = this._actionsByClip[clipUuid];
  27627. let prototypeAction = null;
  27628. if (blendMode === undefined) {
  27629. if (clipObject !== null) {
  27630. blendMode = clipObject.blendMode;
  27631. } else {
  27632. blendMode = NormalAnimationBlendMode;
  27633. }
  27634. }
  27635. if (actionsForClip !== undefined) {
  27636. const existingAction = actionsForClip.actionByRoot[rootUuid];
  27637. if (existingAction !== undefined && existingAction.blendMode === blendMode) {
  27638. return existingAction;
  27639. } // we know the clip, so we don't have to parse all
  27640. // the bindings again but can just copy
  27641. prototypeAction = actionsForClip.knownActions[0]; // also, take the clip from the prototype action
  27642. if (clipObject === null) clipObject = prototypeAction._clip;
  27643. } // clip must be known when specified via string
  27644. if (clipObject === null) return null; // allocate all resources required to run it
  27645. const newAction = new AnimationAction(this, clipObject, optionalRoot, blendMode);
  27646. this._bindAction(newAction, prototypeAction); // and make the action known to the memory manager
  27647. this._addInactiveAction(newAction, clipUuid, rootUuid);
  27648. return newAction;
  27649. } // get an existing action
  27650. existingAction(clip, optionalRoot) {
  27651. const root = optionalRoot || this._root,
  27652. rootUuid = root.uuid,
  27653. clipObject = typeof clip === 'string' ? AnimationClip.findByName(root, clip) : clip,
  27654. clipUuid = clipObject ? clipObject.uuid : clip,
  27655. actionsForClip = this._actionsByClip[clipUuid];
  27656. if (actionsForClip !== undefined) {
  27657. return actionsForClip.actionByRoot[rootUuid] || null;
  27658. }
  27659. return null;
  27660. } // deactivates all previously scheduled actions
  27661. stopAllAction() {
  27662. const actions = this._actions,
  27663. nActions = this._nActiveActions;
  27664. for (let i = nActions - 1; i >= 0; --i) {
  27665. actions[i].stop();
  27666. }
  27667. return this;
  27668. } // advance the time and update apply the animation
  27669. update(deltaTime) {
  27670. deltaTime *= this.timeScale;
  27671. const actions = this._actions,
  27672. nActions = this._nActiveActions,
  27673. time = this.time += deltaTime,
  27674. timeDirection = Math.sign(deltaTime),
  27675. accuIndex = this._accuIndex ^= 1; // run active actions
  27676. for (let i = 0; i !== nActions; ++i) {
  27677. const action = actions[i];
  27678. action._update(time, deltaTime, timeDirection, accuIndex);
  27679. } // update scene graph
  27680. const bindings = this._bindings,
  27681. nBindings = this._nActiveBindings;
  27682. for (let i = 0; i !== nBindings; ++i) {
  27683. bindings[i].apply(accuIndex);
  27684. }
  27685. return this;
  27686. } // Allows you to seek to a specific time in an animation.
  27687. setTime(timeInSeconds) {
  27688. this.time = 0; // Zero out time attribute for AnimationMixer object;
  27689. for (let i = 0; i < this._actions.length; i++) {
  27690. this._actions[i].time = 0; // Zero out time attribute for all associated AnimationAction objects.
  27691. }
  27692. return this.update(timeInSeconds); // Update used to set exact time. Returns "this" AnimationMixer object.
  27693. } // return this mixer's root target object
  27694. getRoot() {
  27695. return this._root;
  27696. } // free all resources specific to a particular clip
  27697. uncacheClip(clip) {
  27698. const actions = this._actions,
  27699. clipUuid = clip.uuid,
  27700. actionsByClip = this._actionsByClip,
  27701. actionsForClip = actionsByClip[clipUuid];
  27702. if (actionsForClip !== undefined) {
  27703. // note: just calling _removeInactiveAction would mess up the
  27704. // iteration state and also require updating the state we can
  27705. // just throw away
  27706. const actionsToRemove = actionsForClip.knownActions;
  27707. for (let i = 0, n = actionsToRemove.length; i !== n; ++i) {
  27708. const action = actionsToRemove[i];
  27709. this._deactivateAction(action);
  27710. const cacheIndex = action._cacheIndex,
  27711. lastInactiveAction = actions[actions.length - 1];
  27712. action._cacheIndex = null;
  27713. action._byClipCacheIndex = null;
  27714. lastInactiveAction._cacheIndex = cacheIndex;
  27715. actions[cacheIndex] = lastInactiveAction;
  27716. actions.pop();
  27717. this._removeInactiveBindingsForAction(action);
  27718. }
  27719. delete actionsByClip[clipUuid];
  27720. }
  27721. } // free all resources specific to a particular root target object
  27722. uncacheRoot(root) {
  27723. const rootUuid = root.uuid,
  27724. actionsByClip = this._actionsByClip;
  27725. for (const clipUuid in actionsByClip) {
  27726. const actionByRoot = actionsByClip[clipUuid].actionByRoot,
  27727. action = actionByRoot[rootUuid];
  27728. if (action !== undefined) {
  27729. this._deactivateAction(action);
  27730. this._removeInactiveAction(action);
  27731. }
  27732. }
  27733. const bindingsByRoot = this._bindingsByRootAndName,
  27734. bindingByName = bindingsByRoot[rootUuid];
  27735. if (bindingByName !== undefined) {
  27736. for (const trackName in bindingByName) {
  27737. const binding = bindingByName[trackName];
  27738. binding.restoreOriginalState();
  27739. this._removeInactiveBinding(binding);
  27740. }
  27741. }
  27742. } // remove a targeted clip from the cache
  27743. uncacheAction(clip, optionalRoot) {
  27744. const action = this.existingAction(clip, optionalRoot);
  27745. if (action !== null) {
  27746. this._deactivateAction(action);
  27747. this._removeInactiveAction(action);
  27748. }
  27749. }
  27750. }
  27751. class Uniform {
  27752. constructor(value) {
  27753. if (typeof value === 'string') {
  27754. console.warn('THREE.Uniform: Type parameter is no longer needed.');
  27755. value = arguments[1];
  27756. }
  27757. this.value = value;
  27758. }
  27759. clone() {
  27760. return new Uniform(this.value.clone === undefined ? this.value : this.value.clone());
  27761. }
  27762. }
  27763. let id = 0;
  27764. class UniformsGroup extends EventDispatcher {
  27765. constructor() {
  27766. super();
  27767. this.isUniformsGroup = true;
  27768. Object.defineProperty(this, 'id', {
  27769. value: id++
  27770. });
  27771. this.name = '';
  27772. this.usage = StaticDrawUsage;
  27773. this.uniforms = [];
  27774. }
  27775. add(uniform) {
  27776. this.uniforms.push(uniform);
  27777. return this;
  27778. }
  27779. remove(uniform) {
  27780. const index = this.uniforms.indexOf(uniform);
  27781. if (index !== -1) this.uniforms.splice(index, 1);
  27782. return this;
  27783. }
  27784. setName(name) {
  27785. this.name = name;
  27786. return this;
  27787. }
  27788. setUsage(value) {
  27789. this.usage = value;
  27790. return this;
  27791. }
  27792. dispose() {
  27793. this.dispatchEvent({
  27794. type: 'dispose'
  27795. });
  27796. return this;
  27797. }
  27798. copy(source) {
  27799. this.name = source.name;
  27800. this.usage = source.usage;
  27801. const uniformsSource = source.uniforms;
  27802. this.uniforms.length = 0;
  27803. for (let i = 0, l = uniformsSource.length; i < l; i++) {
  27804. this.uniforms.push(uniformsSource[i].clone());
  27805. }
  27806. return this;
  27807. }
  27808. clone() {
  27809. return new this.constructor().copy(this);
  27810. }
  27811. }
  27812. class InstancedInterleavedBuffer extends InterleavedBuffer {
  27813. constructor(array, stride, meshPerAttribute = 1) {
  27814. super(array, stride);
  27815. this.isInstancedInterleavedBuffer = true;
  27816. this.meshPerAttribute = meshPerAttribute;
  27817. }
  27818. copy(source) {
  27819. super.copy(source);
  27820. this.meshPerAttribute = source.meshPerAttribute;
  27821. return this;
  27822. }
  27823. clone(data) {
  27824. const ib = super.clone(data);
  27825. ib.meshPerAttribute = this.meshPerAttribute;
  27826. return ib;
  27827. }
  27828. toJSON(data) {
  27829. const json = super.toJSON(data);
  27830. json.isInstancedInterleavedBuffer = true;
  27831. json.meshPerAttribute = this.meshPerAttribute;
  27832. return json;
  27833. }
  27834. }
  27835. class GLBufferAttribute {
  27836. constructor(buffer, type, itemSize, elementSize, count) {
  27837. this.isGLBufferAttribute = true;
  27838. this.buffer = buffer;
  27839. this.type = type;
  27840. this.itemSize = itemSize;
  27841. this.elementSize = elementSize;
  27842. this.count = count;
  27843. this.version = 0;
  27844. }
  27845. set needsUpdate(value) {
  27846. if (value === true) this.version++;
  27847. }
  27848. setBuffer(buffer) {
  27849. this.buffer = buffer;
  27850. return this;
  27851. }
  27852. setType(type, elementSize) {
  27853. this.type = type;
  27854. this.elementSize = elementSize;
  27855. return this;
  27856. }
  27857. setItemSize(itemSize) {
  27858. this.itemSize = itemSize;
  27859. return this;
  27860. }
  27861. setCount(count) {
  27862. this.count = count;
  27863. return this;
  27864. }
  27865. }
  27866. class Raycaster {
  27867. constructor(origin, direction, near = 0, far = Infinity) {
  27868. this.ray = new Ray(origin, direction); // direction is assumed to be normalized (for accurate distance calculations)
  27869. this.near = near;
  27870. this.far = far;
  27871. this.camera = null;
  27872. this.layers = new Layers();
  27873. this.params = {
  27874. Mesh: {},
  27875. Line: {
  27876. threshold: 1
  27877. },
  27878. LOD: {},
  27879. Points: {
  27880. threshold: 1
  27881. },
  27882. Sprite: {}
  27883. };
  27884. }
  27885. set(origin, direction) {
  27886. // direction is assumed to be normalized (for accurate distance calculations)
  27887. this.ray.set(origin, direction);
  27888. }
  27889. setFromCamera(coords, camera) {
  27890. if (camera.isPerspectiveCamera) {
  27891. this.ray.origin.setFromMatrixPosition(camera.matrixWorld);
  27892. this.ray.direction.set(coords.x, coords.y, 0.5).unproject(camera).sub(this.ray.origin).normalize();
  27893. this.camera = camera;
  27894. } else if (camera.isOrthographicCamera) {
  27895. this.ray.origin.set(coords.x, coords.y, (camera.near + camera.far) / (camera.near - camera.far)).unproject(camera); // set origin in plane of camera
  27896. this.ray.direction.set(0, 0, -1).transformDirection(camera.matrixWorld);
  27897. this.camera = camera;
  27898. } else {
  27899. console.error('THREE.Raycaster: Unsupported camera type: ' + camera.type);
  27900. }
  27901. }
  27902. intersectObject(object, recursive = true, intersects = []) {
  27903. intersectObject(object, this, intersects, recursive);
  27904. intersects.sort(ascSort);
  27905. return intersects;
  27906. }
  27907. intersectObjects(objects, recursive = true, intersects = []) {
  27908. for (let i = 0, l = objects.length; i < l; i++) {
  27909. intersectObject(objects[i], this, intersects, recursive);
  27910. }
  27911. intersects.sort(ascSort);
  27912. return intersects;
  27913. }
  27914. }
  27915. function ascSort(a, b) {
  27916. return a.distance - b.distance;
  27917. }
  27918. function intersectObject(object, raycaster, intersects, recursive) {
  27919. if (object.layers.test(raycaster.layers)) {
  27920. object.raycast(raycaster, intersects);
  27921. }
  27922. if (recursive === true) {
  27923. const children = object.children;
  27924. for (let i = 0, l = children.length; i < l; i++) {
  27925. intersectObject(children[i], raycaster, intersects, true);
  27926. }
  27927. }
  27928. }
  27929. /**
  27930. * Ref: https://en.wikipedia.org/wiki/Spherical_coordinate_system
  27931. *
  27932. * The polar angle (phi) is measured from the positive y-axis. The positive y-axis is up.
  27933. * The azimuthal angle (theta) is measured from the positive z-axis.
  27934. */
  27935. class Spherical {
  27936. constructor(radius = 1, phi = 0, theta = 0) {
  27937. this.radius = radius;
  27938. this.phi = phi; // polar angle
  27939. this.theta = theta; // azimuthal angle
  27940. return this;
  27941. }
  27942. set(radius, phi, theta) {
  27943. this.radius = radius;
  27944. this.phi = phi;
  27945. this.theta = theta;
  27946. return this;
  27947. }
  27948. copy(other) {
  27949. this.radius = other.radius;
  27950. this.phi = other.phi;
  27951. this.theta = other.theta;
  27952. return this;
  27953. } // restrict phi to be between EPS and PI-EPS
  27954. makeSafe() {
  27955. const EPS = 0.000001;
  27956. this.phi = Math.max(EPS, Math.min(Math.PI - EPS, this.phi));
  27957. return this;
  27958. }
  27959. setFromVector3(v) {
  27960. return this.setFromCartesianCoords(v.x, v.y, v.z);
  27961. }
  27962. setFromCartesianCoords(x, y, z) {
  27963. this.radius = Math.sqrt(x * x + y * y + z * z);
  27964. if (this.radius === 0) {
  27965. this.theta = 0;
  27966. this.phi = 0;
  27967. } else {
  27968. this.theta = Math.atan2(x, z);
  27969. this.phi = Math.acos(clamp(y / this.radius, -1, 1));
  27970. }
  27971. return this;
  27972. }
  27973. clone() {
  27974. return new this.constructor().copy(this);
  27975. }
  27976. }
  27977. /**
  27978. * Ref: https://en.wikipedia.org/wiki/Cylindrical_coordinate_system
  27979. */
  27980. class Cylindrical {
  27981. constructor(radius = 1, theta = 0, y = 0) {
  27982. this.radius = radius; // distance from the origin to a point in the x-z plane
  27983. this.theta = theta; // counterclockwise angle in the x-z plane measured in radians from the positive z-axis
  27984. this.y = y; // height above the x-z plane
  27985. return this;
  27986. }
  27987. set(radius, theta, y) {
  27988. this.radius = radius;
  27989. this.theta = theta;
  27990. this.y = y;
  27991. return this;
  27992. }
  27993. copy(other) {
  27994. this.radius = other.radius;
  27995. this.theta = other.theta;
  27996. this.y = other.y;
  27997. return this;
  27998. }
  27999. setFromVector3(v) {
  28000. return this.setFromCartesianCoords(v.x, v.y, v.z);
  28001. }
  28002. setFromCartesianCoords(x, y, z) {
  28003. this.radius = Math.sqrt(x * x + z * z);
  28004. this.theta = Math.atan2(x, z);
  28005. this.y = y;
  28006. return this;
  28007. }
  28008. clone() {
  28009. return new this.constructor().copy(this);
  28010. }
  28011. }
  28012. const _vector$4 = /*@__PURE__*/new Vector2();
  28013. class Box2 {
  28014. constructor(min = new Vector2(+Infinity, +Infinity), max = new Vector2(-Infinity, -Infinity)) {
  28015. this.isBox2 = true;
  28016. this.min = min;
  28017. this.max = max;
  28018. }
  28019. set(min, max) {
  28020. this.min.copy(min);
  28021. this.max.copy(max);
  28022. return this;
  28023. }
  28024. setFromPoints(points) {
  28025. this.makeEmpty();
  28026. for (let i = 0, il = points.length; i < il; i++) {
  28027. this.expandByPoint(points[i]);
  28028. }
  28029. return this;
  28030. }
  28031. setFromCenterAndSize(center, size) {
  28032. const halfSize = _vector$4.copy(size).multiplyScalar(0.5);
  28033. this.min.copy(center).sub(halfSize);
  28034. this.max.copy(center).add(halfSize);
  28035. return this;
  28036. }
  28037. clone() {
  28038. return new this.constructor().copy(this);
  28039. }
  28040. copy(box) {
  28041. this.min.copy(box.min);
  28042. this.max.copy(box.max);
  28043. return this;
  28044. }
  28045. makeEmpty() {
  28046. this.min.x = this.min.y = +Infinity;
  28047. this.max.x = this.max.y = -Infinity;
  28048. return this;
  28049. }
  28050. isEmpty() {
  28051. // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes
  28052. return this.max.x < this.min.x || this.max.y < this.min.y;
  28053. }
  28054. getCenter(target) {
  28055. return this.isEmpty() ? target.set(0, 0) : target.addVectors(this.min, this.max).multiplyScalar(0.5);
  28056. }
  28057. getSize(target) {
  28058. return this.isEmpty() ? target.set(0, 0) : target.subVectors(this.max, this.min);
  28059. }
  28060. expandByPoint(point) {
  28061. this.min.min(point);
  28062. this.max.max(point);
  28063. return this;
  28064. }
  28065. expandByVector(vector) {
  28066. this.min.sub(vector);
  28067. this.max.add(vector);
  28068. return this;
  28069. }
  28070. expandByScalar(scalar) {
  28071. this.min.addScalar(-scalar);
  28072. this.max.addScalar(scalar);
  28073. return this;
  28074. }
  28075. containsPoint(point) {
  28076. return point.x < this.min.x || point.x > this.max.x || point.y < this.min.y || point.y > this.max.y ? false : true;
  28077. }
  28078. containsBox(box) {
  28079. return this.min.x <= box.min.x && box.max.x <= this.max.x && this.min.y <= box.min.y && box.max.y <= this.max.y;
  28080. }
  28081. getParameter(point, target) {
  28082. // This can potentially have a divide by zero if the box
  28083. // has a size dimension of 0.
  28084. return target.set((point.x - this.min.x) / (this.max.x - this.min.x), (point.y - this.min.y) / (this.max.y - this.min.y));
  28085. }
  28086. intersectsBox(box) {
  28087. // using 4 splitting planes to rule out intersections
  28088. return box.max.x < this.min.x || box.min.x > this.max.x || box.max.y < this.min.y || box.min.y > this.max.y ? false : true;
  28089. }
  28090. clampPoint(point, target) {
  28091. return target.copy(point).clamp(this.min, this.max);
  28092. }
  28093. distanceToPoint(point) {
  28094. const clampedPoint = _vector$4.copy(point).clamp(this.min, this.max);
  28095. return clampedPoint.sub(point).length();
  28096. }
  28097. intersect(box) {
  28098. this.min.max(box.min);
  28099. this.max.min(box.max);
  28100. return this;
  28101. }
  28102. union(box) {
  28103. this.min.min(box.min);
  28104. this.max.max(box.max);
  28105. return this;
  28106. }
  28107. translate(offset) {
  28108. this.min.add(offset);
  28109. this.max.add(offset);
  28110. return this;
  28111. }
  28112. equals(box) {
  28113. return box.min.equals(this.min) && box.max.equals(this.max);
  28114. }
  28115. }
  28116. const _startP = /*@__PURE__*/new Vector3();
  28117. const _startEnd = /*@__PURE__*/new Vector3();
  28118. class Line3 {
  28119. constructor(start = new Vector3(), end = new Vector3()) {
  28120. this.start = start;
  28121. this.end = end;
  28122. }
  28123. set(start, end) {
  28124. this.start.copy(start);
  28125. this.end.copy(end);
  28126. return this;
  28127. }
  28128. copy(line) {
  28129. this.start.copy(line.start);
  28130. this.end.copy(line.end);
  28131. return this;
  28132. }
  28133. getCenter(target) {
  28134. return target.addVectors(this.start, this.end).multiplyScalar(0.5);
  28135. }
  28136. delta(target) {
  28137. return target.subVectors(this.end, this.start);
  28138. }
  28139. distanceSq() {
  28140. return this.start.distanceToSquared(this.end);
  28141. }
  28142. distance() {
  28143. return this.start.distanceTo(this.end);
  28144. }
  28145. at(t, target) {
  28146. return this.delta(target).multiplyScalar(t).add(this.start);
  28147. }
  28148. closestPointToPointParameter(point, clampToLine) {
  28149. _startP.subVectors(point, this.start);
  28150. _startEnd.subVectors(this.end, this.start);
  28151. const startEnd2 = _startEnd.dot(_startEnd);
  28152. const startEnd_startP = _startEnd.dot(_startP);
  28153. let t = startEnd_startP / startEnd2;
  28154. if (clampToLine) {
  28155. t = clamp(t, 0, 1);
  28156. }
  28157. return t;
  28158. }
  28159. closestPointToPoint(point, clampToLine, target) {
  28160. const t = this.closestPointToPointParameter(point, clampToLine);
  28161. return this.delta(target).multiplyScalar(t).add(this.start);
  28162. }
  28163. applyMatrix4(matrix) {
  28164. this.start.applyMatrix4(matrix);
  28165. this.end.applyMatrix4(matrix);
  28166. return this;
  28167. }
  28168. equals(line) {
  28169. return line.start.equals(this.start) && line.end.equals(this.end);
  28170. }
  28171. clone() {
  28172. return new this.constructor().copy(this);
  28173. }
  28174. }
  28175. const _vector$3 = /*@__PURE__*/new Vector3();
  28176. class SpotLightHelper extends Object3D {
  28177. constructor(light, color) {
  28178. super();
  28179. this.light = light;
  28180. this.light.updateMatrixWorld();
  28181. this.matrix = light.matrixWorld;
  28182. this.matrixAutoUpdate = false;
  28183. this.color = color;
  28184. const geometry = new BufferGeometry();
  28185. const positions = [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, -1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, -1, 1];
  28186. for (let i = 0, j = 1, l = 32; i < l; i++, j++) {
  28187. const p1 = i / l * Math.PI * 2;
  28188. const p2 = j / l * Math.PI * 2;
  28189. positions.push(Math.cos(p1), Math.sin(p1), 1, Math.cos(p2), Math.sin(p2), 1);
  28190. }
  28191. geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
  28192. const material = new LineBasicMaterial({
  28193. fog: false,
  28194. toneMapped: false
  28195. });
  28196. this.cone = new LineSegments(geometry, material);
  28197. this.add(this.cone);
  28198. this.update();
  28199. }
  28200. dispose() {
  28201. this.cone.geometry.dispose();
  28202. this.cone.material.dispose();
  28203. }
  28204. update() {
  28205. this.light.updateMatrixWorld();
  28206. const coneLength = this.light.distance ? this.light.distance : 1000;
  28207. const coneWidth = coneLength * Math.tan(this.light.angle);
  28208. this.cone.scale.set(coneWidth, coneWidth, coneLength);
  28209. _vector$3.setFromMatrixPosition(this.light.target.matrixWorld);
  28210. this.cone.lookAt(_vector$3);
  28211. if (this.color !== undefined) {
  28212. this.cone.material.color.set(this.color);
  28213. } else {
  28214. this.cone.material.color.copy(this.light.color);
  28215. }
  28216. }
  28217. }
  28218. const _vector$2 = /*@__PURE__*/new Vector3();
  28219. const _boneMatrix = /*@__PURE__*/new Matrix4();
  28220. const _matrixWorldInv = /*@__PURE__*/new Matrix4();
  28221. class SkeletonHelper extends LineSegments {
  28222. constructor(object) {
  28223. const bones = getBoneList(object);
  28224. const geometry = new BufferGeometry();
  28225. const vertices = [];
  28226. const colors = [];
  28227. const color1 = new Color(0, 0, 1);
  28228. const color2 = new Color(0, 1, 0);
  28229. for (let i = 0; i < bones.length; i++) {
  28230. const bone = bones[i];
  28231. if (bone.parent && bone.parent.isBone) {
  28232. vertices.push(0, 0, 0);
  28233. vertices.push(0, 0, 0);
  28234. colors.push(color1.r, color1.g, color1.b);
  28235. colors.push(color2.r, color2.g, color2.b);
  28236. }
  28237. }
  28238. geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  28239. geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
  28240. const material = new LineBasicMaterial({
  28241. vertexColors: true,
  28242. depthTest: false,
  28243. depthWrite: false,
  28244. toneMapped: false,
  28245. transparent: true
  28246. });
  28247. super(geometry, material);
  28248. this.isSkeletonHelper = true;
  28249. this.type = 'SkeletonHelper';
  28250. this.root = object;
  28251. this.bones = bones;
  28252. this.matrix = object.matrixWorld;
  28253. this.matrixAutoUpdate = false;
  28254. }
  28255. updateMatrixWorld(force) {
  28256. const bones = this.bones;
  28257. const geometry = this.geometry;
  28258. const position = geometry.getAttribute('position');
  28259. _matrixWorldInv.copy(this.root.matrixWorld).invert();
  28260. for (let i = 0, j = 0; i < bones.length; i++) {
  28261. const bone = bones[i];
  28262. if (bone.parent && bone.parent.isBone) {
  28263. _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.matrixWorld);
  28264. _vector$2.setFromMatrixPosition(_boneMatrix);
  28265. position.setXYZ(j, _vector$2.x, _vector$2.y, _vector$2.z);
  28266. _boneMatrix.multiplyMatrices(_matrixWorldInv, bone.parent.matrixWorld);
  28267. _vector$2.setFromMatrixPosition(_boneMatrix);
  28268. position.setXYZ(j + 1, _vector$2.x, _vector$2.y, _vector$2.z);
  28269. j += 2;
  28270. }
  28271. }
  28272. geometry.getAttribute('position').needsUpdate = true;
  28273. super.updateMatrixWorld(force);
  28274. }
  28275. }
  28276. function getBoneList(object) {
  28277. const boneList = [];
  28278. if (object.isBone === true) {
  28279. boneList.push(object);
  28280. }
  28281. for (let i = 0; i < object.children.length; i++) {
  28282. boneList.push.apply(boneList, getBoneList(object.children[i]));
  28283. }
  28284. return boneList;
  28285. }
  28286. class PointLightHelper extends Mesh {
  28287. constructor(light, sphereSize, color) {
  28288. const geometry = new SphereGeometry(sphereSize, 4, 2);
  28289. const material = new MeshBasicMaterial({
  28290. wireframe: true,
  28291. fog: false,
  28292. toneMapped: false
  28293. });
  28294. super(geometry, material);
  28295. this.light = light;
  28296. this.light.updateMatrixWorld();
  28297. this.color = color;
  28298. this.type = 'PointLightHelper';
  28299. this.matrix = this.light.matrixWorld;
  28300. this.matrixAutoUpdate = false;
  28301. this.update();
  28302. /*
  28303. // TODO: delete this comment?
  28304. const distanceGeometry = new THREE.IcosahedronGeometry( 1, 2 );
  28305. const distanceMaterial = new THREE.MeshBasicMaterial( { color: hexColor, fog: false, wireframe: true, opacity: 0.1, transparent: true } );
  28306. this.lightSphere = new THREE.Mesh( bulbGeometry, bulbMaterial );
  28307. this.lightDistance = new THREE.Mesh( distanceGeometry, distanceMaterial );
  28308. const d = light.distance;
  28309. if ( d === 0.0 ) {
  28310. this.lightDistance.visible = false;
  28311. } else {
  28312. this.lightDistance.scale.set( d, d, d );
  28313. }
  28314. this.add( this.lightDistance );
  28315. */
  28316. }
  28317. dispose() {
  28318. this.geometry.dispose();
  28319. this.material.dispose();
  28320. }
  28321. update() {
  28322. if (this.color !== undefined) {
  28323. this.material.color.set(this.color);
  28324. } else {
  28325. this.material.color.copy(this.light.color);
  28326. }
  28327. /*
  28328. const d = this.light.distance;
  28329. if ( d === 0.0 ) {
  28330. this.lightDistance.visible = false;
  28331. } else {
  28332. this.lightDistance.visible = true;
  28333. this.lightDistance.scale.set( d, d, d );
  28334. }
  28335. */
  28336. }
  28337. }
  28338. const _vector$1 = /*@__PURE__*/new Vector3();
  28339. const _color1 = /*@__PURE__*/new Color();
  28340. const _color2 = /*@__PURE__*/new Color();
  28341. class HemisphereLightHelper extends Object3D {
  28342. constructor(light, size, color) {
  28343. super();
  28344. this.light = light;
  28345. this.light.updateMatrixWorld();
  28346. this.matrix = light.matrixWorld;
  28347. this.matrixAutoUpdate = false;
  28348. this.color = color;
  28349. const geometry = new OctahedronGeometry(size);
  28350. geometry.rotateY(Math.PI * 0.5);
  28351. this.material = new MeshBasicMaterial({
  28352. wireframe: true,
  28353. fog: false,
  28354. toneMapped: false
  28355. });
  28356. if (this.color === undefined) this.material.vertexColors = true;
  28357. const position = geometry.getAttribute('position');
  28358. const colors = new Float32Array(position.count * 3);
  28359. geometry.setAttribute('color', new BufferAttribute(colors, 3));
  28360. this.add(new Mesh(geometry, this.material));
  28361. this.update();
  28362. }
  28363. dispose() {
  28364. this.children[0].geometry.dispose();
  28365. this.children[0].material.dispose();
  28366. }
  28367. update() {
  28368. const mesh = this.children[0];
  28369. if (this.color !== undefined) {
  28370. this.material.color.set(this.color);
  28371. } else {
  28372. const colors = mesh.geometry.getAttribute('color');
  28373. _color1.copy(this.light.color);
  28374. _color2.copy(this.light.groundColor);
  28375. for (let i = 0, l = colors.count; i < l; i++) {
  28376. const color = i < l / 2 ? _color1 : _color2;
  28377. colors.setXYZ(i, color.r, color.g, color.b);
  28378. }
  28379. colors.needsUpdate = true;
  28380. }
  28381. mesh.lookAt(_vector$1.setFromMatrixPosition(this.light.matrixWorld).negate());
  28382. }
  28383. }
  28384. class GridHelper extends LineSegments {
  28385. constructor(size = 10, divisions = 10, color1 = 0x444444, color2 = 0x888888) {
  28386. color1 = new Color(color1);
  28387. color2 = new Color(color2);
  28388. const center = divisions / 2;
  28389. const step = size / divisions;
  28390. const halfSize = size / 2;
  28391. const vertices = [],
  28392. colors = [];
  28393. for (let i = 0, j = 0, k = -halfSize; i <= divisions; i++, k += step) {
  28394. vertices.push(-halfSize, 0, k, halfSize, 0, k);
  28395. vertices.push(k, 0, -halfSize, k, 0, halfSize);
  28396. const color = i === center ? color1 : color2;
  28397. color.toArray(colors, j);
  28398. j += 3;
  28399. color.toArray(colors, j);
  28400. j += 3;
  28401. color.toArray(colors, j);
  28402. j += 3;
  28403. color.toArray(colors, j);
  28404. j += 3;
  28405. }
  28406. const geometry = new BufferGeometry();
  28407. geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  28408. geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
  28409. const material = new LineBasicMaterial({
  28410. vertexColors: true,
  28411. toneMapped: false
  28412. });
  28413. super(geometry, material);
  28414. this.type = 'GridHelper';
  28415. }
  28416. }
  28417. class PolarGridHelper extends LineSegments {
  28418. constructor(radius = 10, radials = 16, circles = 8, divisions = 64, color1 = 0x444444, color2 = 0x888888) {
  28419. color1 = new Color(color1);
  28420. color2 = new Color(color2);
  28421. const vertices = [];
  28422. const colors = []; // create the radials
  28423. for (let i = 0; i <= radials; i++) {
  28424. const v = i / radials * (Math.PI * 2);
  28425. const x = Math.sin(v) * radius;
  28426. const z = Math.cos(v) * radius;
  28427. vertices.push(0, 0, 0);
  28428. vertices.push(x, 0, z);
  28429. const color = i & 1 ? color1 : color2;
  28430. colors.push(color.r, color.g, color.b);
  28431. colors.push(color.r, color.g, color.b);
  28432. } // create the circles
  28433. for (let i = 0; i <= circles; i++) {
  28434. const color = i & 1 ? color1 : color2;
  28435. const r = radius - radius / circles * i;
  28436. for (let j = 0; j < divisions; j++) {
  28437. // first vertex
  28438. let v = j / divisions * (Math.PI * 2);
  28439. let x = Math.sin(v) * r;
  28440. let z = Math.cos(v) * r;
  28441. vertices.push(x, 0, z);
  28442. colors.push(color.r, color.g, color.b); // second vertex
  28443. v = (j + 1) / divisions * (Math.PI * 2);
  28444. x = Math.sin(v) * r;
  28445. z = Math.cos(v) * r;
  28446. vertices.push(x, 0, z);
  28447. colors.push(color.r, color.g, color.b);
  28448. }
  28449. }
  28450. const geometry = new BufferGeometry();
  28451. geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  28452. geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
  28453. const material = new LineBasicMaterial({
  28454. vertexColors: true,
  28455. toneMapped: false
  28456. });
  28457. super(geometry, material);
  28458. this.type = 'PolarGridHelper';
  28459. }
  28460. }
  28461. const _v1 = /*@__PURE__*/new Vector3();
  28462. const _v2 = /*@__PURE__*/new Vector3();
  28463. const _v3 = /*@__PURE__*/new Vector3();
  28464. class DirectionalLightHelper extends Object3D {
  28465. constructor(light, size, color) {
  28466. super();
  28467. this.light = light;
  28468. this.light.updateMatrixWorld();
  28469. this.matrix = light.matrixWorld;
  28470. this.matrixAutoUpdate = false;
  28471. this.color = color;
  28472. if (size === undefined) size = 1;
  28473. let geometry = new BufferGeometry();
  28474. geometry.setAttribute('position', new Float32BufferAttribute([-size, size, 0, size, size, 0, size, -size, 0, -size, -size, 0, -size, size, 0], 3));
  28475. const material = new LineBasicMaterial({
  28476. fog: false,
  28477. toneMapped: false
  28478. });
  28479. this.lightPlane = new Line(geometry, material);
  28480. this.add(this.lightPlane);
  28481. geometry = new BufferGeometry();
  28482. geometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 0, 1], 3));
  28483. this.targetLine = new Line(geometry, material);
  28484. this.add(this.targetLine);
  28485. this.update();
  28486. }
  28487. dispose() {
  28488. this.lightPlane.geometry.dispose();
  28489. this.lightPlane.material.dispose();
  28490. this.targetLine.geometry.dispose();
  28491. this.targetLine.material.dispose();
  28492. }
  28493. update() {
  28494. _v1.setFromMatrixPosition(this.light.matrixWorld);
  28495. _v2.setFromMatrixPosition(this.light.target.matrixWorld);
  28496. _v3.subVectors(_v2, _v1);
  28497. this.lightPlane.lookAt(_v2);
  28498. if (this.color !== undefined) {
  28499. this.lightPlane.material.color.set(this.color);
  28500. this.targetLine.material.color.set(this.color);
  28501. } else {
  28502. this.lightPlane.material.color.copy(this.light.color);
  28503. this.targetLine.material.color.copy(this.light.color);
  28504. }
  28505. this.targetLine.lookAt(_v2);
  28506. this.targetLine.scale.z = _v3.length();
  28507. }
  28508. }
  28509. const _vector = /*@__PURE__*/new Vector3();
  28510. const _camera = /*@__PURE__*/new Camera();
  28511. /**
  28512. * - shows frustum, line of sight and up of the camera
  28513. * - suitable for fast updates
  28514. * - based on frustum visualization in lightgl.js shadowmap example
  28515. * https://github.com/evanw/lightgl.js/blob/master/tests/shadowmap.html
  28516. */
  28517. class CameraHelper extends LineSegments {
  28518. constructor(camera) {
  28519. const geometry = new BufferGeometry();
  28520. const material = new LineBasicMaterial({
  28521. color: 0xffffff,
  28522. vertexColors: true,
  28523. toneMapped: false
  28524. });
  28525. const vertices = [];
  28526. const colors = [];
  28527. const pointMap = {}; // near
  28528. addLine('n1', 'n2');
  28529. addLine('n2', 'n4');
  28530. addLine('n4', 'n3');
  28531. addLine('n3', 'n1'); // far
  28532. addLine('f1', 'f2');
  28533. addLine('f2', 'f4');
  28534. addLine('f4', 'f3');
  28535. addLine('f3', 'f1'); // sides
  28536. addLine('n1', 'f1');
  28537. addLine('n2', 'f2');
  28538. addLine('n3', 'f3');
  28539. addLine('n4', 'f4'); // cone
  28540. addLine('p', 'n1');
  28541. addLine('p', 'n2');
  28542. addLine('p', 'n3');
  28543. addLine('p', 'n4'); // up
  28544. addLine('u1', 'u2');
  28545. addLine('u2', 'u3');
  28546. addLine('u3', 'u1'); // target
  28547. addLine('c', 't');
  28548. addLine('p', 'c'); // cross
  28549. addLine('cn1', 'cn2');
  28550. addLine('cn3', 'cn4');
  28551. addLine('cf1', 'cf2');
  28552. addLine('cf3', 'cf4');
  28553. function addLine(a, b) {
  28554. addPoint(a);
  28555. addPoint(b);
  28556. }
  28557. function addPoint(id) {
  28558. vertices.push(0, 0, 0);
  28559. colors.push(0, 0, 0);
  28560. if (pointMap[id] === undefined) {
  28561. pointMap[id] = [];
  28562. }
  28563. pointMap[id].push(vertices.length / 3 - 1);
  28564. }
  28565. geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  28566. geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
  28567. super(geometry, material);
  28568. this.type = 'CameraHelper';
  28569. this.camera = camera;
  28570. if (this.camera.updateProjectionMatrix) this.camera.updateProjectionMatrix();
  28571. this.matrix = camera.matrixWorld;
  28572. this.matrixAutoUpdate = false;
  28573. this.pointMap = pointMap;
  28574. this.update(); // colors
  28575. const colorFrustum = new Color(0xffaa00);
  28576. const colorCone = new Color(0xff0000);
  28577. const colorUp = new Color(0x00aaff);
  28578. const colorTarget = new Color(0xffffff);
  28579. const colorCross = new Color(0x333333);
  28580. this.setColors(colorFrustum, colorCone, colorUp, colorTarget, colorCross);
  28581. }
  28582. setColors(frustum, cone, up, target, cross) {
  28583. const geometry = this.geometry;
  28584. const colorAttribute = geometry.getAttribute('color'); // near
  28585. colorAttribute.setXYZ(0, frustum.r, frustum.g, frustum.b);
  28586. colorAttribute.setXYZ(1, frustum.r, frustum.g, frustum.b); // n1, n2
  28587. colorAttribute.setXYZ(2, frustum.r, frustum.g, frustum.b);
  28588. colorAttribute.setXYZ(3, frustum.r, frustum.g, frustum.b); // n2, n4
  28589. colorAttribute.setXYZ(4, frustum.r, frustum.g, frustum.b);
  28590. colorAttribute.setXYZ(5, frustum.r, frustum.g, frustum.b); // n4, n3
  28591. colorAttribute.setXYZ(6, frustum.r, frustum.g, frustum.b);
  28592. colorAttribute.setXYZ(7, frustum.r, frustum.g, frustum.b); // n3, n1
  28593. // far
  28594. colorAttribute.setXYZ(8, frustum.r, frustum.g, frustum.b);
  28595. colorAttribute.setXYZ(9, frustum.r, frustum.g, frustum.b); // f1, f2
  28596. colorAttribute.setXYZ(10, frustum.r, frustum.g, frustum.b);
  28597. colorAttribute.setXYZ(11, frustum.r, frustum.g, frustum.b); // f2, f4
  28598. colorAttribute.setXYZ(12, frustum.r, frustum.g, frustum.b);
  28599. colorAttribute.setXYZ(13, frustum.r, frustum.g, frustum.b); // f4, f3
  28600. colorAttribute.setXYZ(14, frustum.r, frustum.g, frustum.b);
  28601. colorAttribute.setXYZ(15, frustum.r, frustum.g, frustum.b); // f3, f1
  28602. // sides
  28603. colorAttribute.setXYZ(16, frustum.r, frustum.g, frustum.b);
  28604. colorAttribute.setXYZ(17, frustum.r, frustum.g, frustum.b); // n1, f1
  28605. colorAttribute.setXYZ(18, frustum.r, frustum.g, frustum.b);
  28606. colorAttribute.setXYZ(19, frustum.r, frustum.g, frustum.b); // n2, f2
  28607. colorAttribute.setXYZ(20, frustum.r, frustum.g, frustum.b);
  28608. colorAttribute.setXYZ(21, frustum.r, frustum.g, frustum.b); // n3, f3
  28609. colorAttribute.setXYZ(22, frustum.r, frustum.g, frustum.b);
  28610. colorAttribute.setXYZ(23, frustum.r, frustum.g, frustum.b); // n4, f4
  28611. // cone
  28612. colorAttribute.setXYZ(24, cone.r, cone.g, cone.b);
  28613. colorAttribute.setXYZ(25, cone.r, cone.g, cone.b); // p, n1
  28614. colorAttribute.setXYZ(26, cone.r, cone.g, cone.b);
  28615. colorAttribute.setXYZ(27, cone.r, cone.g, cone.b); // p, n2
  28616. colorAttribute.setXYZ(28, cone.r, cone.g, cone.b);
  28617. colorAttribute.setXYZ(29, cone.r, cone.g, cone.b); // p, n3
  28618. colorAttribute.setXYZ(30, cone.r, cone.g, cone.b);
  28619. colorAttribute.setXYZ(31, cone.r, cone.g, cone.b); // p, n4
  28620. // up
  28621. colorAttribute.setXYZ(32, up.r, up.g, up.b);
  28622. colorAttribute.setXYZ(33, up.r, up.g, up.b); // u1, u2
  28623. colorAttribute.setXYZ(34, up.r, up.g, up.b);
  28624. colorAttribute.setXYZ(35, up.r, up.g, up.b); // u2, u3
  28625. colorAttribute.setXYZ(36, up.r, up.g, up.b);
  28626. colorAttribute.setXYZ(37, up.r, up.g, up.b); // u3, u1
  28627. // target
  28628. colorAttribute.setXYZ(38, target.r, target.g, target.b);
  28629. colorAttribute.setXYZ(39, target.r, target.g, target.b); // c, t
  28630. colorAttribute.setXYZ(40, cross.r, cross.g, cross.b);
  28631. colorAttribute.setXYZ(41, cross.r, cross.g, cross.b); // p, c
  28632. // cross
  28633. colorAttribute.setXYZ(42, cross.r, cross.g, cross.b);
  28634. colorAttribute.setXYZ(43, cross.r, cross.g, cross.b); // cn1, cn2
  28635. colorAttribute.setXYZ(44, cross.r, cross.g, cross.b);
  28636. colorAttribute.setXYZ(45, cross.r, cross.g, cross.b); // cn3, cn4
  28637. colorAttribute.setXYZ(46, cross.r, cross.g, cross.b);
  28638. colorAttribute.setXYZ(47, cross.r, cross.g, cross.b); // cf1, cf2
  28639. colorAttribute.setXYZ(48, cross.r, cross.g, cross.b);
  28640. colorAttribute.setXYZ(49, cross.r, cross.g, cross.b); // cf3, cf4
  28641. colorAttribute.needsUpdate = true;
  28642. }
  28643. update() {
  28644. const geometry = this.geometry;
  28645. const pointMap = this.pointMap;
  28646. const w = 1,
  28647. h = 1; // we need just camera projection matrix inverse
  28648. // world matrix must be identity
  28649. _camera.projectionMatrixInverse.copy(this.camera.projectionMatrixInverse); // center / target
  28650. setPoint('c', pointMap, geometry, _camera, 0, 0, -1);
  28651. setPoint('t', pointMap, geometry, _camera, 0, 0, 1); // near
  28652. setPoint('n1', pointMap, geometry, _camera, -w, -h, -1);
  28653. setPoint('n2', pointMap, geometry, _camera, w, -h, -1);
  28654. setPoint('n3', pointMap, geometry, _camera, -w, h, -1);
  28655. setPoint('n4', pointMap, geometry, _camera, w, h, -1); // far
  28656. setPoint('f1', pointMap, geometry, _camera, -w, -h, 1);
  28657. setPoint('f2', pointMap, geometry, _camera, w, -h, 1);
  28658. setPoint('f3', pointMap, geometry, _camera, -w, h, 1);
  28659. setPoint('f4', pointMap, geometry, _camera, w, h, 1); // up
  28660. setPoint('u1', pointMap, geometry, _camera, w * 0.7, h * 1.1, -1);
  28661. setPoint('u2', pointMap, geometry, _camera, -w * 0.7, h * 1.1, -1);
  28662. setPoint('u3', pointMap, geometry, _camera, 0, h * 2, -1); // cross
  28663. setPoint('cf1', pointMap, geometry, _camera, -w, 0, 1);
  28664. setPoint('cf2', pointMap, geometry, _camera, w, 0, 1);
  28665. setPoint('cf3', pointMap, geometry, _camera, 0, -h, 1);
  28666. setPoint('cf4', pointMap, geometry, _camera, 0, h, 1);
  28667. setPoint('cn1', pointMap, geometry, _camera, -w, 0, -1);
  28668. setPoint('cn2', pointMap, geometry, _camera, w, 0, -1);
  28669. setPoint('cn3', pointMap, geometry, _camera, 0, -h, -1);
  28670. setPoint('cn4', pointMap, geometry, _camera, 0, h, -1);
  28671. geometry.getAttribute('position').needsUpdate = true;
  28672. }
  28673. dispose() {
  28674. this.geometry.dispose();
  28675. this.material.dispose();
  28676. }
  28677. }
  28678. function setPoint(point, pointMap, geometry, camera, x, y, z) {
  28679. _vector.set(x, y, z).unproject(camera);
  28680. const points = pointMap[point];
  28681. if (points !== undefined) {
  28682. const position = geometry.getAttribute('position');
  28683. for (let i = 0, l = points.length; i < l; i++) {
  28684. position.setXYZ(points[i], _vector.x, _vector.y, _vector.z);
  28685. }
  28686. }
  28687. }
  28688. const _box = /*@__PURE__*/new Box3();
  28689. class BoxHelper extends LineSegments {
  28690. constructor(object, color = 0xffff00) {
  28691. const indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]);
  28692. const positions = new Float32Array(8 * 3);
  28693. const geometry = new BufferGeometry();
  28694. geometry.setIndex(new BufferAttribute(indices, 1));
  28695. geometry.setAttribute('position', new BufferAttribute(positions, 3));
  28696. super(geometry, new LineBasicMaterial({
  28697. color: color,
  28698. toneMapped: false
  28699. }));
  28700. this.object = object;
  28701. this.type = 'BoxHelper';
  28702. this.matrixAutoUpdate = false;
  28703. this.update();
  28704. }
  28705. update(object) {
  28706. if (object !== undefined) {
  28707. console.warn('THREE.BoxHelper: .update() has no longer arguments.');
  28708. }
  28709. if (this.object !== undefined) {
  28710. _box.setFromObject(this.object);
  28711. }
  28712. if (_box.isEmpty()) return;
  28713. const min = _box.min;
  28714. const max = _box.max;
  28715. /*
  28716. 5____4
  28717. 1/___0/|
  28718. | 6__|_7
  28719. 2/___3/
  28720. 0: max.x, max.y, max.z
  28721. 1: min.x, max.y, max.z
  28722. 2: min.x, min.y, max.z
  28723. 3: max.x, min.y, max.z
  28724. 4: max.x, max.y, min.z
  28725. 5: min.x, max.y, min.z
  28726. 6: min.x, min.y, min.z
  28727. 7: max.x, min.y, min.z
  28728. */
  28729. const position = this.geometry.attributes.position;
  28730. const array = position.array;
  28731. array[0] = max.x;
  28732. array[1] = max.y;
  28733. array[2] = max.z;
  28734. array[3] = min.x;
  28735. array[4] = max.y;
  28736. array[5] = max.z;
  28737. array[6] = min.x;
  28738. array[7] = min.y;
  28739. array[8] = max.z;
  28740. array[9] = max.x;
  28741. array[10] = min.y;
  28742. array[11] = max.z;
  28743. array[12] = max.x;
  28744. array[13] = max.y;
  28745. array[14] = min.z;
  28746. array[15] = min.x;
  28747. array[16] = max.y;
  28748. array[17] = min.z;
  28749. array[18] = min.x;
  28750. array[19] = min.y;
  28751. array[20] = min.z;
  28752. array[21] = max.x;
  28753. array[22] = min.y;
  28754. array[23] = min.z;
  28755. position.needsUpdate = true;
  28756. this.geometry.computeBoundingSphere();
  28757. }
  28758. setFromObject(object) {
  28759. this.object = object;
  28760. this.update();
  28761. return this;
  28762. }
  28763. copy(source, recursive) {
  28764. super.copy(source, recursive);
  28765. this.object = source.object;
  28766. return this;
  28767. }
  28768. }
  28769. class Box3Helper extends LineSegments {
  28770. constructor(box, color = 0xffff00) {
  28771. const indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]);
  28772. const positions = [1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1];
  28773. const geometry = new BufferGeometry();
  28774. geometry.setIndex(new BufferAttribute(indices, 1));
  28775. geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
  28776. super(geometry, new LineBasicMaterial({
  28777. color: color,
  28778. toneMapped: false
  28779. }));
  28780. this.box = box;
  28781. this.type = 'Box3Helper';
  28782. this.geometry.computeBoundingSphere();
  28783. }
  28784. updateMatrixWorld(force) {
  28785. const box = this.box;
  28786. if (box.isEmpty()) return;
  28787. box.getCenter(this.position);
  28788. box.getSize(this.scale);
  28789. this.scale.multiplyScalar(0.5);
  28790. super.updateMatrixWorld(force);
  28791. }
  28792. }
  28793. class PlaneHelper extends Line {
  28794. constructor(plane, size = 1, hex = 0xffff00) {
  28795. const color = hex;
  28796. const positions = [1, -1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0];
  28797. const geometry = new BufferGeometry();
  28798. geometry.setAttribute('position', new Float32BufferAttribute(positions, 3));
  28799. geometry.computeBoundingSphere();
  28800. super(geometry, new LineBasicMaterial({
  28801. color: color,
  28802. toneMapped: false
  28803. }));
  28804. this.type = 'PlaneHelper';
  28805. this.plane = plane;
  28806. this.size = size;
  28807. const positions2 = [1, 1, 0, -1, 1, 0, -1, -1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0];
  28808. const geometry2 = new BufferGeometry();
  28809. geometry2.setAttribute('position', new Float32BufferAttribute(positions2, 3));
  28810. geometry2.computeBoundingSphere();
  28811. this.add(new Mesh(geometry2, new MeshBasicMaterial({
  28812. color: color,
  28813. opacity: 0.2,
  28814. transparent: true,
  28815. depthWrite: false,
  28816. toneMapped: false
  28817. })));
  28818. }
  28819. updateMatrixWorld(force) {
  28820. this.position.set(0, 0, 0);
  28821. this.scale.set(0.5 * this.size, 0.5 * this.size, 1);
  28822. this.lookAt(this.plane.normal);
  28823. this.translateZ(-this.plane.constant);
  28824. super.updateMatrixWorld(force);
  28825. }
  28826. }
  28827. const _axis = /*@__PURE__*/new Vector3();
  28828. let _lineGeometry, _coneGeometry;
  28829. class ArrowHelper extends Object3D {
  28830. // dir is assumed to be normalized
  28831. constructor(dir = new Vector3(0, 0, 1), origin = new Vector3(0, 0, 0), length = 1, color = 0xffff00, headLength = length * 0.2, headWidth = headLength * 0.2) {
  28832. super();
  28833. this.type = 'ArrowHelper';
  28834. if (_lineGeometry === undefined) {
  28835. _lineGeometry = new BufferGeometry();
  28836. _lineGeometry.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 0, 1, 0], 3));
  28837. _coneGeometry = new CylinderGeometry(0, 0.5, 1, 5, 1);
  28838. _coneGeometry.translate(0, -0.5, 0);
  28839. }
  28840. this.position.copy(origin);
  28841. this.line = new Line(_lineGeometry, new LineBasicMaterial({
  28842. color: color,
  28843. toneMapped: false
  28844. }));
  28845. this.line.matrixAutoUpdate = false;
  28846. this.add(this.line);
  28847. this.cone = new Mesh(_coneGeometry, new MeshBasicMaterial({
  28848. color: color,
  28849. toneMapped: false
  28850. }));
  28851. this.cone.matrixAutoUpdate = false;
  28852. this.add(this.cone);
  28853. this.setDirection(dir);
  28854. this.setLength(length, headLength, headWidth);
  28855. }
  28856. setDirection(dir) {
  28857. // dir is assumed to be normalized
  28858. if (dir.y > 0.99999) {
  28859. this.quaternion.set(0, 0, 0, 1);
  28860. } else if (dir.y < -0.99999) {
  28861. this.quaternion.set(1, 0, 0, 0);
  28862. } else {
  28863. _axis.set(dir.z, 0, -dir.x).normalize();
  28864. const radians = Math.acos(dir.y);
  28865. this.quaternion.setFromAxisAngle(_axis, radians);
  28866. }
  28867. }
  28868. setLength(length, headLength = length * 0.2, headWidth = headLength * 0.2) {
  28869. this.line.scale.set(1, Math.max(0.0001, length - headLength), 1); // see #17458
  28870. this.line.updateMatrix();
  28871. this.cone.scale.set(headWidth, headLength, headWidth);
  28872. this.cone.position.y = length;
  28873. this.cone.updateMatrix();
  28874. }
  28875. setColor(color) {
  28876. this.line.material.color.set(color);
  28877. this.cone.material.color.set(color);
  28878. }
  28879. copy(source) {
  28880. super.copy(source, false);
  28881. this.line.copy(source.line);
  28882. this.cone.copy(source.cone);
  28883. return this;
  28884. }
  28885. }
  28886. class AxesHelper extends LineSegments {
  28887. constructor(size = 1) {
  28888. const vertices = [0, 0, 0, size, 0, 0, 0, 0, 0, 0, size, 0, 0, 0, 0, 0, 0, size];
  28889. const colors = [1, 0, 0, 1, 0.6, 0, 0, 1, 0, 0.6, 1, 0, 0, 0, 1, 0, 0.6, 1];
  28890. const geometry = new BufferGeometry();
  28891. geometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
  28892. geometry.setAttribute('color', new Float32BufferAttribute(colors, 3));
  28893. const material = new LineBasicMaterial({
  28894. vertexColors: true,
  28895. toneMapped: false
  28896. });
  28897. super(geometry, material);
  28898. this.type = 'AxesHelper';
  28899. }
  28900. setColors(xAxisColor, yAxisColor, zAxisColor) {
  28901. const color = new Color();
  28902. const array = this.geometry.attributes.color.array;
  28903. color.set(xAxisColor);
  28904. color.toArray(array, 0);
  28905. color.toArray(array, 3);
  28906. color.set(yAxisColor);
  28907. color.toArray(array, 6);
  28908. color.toArray(array, 9);
  28909. color.set(zAxisColor);
  28910. color.toArray(array, 12);
  28911. color.toArray(array, 15);
  28912. this.geometry.attributes.color.needsUpdate = true;
  28913. return this;
  28914. }
  28915. dispose() {
  28916. this.geometry.dispose();
  28917. this.material.dispose();
  28918. }
  28919. }
  28920. class ShapePath {
  28921. constructor() {
  28922. this.type = 'ShapePath';
  28923. this.color = new Color();
  28924. this.subPaths = [];
  28925. this.currentPath = null;
  28926. }
  28927. moveTo(x, y) {
  28928. this.currentPath = new Path();
  28929. this.subPaths.push(this.currentPath);
  28930. this.currentPath.moveTo(x, y);
  28931. return this;
  28932. }
  28933. lineTo(x, y) {
  28934. this.currentPath.lineTo(x, y);
  28935. return this;
  28936. }
  28937. quadraticCurveTo(aCPx, aCPy, aX, aY) {
  28938. this.currentPath.quadraticCurveTo(aCPx, aCPy, aX, aY);
  28939. return this;
  28940. }
  28941. bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY) {
  28942. this.currentPath.bezierCurveTo(aCP1x, aCP1y, aCP2x, aCP2y, aX, aY);
  28943. return this;
  28944. }
  28945. splineThru(pts) {
  28946. this.currentPath.splineThru(pts);
  28947. return this;
  28948. }
  28949. toShapes(isCCW, noHoles) {
  28950. function toShapesNoHoles(inSubpaths) {
  28951. const shapes = [];
  28952. for (let i = 0, l = inSubpaths.length; i < l; i++) {
  28953. const tmpPath = inSubpaths[i];
  28954. const tmpShape = new Shape();
  28955. tmpShape.curves = tmpPath.curves;
  28956. shapes.push(tmpShape);
  28957. }
  28958. return shapes;
  28959. }
  28960. function isPointInsidePolygon(inPt, inPolygon) {
  28961. const polyLen = inPolygon.length; // inPt on polygon contour => immediate success or
  28962. // toggling of inside/outside at every single! intersection point of an edge
  28963. // with the horizontal line through inPt, left of inPt
  28964. // not counting lowerY endpoints of edges and whole edges on that line
  28965. let inside = false;
  28966. for (let p = polyLen - 1, q = 0; q < polyLen; p = q++) {
  28967. let edgeLowPt = inPolygon[p];
  28968. let edgeHighPt = inPolygon[q];
  28969. let edgeDx = edgeHighPt.x - edgeLowPt.x;
  28970. let edgeDy = edgeHighPt.y - edgeLowPt.y;
  28971. if (Math.abs(edgeDy) > Number.EPSILON) {
  28972. // not parallel
  28973. if (edgeDy < 0) {
  28974. edgeLowPt = inPolygon[q];
  28975. edgeDx = -edgeDx;
  28976. edgeHighPt = inPolygon[p];
  28977. edgeDy = -edgeDy;
  28978. }
  28979. if (inPt.y < edgeLowPt.y || inPt.y > edgeHighPt.y) continue;
  28980. if (inPt.y === edgeLowPt.y) {
  28981. if (inPt.x === edgeLowPt.x) return true; // inPt is on contour ?
  28982. // continue; // no intersection or edgeLowPt => doesn't count !!!
  28983. } else {
  28984. const perpEdge = edgeDy * (inPt.x - edgeLowPt.x) - edgeDx * (inPt.y - edgeLowPt.y);
  28985. if (perpEdge === 0) return true; // inPt is on contour ?
  28986. if (perpEdge < 0) continue;
  28987. inside = !inside; // true intersection left of inPt
  28988. }
  28989. } else {
  28990. // parallel or collinear
  28991. if (inPt.y !== edgeLowPt.y) continue; // parallel
  28992. // edge lies on the same horizontal line as inPt
  28993. if (edgeHighPt.x <= inPt.x && inPt.x <= edgeLowPt.x || edgeLowPt.x <= inPt.x && inPt.x <= edgeHighPt.x) return true; // inPt: Point on contour !
  28994. // continue;
  28995. }
  28996. }
  28997. return inside;
  28998. }
  28999. const isClockWise = ShapeUtils.isClockWise;
  29000. const subPaths = this.subPaths;
  29001. if (subPaths.length === 0) return [];
  29002. if (noHoles === true) return toShapesNoHoles(subPaths);
  29003. let solid, tmpPath, tmpShape;
  29004. const shapes = [];
  29005. if (subPaths.length === 1) {
  29006. tmpPath = subPaths[0];
  29007. tmpShape = new Shape();
  29008. tmpShape.curves = tmpPath.curves;
  29009. shapes.push(tmpShape);
  29010. return shapes;
  29011. }
  29012. let holesFirst = !isClockWise(subPaths[0].getPoints());
  29013. holesFirst = isCCW ? !holesFirst : holesFirst; // console.log("Holes first", holesFirst);
  29014. const betterShapeHoles = [];
  29015. const newShapes = [];
  29016. let newShapeHoles = [];
  29017. let mainIdx = 0;
  29018. let tmpPoints;
  29019. newShapes[mainIdx] = undefined;
  29020. newShapeHoles[mainIdx] = [];
  29021. for (let i = 0, l = subPaths.length; i < l; i++) {
  29022. tmpPath = subPaths[i];
  29023. tmpPoints = tmpPath.getPoints();
  29024. solid = isClockWise(tmpPoints);
  29025. solid = isCCW ? !solid : solid;
  29026. if (solid) {
  29027. if (!holesFirst && newShapes[mainIdx]) mainIdx++;
  29028. newShapes[mainIdx] = {
  29029. s: new Shape(),
  29030. p: tmpPoints
  29031. };
  29032. newShapes[mainIdx].s.curves = tmpPath.curves;
  29033. if (holesFirst) mainIdx++;
  29034. newShapeHoles[mainIdx] = []; //console.log('cw', i);
  29035. } else {
  29036. newShapeHoles[mainIdx].push({
  29037. h: tmpPath,
  29038. p: tmpPoints[0]
  29039. }); //console.log('ccw', i);
  29040. }
  29041. } // only Holes? -> probably all Shapes with wrong orientation
  29042. if (!newShapes[0]) return toShapesNoHoles(subPaths);
  29043. if (newShapes.length > 1) {
  29044. let ambiguous = false;
  29045. let toChange = 0;
  29046. for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) {
  29047. betterShapeHoles[sIdx] = [];
  29048. }
  29049. for (let sIdx = 0, sLen = newShapes.length; sIdx < sLen; sIdx++) {
  29050. const sho = newShapeHoles[sIdx];
  29051. for (let hIdx = 0; hIdx < sho.length; hIdx++) {
  29052. const ho = sho[hIdx];
  29053. let hole_unassigned = true;
  29054. for (let s2Idx = 0; s2Idx < newShapes.length; s2Idx++) {
  29055. if (isPointInsidePolygon(ho.p, newShapes[s2Idx].p)) {
  29056. if (sIdx !== s2Idx) toChange++;
  29057. if (hole_unassigned) {
  29058. hole_unassigned = false;
  29059. betterShapeHoles[s2Idx].push(ho);
  29060. } else {
  29061. ambiguous = true;
  29062. }
  29063. }
  29064. }
  29065. if (hole_unassigned) {
  29066. betterShapeHoles[sIdx].push(ho);
  29067. }
  29068. }
  29069. }
  29070. if (toChange > 0 && ambiguous === false) {
  29071. newShapeHoles = betterShapeHoles;
  29072. }
  29073. }
  29074. let tmpHoles;
  29075. for (let i = 0, il = newShapes.length; i < il; i++) {
  29076. tmpShape = newShapes[i].s;
  29077. shapes.push(tmpShape);
  29078. tmpHoles = newShapeHoles[i];
  29079. for (let j = 0, jl = tmpHoles.length; j < jl; j++) {
  29080. tmpShape.holes.push(tmpHoles[j].h);
  29081. }
  29082. } //console.log("shape", shapes);
  29083. return shapes;
  29084. }
  29085. }
  29086. const _tables = /*@__PURE__*/_generateTables();
  29087. function _generateTables() {
  29088. // float32 to float16 helpers
  29089. const buffer = new ArrayBuffer(4);
  29090. const floatView = new Float32Array(buffer);
  29091. const uint32View = new Uint32Array(buffer);
  29092. const baseTable = new Uint32Array(512);
  29093. const shiftTable = new Uint32Array(512);
  29094. for (let i = 0; i < 256; ++i) {
  29095. const e = i - 127; // very small number (0, -0)
  29096. if (e < -27) {
  29097. baseTable[i] = 0x0000;
  29098. baseTable[i | 0x100] = 0x8000;
  29099. shiftTable[i] = 24;
  29100. shiftTable[i | 0x100] = 24; // small number (denorm)
  29101. } else if (e < -14) {
  29102. baseTable[i] = 0x0400 >> -e - 14;
  29103. baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;
  29104. shiftTable[i] = -e - 1;
  29105. shiftTable[i | 0x100] = -e - 1; // normal number
  29106. } else if (e <= 15) {
  29107. baseTable[i] = e + 15 << 10;
  29108. baseTable[i | 0x100] = e + 15 << 10 | 0x8000;
  29109. shiftTable[i] = 13;
  29110. shiftTable[i | 0x100] = 13; // large number (Infinity, -Infinity)
  29111. } else if (e < 128) {
  29112. baseTable[i] = 0x7c00;
  29113. baseTable[i | 0x100] = 0xfc00;
  29114. shiftTable[i] = 24;
  29115. shiftTable[i | 0x100] = 24; // stay (NaN, Infinity, -Infinity)
  29116. } else {
  29117. baseTable[i] = 0x7c00;
  29118. baseTable[i | 0x100] = 0xfc00;
  29119. shiftTable[i] = 13;
  29120. shiftTable[i | 0x100] = 13;
  29121. }
  29122. } // float16 to float32 helpers
  29123. const mantissaTable = new Uint32Array(2048);
  29124. const exponentTable = new Uint32Array(64);
  29125. const offsetTable = new Uint32Array(64);
  29126. for (let i = 1; i < 1024; ++i) {
  29127. let m = i << 13; // zero pad mantissa bits
  29128. let e = 0; // zero exponent
  29129. // normalized
  29130. while ((m & 0x00800000) === 0) {
  29131. m <<= 1;
  29132. e -= 0x00800000; // decrement exponent
  29133. }
  29134. m &= ~0x00800000; // clear leading 1 bit
  29135. e += 0x38800000; // adjust bias
  29136. mantissaTable[i] = m | e;
  29137. }
  29138. for (let i = 1024; i < 2048; ++i) {
  29139. mantissaTable[i] = 0x38000000 + (i - 1024 << 13);
  29140. }
  29141. for (let i = 1; i < 31; ++i) {
  29142. exponentTable[i] = i << 23;
  29143. }
  29144. exponentTable[31] = 0x47800000;
  29145. exponentTable[32] = 0x80000000;
  29146. for (let i = 33; i < 63; ++i) {
  29147. exponentTable[i] = 0x80000000 + (i - 32 << 23);
  29148. }
  29149. exponentTable[63] = 0xc7800000;
  29150. for (let i = 1; i < 64; ++i) {
  29151. if (i !== 32) {
  29152. offsetTable[i] = 1024;
  29153. }
  29154. }
  29155. return {
  29156. floatView: floatView,
  29157. uint32View: uint32View,
  29158. baseTable: baseTable,
  29159. shiftTable: shiftTable,
  29160. mantissaTable: mantissaTable,
  29161. exponentTable: exponentTable,
  29162. offsetTable: offsetTable
  29163. };
  29164. } // float32 to float16
  29165. function toHalfFloat(val) {
  29166. if (Math.abs(val) > 65504) console.warn('THREE.DataUtils.toHalfFloat(): Value out of range.');
  29167. val = clamp(val, -65504, 65504);
  29168. _tables.floatView[0] = val;
  29169. const f = _tables.uint32View[0];
  29170. const e = f >> 23 & 0x1ff;
  29171. return _tables.baseTable[e] + ((f & 0x007fffff) >> _tables.shiftTable[e]);
  29172. } // float16 to float32
  29173. function fromHalfFloat(val) {
  29174. const m = val >> 10;
  29175. _tables.uint32View[0] = _tables.mantissaTable[_tables.offsetTable[m] + (val & 0x3ff)] + _tables.exponentTable[m];
  29176. return _tables.floatView[0];
  29177. }
  29178. var DataUtils = /*#__PURE__*/Object.freeze({
  29179. __proto__: null,
  29180. toHalfFloat: toHalfFloat,
  29181. fromHalfFloat: fromHalfFloat
  29182. });
  29183. class ParametricGeometry extends BufferGeometry {
  29184. constructor() {
  29185. console.error('THREE.ParametricGeometry has been moved to /examples/jsm/geometries/ParametricGeometry.js');
  29186. super();
  29187. }
  29188. } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92
  29189. class TextGeometry extends BufferGeometry {
  29190. constructor() {
  29191. console.error('THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js');
  29192. super();
  29193. }
  29194. } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92
  29195. function FontLoader() {
  29196. console.error('THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js');
  29197. } // r133, eb58ff153119090d3bbb24474ea0ffc40c70dc92
  29198. function Font() {
  29199. console.error('THREE.Font has been moved to /examples/jsm/loaders/FontLoader.js');
  29200. } // r134, d65e0af06644fe5a84a6fc0e372f4318f95a04c0
  29201. function ImmediateRenderObject() {
  29202. console.error('THREE.ImmediateRenderObject has been removed.');
  29203. } // r138, 48b05d3500acc084df50be9b4c90781ad9b8cb17
  29204. class WebGLMultisampleRenderTarget extends WebGLRenderTarget {
  29205. constructor(width, height, options) {
  29206. console.error('THREE.WebGLMultisampleRenderTarget has been removed. Use a normal render target and set the "samples" property to greater 0 to enable multisampling.');
  29207. super(width, height, options);
  29208. this.samples = 4;
  29209. }
  29210. } // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce
  29211. class DataTexture2DArray extends DataArrayTexture {
  29212. constructor(data, width, height, depth) {
  29213. console.warn('THREE.DataTexture2DArray has been renamed to DataArrayTexture.');
  29214. super(data, width, height, depth);
  29215. }
  29216. } // r138, f9cd9cab03b7b64244e304900a3a2eeaa3a588ce
  29217. class DataTexture3D extends Data3DTexture {
  29218. constructor(data, width, height, depth) {
  29219. console.warn('THREE.DataTexture3D has been renamed to Data3DTexture.');
  29220. super(data, width, height, depth);
  29221. }
  29222. }
  29223. if (typeof __THREE_DEVTOOLS__ !== 'undefined') {
  29224. __THREE_DEVTOOLS__.dispatchEvent(new CustomEvent('register', {
  29225. detail: {
  29226. revision: REVISION
  29227. }
  29228. }));
  29229. }
  29230. if (typeof window !== 'undefined') {
  29231. if (window.__THREE__) {
  29232. console.warn('WARNING: Multiple instances of Three.js being imported.');
  29233. } else {
  29234. window.__THREE__ = REVISION;
  29235. }
  29236. }
  29237. exports.ACESFilmicToneMapping = ACESFilmicToneMapping;
  29238. exports.AddEquation = AddEquation;
  29239. exports.AddOperation = AddOperation;
  29240. exports.AdditiveAnimationBlendMode = AdditiveAnimationBlendMode;
  29241. exports.AdditiveBlending = AdditiveBlending;
  29242. exports.AlphaFormat = AlphaFormat;
  29243. exports.AlwaysDepth = AlwaysDepth;
  29244. exports.AlwaysStencilFunc = AlwaysStencilFunc;
  29245. exports.AmbientLight = AmbientLight;
  29246. exports.AmbientLightProbe = AmbientLightProbe;
  29247. exports.AnimationClip = AnimationClip;
  29248. exports.AnimationLoader = AnimationLoader;
  29249. exports.AnimationMixer = AnimationMixer;
  29250. exports.AnimationObjectGroup = AnimationObjectGroup;
  29251. exports.AnimationUtils = AnimationUtils;
  29252. exports.ArcCurve = ArcCurve;
  29253. exports.ArrayCamera = ArrayCamera;
  29254. exports.ArrowHelper = ArrowHelper;
  29255. exports.Audio = Audio;
  29256. exports.AudioAnalyser = AudioAnalyser;
  29257. exports.AudioContext = AudioContext;
  29258. exports.AudioListener = AudioListener;
  29259. exports.AudioLoader = AudioLoader;
  29260. exports.AxesHelper = AxesHelper;
  29261. exports.BackSide = BackSide;
  29262. exports.BasicDepthPacking = BasicDepthPacking;
  29263. exports.BasicShadowMap = BasicShadowMap;
  29264. exports.Bone = Bone;
  29265. exports.BooleanKeyframeTrack = BooleanKeyframeTrack;
  29266. exports.Box2 = Box2;
  29267. exports.Box3 = Box3;
  29268. exports.Box3Helper = Box3Helper;
  29269. exports.BoxBufferGeometry = BoxGeometry;
  29270. exports.BoxGeometry = BoxGeometry;
  29271. exports.BoxHelper = BoxHelper;
  29272. exports.BufferAttribute = BufferAttribute;
  29273. exports.BufferGeometry = BufferGeometry;
  29274. exports.BufferGeometryLoader = BufferGeometryLoader;
  29275. exports.ByteType = ByteType;
  29276. exports.Cache = Cache;
  29277. exports.Camera = Camera;
  29278. exports.CameraHelper = CameraHelper;
  29279. exports.CanvasTexture = CanvasTexture;
  29280. exports.CapsuleBufferGeometry = CapsuleGeometry;
  29281. exports.CapsuleGeometry = CapsuleGeometry;
  29282. exports.CatmullRomCurve3 = CatmullRomCurve3;
  29283. exports.CineonToneMapping = CineonToneMapping;
  29284. exports.CircleBufferGeometry = CircleGeometry;
  29285. exports.CircleGeometry = CircleGeometry;
  29286. exports.ClampToEdgeWrapping = ClampToEdgeWrapping;
  29287. exports.Clock = Clock;
  29288. exports.Color = Color;
  29289. exports.ColorKeyframeTrack = ColorKeyframeTrack;
  29290. exports.ColorManagement = ColorManagement;
  29291. exports.CompressedTexture = CompressedTexture;
  29292. exports.CompressedTextureLoader = CompressedTextureLoader;
  29293. exports.ConeBufferGeometry = ConeGeometry;
  29294. exports.ConeGeometry = ConeGeometry;
  29295. exports.CubeCamera = CubeCamera;
  29296. exports.CubeReflectionMapping = CubeReflectionMapping;
  29297. exports.CubeRefractionMapping = CubeRefractionMapping;
  29298. exports.CubeTexture = CubeTexture;
  29299. exports.CubeTextureLoader = CubeTextureLoader;
  29300. exports.CubeUVReflectionMapping = CubeUVReflectionMapping;
  29301. exports.CubicBezierCurve = CubicBezierCurve;
  29302. exports.CubicBezierCurve3 = CubicBezierCurve3;
  29303. exports.CubicInterpolant = CubicInterpolant;
  29304. exports.CullFaceBack = CullFaceBack;
  29305. exports.CullFaceFront = CullFaceFront;
  29306. exports.CullFaceFrontBack = CullFaceFrontBack;
  29307. exports.CullFaceNone = CullFaceNone;
  29308. exports.Curve = Curve;
  29309. exports.CurvePath = CurvePath;
  29310. exports.CustomBlending = CustomBlending;
  29311. exports.CustomToneMapping = CustomToneMapping;
  29312. exports.CylinderBufferGeometry = CylinderGeometry;
  29313. exports.CylinderGeometry = CylinderGeometry;
  29314. exports.Cylindrical = Cylindrical;
  29315. exports.Data3DTexture = Data3DTexture;
  29316. exports.DataArrayTexture = DataArrayTexture;
  29317. exports.DataTexture = DataTexture;
  29318. exports.DataTexture2DArray = DataTexture2DArray;
  29319. exports.DataTexture3D = DataTexture3D;
  29320. exports.DataTextureLoader = DataTextureLoader;
  29321. exports.DataUtils = DataUtils;
  29322. exports.DecrementStencilOp = DecrementStencilOp;
  29323. exports.DecrementWrapStencilOp = DecrementWrapStencilOp;
  29324. exports.DefaultLoadingManager = DefaultLoadingManager;
  29325. exports.DepthFormat = DepthFormat;
  29326. exports.DepthStencilFormat = DepthStencilFormat;
  29327. exports.DepthTexture = DepthTexture;
  29328. exports.DirectionalLight = DirectionalLight;
  29329. exports.DirectionalLightHelper = DirectionalLightHelper;
  29330. exports.DiscreteInterpolant = DiscreteInterpolant;
  29331. exports.DodecahedronBufferGeometry = DodecahedronGeometry;
  29332. exports.DodecahedronGeometry = DodecahedronGeometry;
  29333. exports.DoubleSide = DoubleSide;
  29334. exports.DstAlphaFactor = DstAlphaFactor;
  29335. exports.DstColorFactor = DstColorFactor;
  29336. exports.DynamicCopyUsage = DynamicCopyUsage;
  29337. exports.DynamicDrawUsage = DynamicDrawUsage;
  29338. exports.DynamicReadUsage = DynamicReadUsage;
  29339. exports.EdgesGeometry = EdgesGeometry;
  29340. exports.EllipseCurve = EllipseCurve;
  29341. exports.EqualDepth = EqualDepth;
  29342. exports.EqualStencilFunc = EqualStencilFunc;
  29343. exports.EquirectangularReflectionMapping = EquirectangularReflectionMapping;
  29344. exports.EquirectangularRefractionMapping = EquirectangularRefractionMapping;
  29345. exports.Euler = Euler;
  29346. exports.EventDispatcher = EventDispatcher;
  29347. exports.ExtrudeBufferGeometry = ExtrudeGeometry;
  29348. exports.ExtrudeGeometry = ExtrudeGeometry;
  29349. exports.FileLoader = FileLoader;
  29350. exports.FlatShading = FlatShading;
  29351. exports.Float16BufferAttribute = Float16BufferAttribute;
  29352. exports.Float32BufferAttribute = Float32BufferAttribute;
  29353. exports.Float64BufferAttribute = Float64BufferAttribute;
  29354. exports.FloatType = FloatType;
  29355. exports.Fog = Fog;
  29356. exports.FogExp2 = FogExp2;
  29357. exports.Font = Font;
  29358. exports.FontLoader = FontLoader;
  29359. exports.FramebufferTexture = FramebufferTexture;
  29360. exports.FrontSide = FrontSide;
  29361. exports.Frustum = Frustum;
  29362. exports.GLBufferAttribute = GLBufferAttribute;
  29363. exports.GLSL1 = GLSL1;
  29364. exports.GLSL3 = GLSL3;
  29365. exports.GreaterDepth = GreaterDepth;
  29366. exports.GreaterEqualDepth = GreaterEqualDepth;
  29367. exports.GreaterEqualStencilFunc = GreaterEqualStencilFunc;
  29368. exports.GreaterStencilFunc = GreaterStencilFunc;
  29369. exports.GridHelper = GridHelper;
  29370. exports.Group = Group;
  29371. exports.HalfFloatType = HalfFloatType;
  29372. exports.HemisphereLight = HemisphereLight;
  29373. exports.HemisphereLightHelper = HemisphereLightHelper;
  29374. exports.HemisphereLightProbe = HemisphereLightProbe;
  29375. exports.IcosahedronBufferGeometry = IcosahedronGeometry;
  29376. exports.IcosahedronGeometry = IcosahedronGeometry;
  29377. exports.ImageBitmapLoader = ImageBitmapLoader;
  29378. exports.ImageLoader = ImageLoader;
  29379. exports.ImageUtils = ImageUtils;
  29380. exports.ImmediateRenderObject = ImmediateRenderObject;
  29381. exports.IncrementStencilOp = IncrementStencilOp;
  29382. exports.IncrementWrapStencilOp = IncrementWrapStencilOp;
  29383. exports.InstancedBufferAttribute = InstancedBufferAttribute;
  29384. exports.InstancedBufferGeometry = InstancedBufferGeometry;
  29385. exports.InstancedInterleavedBuffer = InstancedInterleavedBuffer;
  29386. exports.InstancedMesh = InstancedMesh;
  29387. exports.Int16BufferAttribute = Int16BufferAttribute;
  29388. exports.Int32BufferAttribute = Int32BufferAttribute;
  29389. exports.Int8BufferAttribute = Int8BufferAttribute;
  29390. exports.IntType = IntType;
  29391. exports.InterleavedBuffer = InterleavedBuffer;
  29392. exports.InterleavedBufferAttribute = InterleavedBufferAttribute;
  29393. exports.Interpolant = Interpolant;
  29394. exports.InterpolateDiscrete = InterpolateDiscrete;
  29395. exports.InterpolateLinear = InterpolateLinear;
  29396. exports.InterpolateSmooth = InterpolateSmooth;
  29397. exports.InvertStencilOp = InvertStencilOp;
  29398. exports.KeepStencilOp = KeepStencilOp;
  29399. exports.KeyframeTrack = KeyframeTrack;
  29400. exports.LOD = LOD;
  29401. exports.LatheBufferGeometry = LatheGeometry;
  29402. exports.LatheGeometry = LatheGeometry;
  29403. exports.Layers = Layers;
  29404. exports.LessDepth = LessDepth;
  29405. exports.LessEqualDepth = LessEqualDepth;
  29406. exports.LessEqualStencilFunc = LessEqualStencilFunc;
  29407. exports.LessStencilFunc = LessStencilFunc;
  29408. exports.Light = Light;
  29409. exports.LightProbe = LightProbe;
  29410. exports.Line = Line;
  29411. exports.Line3 = Line3;
  29412. exports.LineBasicMaterial = LineBasicMaterial;
  29413. exports.LineCurve = LineCurve;
  29414. exports.LineCurve3 = LineCurve3;
  29415. exports.LineDashedMaterial = LineDashedMaterial;
  29416. exports.LineLoop = LineLoop;
  29417. exports.LineSegments = LineSegments;
  29418. exports.LinearEncoding = LinearEncoding;
  29419. exports.LinearFilter = LinearFilter;
  29420. exports.LinearInterpolant = LinearInterpolant;
  29421. exports.LinearMipMapLinearFilter = LinearMipMapLinearFilter;
  29422. exports.LinearMipMapNearestFilter = LinearMipMapNearestFilter;
  29423. exports.LinearMipmapLinearFilter = LinearMipmapLinearFilter;
  29424. exports.LinearMipmapNearestFilter = LinearMipmapNearestFilter;
  29425. exports.LinearSRGBColorSpace = LinearSRGBColorSpace;
  29426. exports.LinearToneMapping = LinearToneMapping;
  29427. exports.Loader = Loader;
  29428. exports.LoaderUtils = LoaderUtils;
  29429. exports.LoadingManager = LoadingManager;
  29430. exports.LoopOnce = LoopOnce;
  29431. exports.LoopPingPong = LoopPingPong;
  29432. exports.LoopRepeat = LoopRepeat;
  29433. exports.LuminanceAlphaFormat = LuminanceAlphaFormat;
  29434. exports.LuminanceFormat = LuminanceFormat;
  29435. exports.MOUSE = MOUSE;
  29436. exports.Material = Material;
  29437. exports.MaterialLoader = MaterialLoader;
  29438. exports.MathUtils = MathUtils;
  29439. exports.Matrix3 = Matrix3;
  29440. exports.Matrix4 = Matrix4;
  29441. exports.MaxEquation = MaxEquation;
  29442. exports.Mesh = Mesh;
  29443. exports.MeshBasicMaterial = MeshBasicMaterial;
  29444. exports.MeshDepthMaterial = MeshDepthMaterial;
  29445. exports.MeshDistanceMaterial = MeshDistanceMaterial;
  29446. exports.MeshLambertMaterial = MeshLambertMaterial;
  29447. exports.MeshMatcapMaterial = MeshMatcapMaterial;
  29448. exports.MeshNormalMaterial = MeshNormalMaterial;
  29449. exports.MeshPhongMaterial = MeshPhongMaterial;
  29450. exports.MeshPhysicalMaterial = MeshPhysicalMaterial;
  29451. exports.MeshStandardMaterial = MeshStandardMaterial;
  29452. exports.MeshToonMaterial = MeshToonMaterial;
  29453. exports.MinEquation = MinEquation;
  29454. exports.MirroredRepeatWrapping = MirroredRepeatWrapping;
  29455. exports.MixOperation = MixOperation;
  29456. exports.MultiplyBlending = MultiplyBlending;
  29457. exports.MultiplyOperation = MultiplyOperation;
  29458. exports.NearestFilter = NearestFilter;
  29459. exports.NearestMipMapLinearFilter = NearestMipMapLinearFilter;
  29460. exports.NearestMipMapNearestFilter = NearestMipMapNearestFilter;
  29461. exports.NearestMipmapLinearFilter = NearestMipmapLinearFilter;
  29462. exports.NearestMipmapNearestFilter = NearestMipmapNearestFilter;
  29463. exports.NeverDepth = NeverDepth;
  29464. exports.NeverStencilFunc = NeverStencilFunc;
  29465. exports.NoBlending = NoBlending;
  29466. exports.NoColorSpace = NoColorSpace;
  29467. exports.NoToneMapping = NoToneMapping;
  29468. exports.NormalAnimationBlendMode = NormalAnimationBlendMode;
  29469. exports.NormalBlending = NormalBlending;
  29470. exports.NotEqualDepth = NotEqualDepth;
  29471. exports.NotEqualStencilFunc = NotEqualStencilFunc;
  29472. exports.NumberKeyframeTrack = NumberKeyframeTrack;
  29473. exports.Object3D = Object3D;
  29474. exports.ObjectLoader = ObjectLoader;
  29475. exports.ObjectSpaceNormalMap = ObjectSpaceNormalMap;
  29476. exports.OctahedronBufferGeometry = OctahedronGeometry;
  29477. exports.OctahedronGeometry = OctahedronGeometry;
  29478. exports.OneFactor = OneFactor;
  29479. exports.OneMinusDstAlphaFactor = OneMinusDstAlphaFactor;
  29480. exports.OneMinusDstColorFactor = OneMinusDstColorFactor;
  29481. exports.OneMinusSrcAlphaFactor = OneMinusSrcAlphaFactor;
  29482. exports.OneMinusSrcColorFactor = OneMinusSrcColorFactor;
  29483. exports.OrthographicCamera = OrthographicCamera;
  29484. exports.PCFShadowMap = PCFShadowMap;
  29485. exports.PCFSoftShadowMap = PCFSoftShadowMap;
  29486. exports.PMREMGenerator = PMREMGenerator;
  29487. exports.ParametricGeometry = ParametricGeometry;
  29488. exports.Path = Path;
  29489. exports.PerspectiveCamera = PerspectiveCamera;
  29490. exports.Plane = Plane;
  29491. exports.PlaneBufferGeometry = PlaneGeometry;
  29492. exports.PlaneGeometry = PlaneGeometry;
  29493. exports.PlaneHelper = PlaneHelper;
  29494. exports.PointLight = PointLight;
  29495. exports.PointLightHelper = PointLightHelper;
  29496. exports.Points = Points;
  29497. exports.PointsMaterial = PointsMaterial;
  29498. exports.PolarGridHelper = PolarGridHelper;
  29499. exports.PolyhedronBufferGeometry = PolyhedronGeometry;
  29500. exports.PolyhedronGeometry = PolyhedronGeometry;
  29501. exports.PositionalAudio = PositionalAudio;
  29502. exports.PropertyBinding = PropertyBinding;
  29503. exports.PropertyMixer = PropertyMixer;
  29504. exports.QuadraticBezierCurve = QuadraticBezierCurve;
  29505. exports.QuadraticBezierCurve3 = QuadraticBezierCurve3;
  29506. exports.Quaternion = Quaternion;
  29507. exports.QuaternionKeyframeTrack = QuaternionKeyframeTrack;
  29508. exports.QuaternionLinearInterpolant = QuaternionLinearInterpolant;
  29509. exports.REVISION = REVISION;
  29510. exports.RGBADepthPacking = RGBADepthPacking;
  29511. exports.RGBAFormat = RGBAFormat;
  29512. exports.RGBAIntegerFormat = RGBAIntegerFormat;
  29513. exports.RGBA_ASTC_10x10_Format = RGBA_ASTC_10x10_Format;
  29514. exports.RGBA_ASTC_10x5_Format = RGBA_ASTC_10x5_Format;
  29515. exports.RGBA_ASTC_10x6_Format = RGBA_ASTC_10x6_Format;
  29516. exports.RGBA_ASTC_10x8_Format = RGBA_ASTC_10x8_Format;
  29517. exports.RGBA_ASTC_12x10_Format = RGBA_ASTC_12x10_Format;
  29518. exports.RGBA_ASTC_12x12_Format = RGBA_ASTC_12x12_Format;
  29519. exports.RGBA_ASTC_4x4_Format = RGBA_ASTC_4x4_Format;
  29520. exports.RGBA_ASTC_5x4_Format = RGBA_ASTC_5x4_Format;
  29521. exports.RGBA_ASTC_5x5_Format = RGBA_ASTC_5x5_Format;
  29522. exports.RGBA_ASTC_6x5_Format = RGBA_ASTC_6x5_Format;
  29523. exports.RGBA_ASTC_6x6_Format = RGBA_ASTC_6x6_Format;
  29524. exports.RGBA_ASTC_8x5_Format = RGBA_ASTC_8x5_Format;
  29525. exports.RGBA_ASTC_8x6_Format = RGBA_ASTC_8x6_Format;
  29526. exports.RGBA_ASTC_8x8_Format = RGBA_ASTC_8x8_Format;
  29527. exports.RGBA_BPTC_Format = RGBA_BPTC_Format;
  29528. exports.RGBA_ETC2_EAC_Format = RGBA_ETC2_EAC_Format;
  29529. exports.RGBA_PVRTC_2BPPV1_Format = RGBA_PVRTC_2BPPV1_Format;
  29530. exports.RGBA_PVRTC_4BPPV1_Format = RGBA_PVRTC_4BPPV1_Format;
  29531. exports.RGBA_S3TC_DXT1_Format = RGBA_S3TC_DXT1_Format;
  29532. exports.RGBA_S3TC_DXT3_Format = RGBA_S3TC_DXT3_Format;
  29533. exports.RGBA_S3TC_DXT5_Format = RGBA_S3TC_DXT5_Format;
  29534. exports.RGBFormat = RGBFormat;
  29535. exports.RGB_ETC1_Format = RGB_ETC1_Format;
  29536. exports.RGB_ETC2_Format = RGB_ETC2_Format;
  29537. exports.RGB_PVRTC_2BPPV1_Format = RGB_PVRTC_2BPPV1_Format;
  29538. exports.RGB_PVRTC_4BPPV1_Format = RGB_PVRTC_4BPPV1_Format;
  29539. exports.RGB_S3TC_DXT1_Format = RGB_S3TC_DXT1_Format;
  29540. exports.RGFormat = RGFormat;
  29541. exports.RGIntegerFormat = RGIntegerFormat;
  29542. exports.RawShaderMaterial = RawShaderMaterial;
  29543. exports.Ray = Ray;
  29544. exports.Raycaster = Raycaster;
  29545. exports.RectAreaLight = RectAreaLight;
  29546. exports.RedFormat = RedFormat;
  29547. exports.RedIntegerFormat = RedIntegerFormat;
  29548. exports.ReinhardToneMapping = ReinhardToneMapping;
  29549. exports.RepeatWrapping = RepeatWrapping;
  29550. exports.ReplaceStencilOp = ReplaceStencilOp;
  29551. exports.ReverseSubtractEquation = ReverseSubtractEquation;
  29552. exports.RingBufferGeometry = RingGeometry;
  29553. exports.RingGeometry = RingGeometry;
  29554. exports.SRGBColorSpace = SRGBColorSpace;
  29555. exports.Scene = Scene;
  29556. exports.ShaderChunk = ShaderChunk;
  29557. exports.ShaderLib = ShaderLib;
  29558. exports.ShaderMaterial = ShaderMaterial;
  29559. exports.ShadowMaterial = ShadowMaterial;
  29560. exports.Shape = Shape;
  29561. exports.ShapeBufferGeometry = ShapeGeometry;
  29562. exports.ShapeGeometry = ShapeGeometry;
  29563. exports.ShapePath = ShapePath;
  29564. exports.ShapeUtils = ShapeUtils;
  29565. exports.ShortType = ShortType;
  29566. exports.Skeleton = Skeleton;
  29567. exports.SkeletonHelper = SkeletonHelper;
  29568. exports.SkinnedMesh = SkinnedMesh;
  29569. exports.SmoothShading = SmoothShading;
  29570. exports.Source = Source;
  29571. exports.Sphere = Sphere;
  29572. exports.SphereBufferGeometry = SphereGeometry;
  29573. exports.SphereGeometry = SphereGeometry;
  29574. exports.Spherical = Spherical;
  29575. exports.SphericalHarmonics3 = SphericalHarmonics3;
  29576. exports.SplineCurve = SplineCurve;
  29577. exports.SpotLight = SpotLight;
  29578. exports.SpotLightHelper = SpotLightHelper;
  29579. exports.Sprite = Sprite;
  29580. exports.SpriteMaterial = SpriteMaterial;
  29581. exports.SrcAlphaFactor = SrcAlphaFactor;
  29582. exports.SrcAlphaSaturateFactor = SrcAlphaSaturateFactor;
  29583. exports.SrcColorFactor = SrcColorFactor;
  29584. exports.StaticCopyUsage = StaticCopyUsage;
  29585. exports.StaticDrawUsage = StaticDrawUsage;
  29586. exports.StaticReadUsage = StaticReadUsage;
  29587. exports.StereoCamera = StereoCamera;
  29588. exports.StreamCopyUsage = StreamCopyUsage;
  29589. exports.StreamDrawUsage = StreamDrawUsage;
  29590. exports.StreamReadUsage = StreamReadUsage;
  29591. exports.StringKeyframeTrack = StringKeyframeTrack;
  29592. exports.SubtractEquation = SubtractEquation;
  29593. exports.SubtractiveBlending = SubtractiveBlending;
  29594. exports.TOUCH = TOUCH;
  29595. exports.TangentSpaceNormalMap = TangentSpaceNormalMap;
  29596. exports.TetrahedronBufferGeometry = TetrahedronGeometry;
  29597. exports.TetrahedronGeometry = TetrahedronGeometry;
  29598. exports.TextGeometry = TextGeometry;
  29599. exports.Texture = Texture;
  29600. exports.TextureLoader = TextureLoader;
  29601. exports.TorusBufferGeometry = TorusGeometry;
  29602. exports.TorusGeometry = TorusGeometry;
  29603. exports.TorusKnotBufferGeometry = TorusKnotGeometry;
  29604. exports.TorusKnotGeometry = TorusKnotGeometry;
  29605. exports.Triangle = Triangle;
  29606. exports.TriangleFanDrawMode = TriangleFanDrawMode;
  29607. exports.TriangleStripDrawMode = TriangleStripDrawMode;
  29608. exports.TrianglesDrawMode = TrianglesDrawMode;
  29609. exports.TubeBufferGeometry = TubeGeometry;
  29610. exports.TubeGeometry = TubeGeometry;
  29611. exports.UVMapping = UVMapping;
  29612. exports.Uint16BufferAttribute = Uint16BufferAttribute;
  29613. exports.Uint32BufferAttribute = Uint32BufferAttribute;
  29614. exports.Uint8BufferAttribute = Uint8BufferAttribute;
  29615. exports.Uint8ClampedBufferAttribute = Uint8ClampedBufferAttribute;
  29616. exports.Uniform = Uniform;
  29617. exports.UniformsGroup = UniformsGroup;
  29618. exports.UniformsLib = UniformsLib;
  29619. exports.UniformsUtils = UniformsUtils;
  29620. exports.UnsignedByteType = UnsignedByteType;
  29621. exports.UnsignedInt248Type = UnsignedInt248Type;
  29622. exports.UnsignedIntType = UnsignedIntType;
  29623. exports.UnsignedShort4444Type = UnsignedShort4444Type;
  29624. exports.UnsignedShort5551Type = UnsignedShort5551Type;
  29625. exports.UnsignedShortType = UnsignedShortType;
  29626. exports.VSMShadowMap = VSMShadowMap;
  29627. exports.Vector2 = Vector2;
  29628. exports.Vector3 = Vector3;
  29629. exports.Vector4 = Vector4;
  29630. exports.VectorKeyframeTrack = VectorKeyframeTrack;
  29631. exports.VideoTexture = VideoTexture;
  29632. exports.WebGL1Renderer = WebGL1Renderer;
  29633. exports.WebGL3DRenderTarget = WebGL3DRenderTarget;
  29634. exports.WebGLArrayRenderTarget = WebGLArrayRenderTarget;
  29635. exports.WebGLCubeRenderTarget = WebGLCubeRenderTarget;
  29636. exports.WebGLMultipleRenderTargets = WebGLMultipleRenderTargets;
  29637. exports.WebGLMultisampleRenderTarget = WebGLMultisampleRenderTarget;
  29638. exports.WebGLRenderTarget = WebGLRenderTarget;
  29639. exports.WebGLRenderer = WebGLRenderer;
  29640. exports.WebGLUtils = WebGLUtils;
  29641. exports.WireframeGeometry = WireframeGeometry;
  29642. exports.WrapAroundEnding = WrapAroundEnding;
  29643. exports.ZeroCurvatureEnding = ZeroCurvatureEnding;
  29644. exports.ZeroFactor = ZeroFactor;
  29645. exports.ZeroSlopeEnding = ZeroSlopeEnding;
  29646. exports.ZeroStencilOp = ZeroStencilOp;
  29647. exports._SRGBAFormat = _SRGBAFormat;
  29648. exports.sRGBEncoding = sRGBEncoding;
  29649. Object.defineProperty(exports, '__esModule', { value: true });
  29650. }));
  29651. ;
  29652. THREE.HorizontalBlurShader = {
  29653. uniforms: {
  29654. tDiffuse: {
  29655. type: 't',
  29656. value: null,
  29657. },
  29658. h: {
  29659. type: 'f',
  29660. value: 1 / 512,
  29661. },
  29662. },
  29663. vertexShader: ['varying vec2 vUv;', 'void main() {', 'vUv = uv;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'),
  29664. fragmentShader: [
  29665. 'uniform sampler2D tDiffuse;',
  29666. 'uniform float h;',
  29667. 'varying vec2 vUv;',
  29668. 'void main() {',
  29669. 'vec4 sum = vec4( 0.0 );',
  29670. 'sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;',
  29671. 'sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;',
  29672. 'sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;',
  29673. 'sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;',
  29674. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;',
  29675. 'sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;',
  29676. 'sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;',
  29677. 'sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;',
  29678. 'sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;',
  29679. 'gl_FragColor = sum;',
  29680. '}',
  29681. ].join('\n'),
  29682. }
  29683. THREE.VerticalBlurShader = {
  29684. uniforms: {
  29685. tDiffuse: {
  29686. type: 't',
  29687. value: null,
  29688. },
  29689. v: {
  29690. type: 'f',
  29691. value: 1 / 512,
  29692. },
  29693. },
  29694. vertexShader: ['varying vec2 vUv;', 'void main() {', 'vUv = uv;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'),
  29695. fragmentShader: [
  29696. 'uniform sampler2D tDiffuse;',
  29697. 'uniform float v;',
  29698. 'varying vec2 vUv;',
  29699. 'void main() {',
  29700. 'vec4 sum = vec4( 0.0 );',
  29701. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;',
  29702. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;',
  29703. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;',
  29704. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;',
  29705. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;',
  29706. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;',
  29707. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;',
  29708. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;',
  29709. 'sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;',
  29710. 'gl_FragColor = sum;',
  29711. '}',
  29712. ].join('\n'),
  29713. }
  29714. THREE.ShaderPass = function (material, t) {
  29715. this.textureID = void 0 !== t ? t : 'tDiffuse'
  29716. if (material instanceof THREE.ShaderMaterial) {
  29717. this.uniforms = material.uniforms
  29718. this.material = material
  29719. } else if (material) {
  29720. this.uniforms = THREE.UniformsUtils.clone(material.uniforms)
  29721. this.material = new THREE.ShaderMaterial({
  29722. defines: material.defines || {},
  29723. uniforms: this.uniforms,
  29724. vertexShader: material.vertexShader,
  29725. fragmentShader: material.fragmentShader,
  29726. })
  29727. }
  29728. this.renderToScreen = !1
  29729. this.enabled = !0
  29730. this.needsSwap = !0
  29731. this.clear = !1
  29732. this.camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1)
  29733. this.scene = new THREE.Scene()
  29734. this.quad = new THREE.Mesh(new THREE.PlaneBufferGeometry(2, 2), null)
  29735. this.scene.add(this.quad)
  29736. }
  29737. THREE.ShaderPass.prototype = {
  29738. render:function(e, t, i, n) {
  29739. this.uniforms[this.textureID] && (this.uniforms[this.textureID].value = i)
  29740. this.quad.material = this.material
  29741. if (this.renderToScreen) {
  29742. e.render(this.scene, this.camera)
  29743. } else {
  29744. e.render(this.scene, this.camera, t, this.clear)
  29745. }
  29746. //this.renderToScreen ? e.render(this.scene, this.camera) : e.render(this.scene, this.camera, t, this.clear)
  29747. },
  29748. }
  29749. THREE.ImageUtils.crossOrigin = 'anonymous'
  29750. ;
  29751. !(function () {
  29752. if (('performance' in window == 0 && (window.performance = {}), 'now' in window.performance == 0)) {
  29753. var e = Date.now()
  29754. performance.timing && performance.timing.navigationStart && (e = performance.timing.navigationStart),
  29755. (window.performance.now = function () {
  29756. return Date.now() - e
  29757. })
  29758. }
  29759. })(),
  29760. (THREE.WebGLRenderer.prototype.paramThreeToGL = function (e) {
  29761. var t,
  29762. i = this.extensions,
  29763. r = this.getContext() // this.context
  29764. if (e === THREE.RepeatWrapping) return r.REPEAT
  29765. if (e === THREE.ClampToEdgeWrapping) return r.CLAMP_TO_EDGE
  29766. if (e === THREE.MirroredRepeatWrapping) return r.MIRRORED_REPEAT
  29767. if (e === THREE.NearestFilter) return r.NEAREST
  29768. if (e === THREE.NearestMipMapNearestFilter) return r.NEAREST_MIPMAP_NEAREST
  29769. if (e === THREE.NearestMipMapLinearFilter) return r.NEAREST_MIPMAP_LINEAR
  29770. if (e === THREE.LinearFilter) return r.LINEAR
  29771. if (e === THREE.LinearMipMapNearestFilter) return r.LINEAR_MIPMAP_NEAREST
  29772. if (e === THREE.LinearMipMapLinearFilter) return r.LINEAR_MIPMAP_LINEAR
  29773. if (e === THREE.UnsignedByteType) return r.UNSIGNED_BYTE
  29774. if (e === THREE.UnsignedShort4444Type) return r.UNSIGNED_SHORT_4_4_4_4
  29775. if (e === THREE.UnsignedShort5551Type) return r.UNSIGNED_SHORT_5_5_5_1
  29776. if (e === THREE.UnsignedShort565Type) return r.UNSIGNED_SHORT_5_6_5
  29777. if (e === THREE.ByteType) return r.BYTE
  29778. if (e === THREE.ShortType) return r.SHORT
  29779. if (e === THREE.UnsignedShortType) return r.UNSIGNED_SHORT
  29780. if (e === THREE.IntType) return r.INT
  29781. if (e === THREE.UnsignedIntType) return r.UNSIGNED_INT
  29782. if (e === THREE.FloatType) return r.FLOAT
  29783. if (e === THREE.HalfFloatType && i.get('OES_texture_half_float') !== null) return t.HALF_FLOAT_OES
  29784. if (e === THREE.AlphaFormat) return r.ALPHA
  29785. if (e === THREE.RGBFormat) return r.RGB
  29786. if (e === THREE.RGBAFormat) return r.RGBA
  29787. if (e === THREE.LuminanceFormat) return r.LUMINANCE
  29788. if (e === THREE.LuminanceAlphaFormat) return r.LUMINANCE_ALPHA
  29789. if (e === THREE.AddEquation) return r.FUNC_ADD
  29790. if (e === THREE.SubtractEquation) return r.FUNC_SUBTRACT
  29791. if (e === THREE.ReverseSubtractEquation) return r.FUNC_REVERSE_SUBTRACT
  29792. if (e === THREE.ZeroFactor) return r.ZERO
  29793. if (e === THREE.OneFactor) return r.ONE
  29794. if (e === THREE.SrcColorFactor) return r.SRC_COLOR
  29795. if (e === THREE.OneMinusSrcColorFactor) return r.ONE_MINUS_SRC_COLOR
  29796. if (e === THREE.SrcAlphaFactor) return r.SRC_ALPHA
  29797. if (e === THREE.OneMinusSrcAlphaFactor) return r.ONE_MINUS_SRC_ALPHA
  29798. if (e === THREE.DstAlphaFactor) return r.DST_ALPHA
  29799. if (e === THREE.OneMinusDstAlphaFactor) return r.ONE_MINUS_DST_ALPHA
  29800. if (e === THREE.DstColorFactor) return r.DST_COLOR
  29801. if (e === THREE.OneMinusDstColorFactor) return r.ONE_MINUS_DST_COLOR
  29802. if (e === THREE.SrcAlphaSaturateFactor) return r.SRC_ALPHA_SATURATE
  29803. if (((t = i.get('WEBGL_compressed_texture_s3tc')), null !== t)) {
  29804. if (e === THREE.RGB_S3TC_DXT1_Format) return t.COMPRESSED_RGB_S3TC_DXT1_EXT
  29805. if (e === THREE.RGBA_S3TC_DXT1_Format) return t.COMPRESSED_RGBA_S3TC_DXT1_EXT
  29806. if (e === THREE.RGBA_S3TC_DXT3_Format) return t.COMPRESSED_RGBA_S3TC_DXT3_EXT
  29807. if (e === THREE.RGBA_S3TC_DXT5_Format) return t.COMPRESSED_RGBA_S3TC_DXT5_EXT
  29808. }
  29809. if (((t = i.get('WEBGL_compressed_texture_pvrtc')), null !== t)) {
  29810. if (e === THREE.RGB_PVRTC_4BPPV1_Format) return t.COMPRESSED_RGB_PVRTC_4BPPV1_IMG
  29811. if (e === THREE.RGB_PVRTC_2BPPV1_Format) return t.COMPRESSED_RGB_PVRTC_2BPPV1_IMG
  29812. if (e === THREE.RGBA_PVRTC_4BPPV1_Format) return t.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
  29813. if (e === THREE.RGBA_PVRTC_2BPPV1_Format) return t.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
  29814. }
  29815. if (((t = i.get('WEBGL_compressed_texture_etc1')), null !== t && e === THREE.RGB_ETC1_Format)) return t.COMPRESSED_RGB_ETC1_WEBGL
  29816. if (((t = i.get('EXT_blend_minmax')), null !== t)) {
  29817. if (e === THREE.MinEquation) return t.MIN_EXT
  29818. if (e === THREE.MaxEquation) return t.MAX_EXT
  29819. }
  29820. return 0
  29821. }),
  29822. (THREE.WebGLState = function (e, t, i) {
  29823. var r = this,
  29824. o = new THREE.Vector4(),
  29825. a = e.getParameter(e.MAX_VERTEX_ATTRIBS),
  29826. s = new Uint8Array(a),
  29827. l = new Uint8Array(a),
  29828. c = new Uint8Array(a),
  29829. h = {},
  29830. u = null,
  29831. d = null,
  29832. p = null,
  29833. f = null,
  29834. g = null,
  29835. m = null,
  29836. v = null,
  29837. A = null,
  29838. y = !1,
  29839. C = null,
  29840. I = null,
  29841. E = null,
  29842. b = null,
  29843. w = null,
  29844. _ = null,
  29845. T = null,
  29846. x = null,
  29847. S = null,
  29848. M = null,
  29849. R = null,
  29850. P = null,
  29851. O = null,
  29852. L = null,
  29853. D = null,
  29854. N = e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),
  29855. B = void 0,
  29856. F = {},
  29857. V = new THREE.Vector4(),
  29858. U = null,
  29859. k = null,
  29860. H = new THREE.Vector4(),
  29861. G = new THREE.Vector4()
  29862. ;(this.init = function () {
  29863. this.clearColor(0, 0, 0, 1),
  29864. this.clearDepth(1),
  29865. this.clearStencil(0),
  29866. this.enable(e.DEPTH_TEST),
  29867. e.depthFunc(e.LEQUAL),
  29868. e.frontFace(e.CCW),
  29869. e.cullFace(e.BACK),
  29870. this.enable(e.CULL_FACE),
  29871. this.enable(e.BLEND),
  29872. e.blendEquation(e.FUNC_ADD),
  29873. e.blendFunc(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA)
  29874. }),
  29875. (this.initAttributes = function () {
  29876. for (var e = 0, t = s.length; e < t; e++) s[e] = 0
  29877. }),
  29878. (this.enableAttribute = function (i) {
  29879. if (((s[i] = 1), 0 === l[i] && (e.enableVertexAttribArray(i), (l[i] = 1)), 0 !== c[i])) {
  29880. var n = t.get('ANGLE_instanced_arrays')
  29881. n.vertexAttribDivisorANGLE(i, 0), (c[i] = 0)
  29882. }
  29883. }),
  29884. (this.enableAttributeAndDivisor = function (t, i, n) {
  29885. ;(s[t] = 1), 0 === l[t] && (e.enableVertexAttribArray(t), (l[t] = 1)), c[t] !== i && (n.vertexAttribDivisorANGLE(t, i), (c[t] = i))
  29886. }),
  29887. (this.disableUnusedAttributes = function () {
  29888. for (var t = 0, i = l.length; t < i; t++) l[t] !== s[t] && (e.disableVertexAttribArray(t), (l[t] = 0))
  29889. }),
  29890. (this.enable = function (t) {
  29891. h[t] !== !0 && (e.enable(t), (h[t] = !0))
  29892. }),
  29893. (this.disable = function (t) {
  29894. h[t] !== !1 && (e.disable(t), (h[t] = !1))
  29895. }),
  29896. (this.getCompressedTextureFormats = function () {
  29897. if (null === u && ((u = []), t.get('WEBGL_compressed_texture_pvrtc') || t.get('WEBGL_compressed_texture_s3tc') || t.get('WEBGL_compressed_texture_etc1')))
  29898. for (var i = e.getParameter(e.COMPRESSED_TEXTURE_FORMATS), n = 0; n < i.length; n++) u.push(i[n])
  29899. return u
  29900. }),
  29901. (this.setBlending = function (t, r, o, a, s, l, c, h) {
  29902. t === THREE.NoBlending ? this.disable(e.BLEND) : this.enable(e.BLEND),
  29903. (t === d && h === y) ||
  29904. (t === THREE.AdditiveBlending
  29905. ? h
  29906. ? (e.blendEquationSeparate(e.FUNC_ADD, e.FUNC_ADD), e.blendFuncSeparate(e.ONE, e.ONE, e.ONE, e.ONE))
  29907. : (e.blendEquation(e.FUNC_ADD), e.blendFunc(e.SRC_ALPHA, e.ONE))
  29908. : t === THREE.SubtractiveBlending
  29909. ? h
  29910. ? (e.blendEquationSeparate(e.FUNC_ADD, e.FUNC_ADD), e.blendFuncSeparate(e.ZERO, e.ZERO, e.ONE_MINUS_SRC_COLOR, e.ONE_MINUS_SRC_ALPHA))
  29911. : (e.blendEquation(e.FUNC_ADD), e.blendFunc(e.ZERO, e.ONE_MINUS_SRC_COLOR))
  29912. : t === THREE.MultiplyBlending
  29913. ? h
  29914. ? (e.blendEquationSeparate(e.FUNC_ADD, e.FUNC_ADD), e.blendFuncSeparate(e.ZERO, e.ZERO, e.SRC_COLOR, e.SRC_ALPHA))
  29915. : (e.blendEquation(e.FUNC_ADD), e.blendFunc(e.ZERO, e.SRC_COLOR))
  29916. : h
  29917. ? (e.blendEquationSeparate(e.FUNC_ADD, e.FUNC_ADD), e.blendFuncSeparate(e.ONE, e.ONE_MINUS_SRC_ALPHA, e.ONE, e.ONE_MINUS_SRC_ALPHA))
  29918. : (e.blendEquationSeparate(e.FUNC_ADD, e.FUNC_ADD), e.blendFuncSeparate(e.SRC_ALPHA, e.ONE_MINUS_SRC_ALPHA, e.ONE, e.ONE_MINUS_SRC_ALPHA)),
  29919. (d = t),
  29920. (y = h)),
  29921. t === THREE.CustomBlending
  29922. ? ((s = s || r),
  29923. (l = l || o),
  29924. (c = c || a),
  29925. (r === p && s === m) || (e.blendEquationSeparate(i(r), i(s)), (p = r), (m = s)),
  29926. (o === f && a === g && l === v && c === A) || (e.blendFuncSeparate(i(o), i(a), i(l), i(c)), (f = o), (g = a), (v = l), (A = c)))
  29927. : ((p = null), (f = null), (g = null), (m = null), (v = null), (A = null))
  29928. }),
  29929. (this.setDepthFunc = function (t) {
  29930. if (C !== t) {
  29931. if (t)
  29932. switch (t) {
  29933. case THREE.NeverDepth:
  29934. e.depthFunc(e.NEVER)
  29935. break
  29936. case THREE.AlwaysDepth:
  29937. e.depthFunc(e.ALWAYS)
  29938. break
  29939. case THREE.LessDepth:
  29940. e.depthFunc(e.LESS)
  29941. break
  29942. case THREE.LessEqualDepth:
  29943. e.depthFunc(e.LEQUAL)
  29944. break
  29945. case THREE.EqualDepth:
  29946. e.depthFunc(e.EQUAL)
  29947. break
  29948. case THREE.GreaterEqualDepth:
  29949. e.depthFunc(e.GEQUAL)
  29950. break
  29951. case THREE.GreaterDepth:
  29952. e.depthFunc(e.GREATER)
  29953. break
  29954. case THREE.NotEqualDepth:
  29955. e.depthFunc(e.NOTEQUAL)
  29956. break
  29957. default:
  29958. e.depthFunc(e.LEQUAL)
  29959. }
  29960. else e.depthFunc(e.LEQUAL)
  29961. C = t
  29962. }
  29963. }),
  29964. (this.setDepthTest = function (t) {
  29965. t ? this.enable(e.DEPTH_TEST) : this.disable(e.DEPTH_TEST)
  29966. }),
  29967. (this.setDepthWrite = function (t) {
  29968. I !== t && (e.depthMask(t), (I = t))
  29969. }),
  29970. (this.setColorWrite = function (t) {
  29971. E !== t && (e.colorMask(t, t, t, t), (E = t))
  29972. }),
  29973. (this.setStencilFunc = function (t, i, n) {
  29974. ;(w === t && _ === i && T === n) || (e.stencilFunc(t, i, n), (w = t), (_ = i), (T = n))
  29975. }),
  29976. (this.setStencilOp = function (t, i, n) {
  29977. ;(x === t && S === i && M === n) || (e.stencilOp(t, i, n), (x = t), (S = i), (M = n))
  29978. }),
  29979. (this.setStencilTest = function (t) {
  29980. t ? this.enable(e.STENCIL_TEST) : this.disable(e.STENCIL_TEST)
  29981. }),
  29982. (this.setStencilWrite = function (t) {
  29983. b !== t && (e.stencilMask(t), (b = t))
  29984. }),
  29985. (this.setFlipSided = function (t) {
  29986. R !== t && (t ? e.frontFace(e.CW) : e.frontFace(e.CCW), (R = t))
  29987. }),
  29988. (this.setLineWidth = function (t) {
  29989. t !== P && (e.lineWidth(t), (P = t))
  29990. }),
  29991. (this.setPolygonOffset = function (t, i, n) {
  29992. t ? this.enable(e.POLYGON_OFFSET_FILL) : this.disable(e.POLYGON_OFFSET_FILL), !t || (O === i && L === n) || (e.polygonOffset(i, n), (O = i), (L = n))
  29993. }),
  29994. (this.getScissorTest = function () {
  29995. return D
  29996. }),
  29997. (this.setScissorTest = function (t) {
  29998. ;(D = t), t ? this.enable(e.SCISSOR_TEST) : this.disable(e.SCISSOR_TEST)
  29999. }),
  30000. (this.activeTexture = function (t) {
  30001. void 0 === t && (t = e.TEXTURE0 + N - 1), B !== t && (e.activeTexture(t), (B = t))
  30002. }),
  30003. (this.bindTexture = function (t, i) {
  30004. void 0 === B && r.activeTexture()
  30005. var n = F[B]
  30006. void 0 === n &&
  30007. ((n = {
  30008. type: void 0,
  30009. texture: void 0,
  30010. }),
  30011. (F[B] = n)),
  30012. (n.type === t && n.texture === i) || (e.bindTexture(t, i), (n.type = t), (n.texture = i))
  30013. }),
  30014. (this.compressedTexImage2D = function () {
  30015. try {
  30016. e.compressedTexImage2D.apply(e, arguments)
  30017. } catch (e) {
  30018. console.error(e)
  30019. }
  30020. }),
  30021. (this.texImage2D = function () {
  30022. try {
  30023. e.texImage2D.apply(e, arguments)
  30024. } catch (e) {
  30025. console.error(e)
  30026. }
  30027. }),
  30028. (this.clearColor = function (t, i, n, r) {
  30029. o.set(t, i, n, r), V.equals(o) === !1 && (e.clearColor(t, i, n, r), V.copy(o))
  30030. }),
  30031. (this.clearDepth = function (t) {
  30032. U !== t && (e.clearDepth(t), (U = t))
  30033. }),
  30034. (this.clearStencil = function (t) {
  30035. k !== t && (e.clearStencil(t), (k = t))
  30036. }),
  30037. (this.scissor = function (t) {
  30038. H.equals(t) === !1 && (e.scissor(t.x, t.y, t.z, t.w), H.copy(t))
  30039. }),
  30040. (this.viewport = function (t) {
  30041. G.equals(t) === !1 && (e.viewport(t.x, t.y, t.z, t.w), G.copy(t))
  30042. }),
  30043. (this.reset = function () {
  30044. for (var t = 0; t < l.length; t++) 1 === l[t] && (e.disableVertexAttribArray(t), (l[t] = 0))
  30045. ;(h = {}), (u = null), (B = void 0), (F = {}), (d = null), (E = null), (I = null), (b = null), (R = null)
  30046. })
  30047. })
  30048. ;
  30049. ;(function () {
  30050. /**
  30051. * Full-screen textured quad shader
  30052. */
  30053. const CopyShader = {
  30054. uniforms: {
  30055. tDiffuse: {
  30056. value: null,
  30057. },
  30058. opacity: {
  30059. value: 1.0,
  30060. },
  30061. },
  30062. vertexShader:
  30063. /* glsl */
  30064. `
  30065. varying vec2 vUv;
  30066. void main() {
  30067. vUv = uv;
  30068. gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  30069. }`,
  30070. fragmentShader:
  30071. /* glsl */
  30072. `
  30073. uniform float opacity;
  30074. uniform sampler2D tDiffuse;
  30075. varying vec2 vUv;
  30076. void main() {
  30077. gl_FragColor = texture2D( tDiffuse, vUv );
  30078. gl_FragColor.a *= opacity;
  30079. }`,
  30080. }
  30081. THREE.CopyShader = CopyShader
  30082. })()
  30083. ;
  30084. ;(function () {
  30085. /**
  30086. * Two pass Gaussian blur filter (horizontal and vertical blur shaders)
  30087. * - see http://www.cake23.de/traveling-wavefronts-lit-up.html
  30088. *
  30089. * - 9 samples per pass
  30090. * - standard deviation 2.7
  30091. * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  30092. */
  30093. const HorizontalBlurShader = {
  30094. uniforms: {
  30095. tDiffuse: {
  30096. value: null,
  30097. },
  30098. h: {
  30099. value: 1.0 / 512.0,
  30100. },
  30101. },
  30102. vertexShader:
  30103. /* glsl */
  30104. `
  30105. varying vec2 vUv;
  30106. void main() {
  30107. vUv = uv;
  30108. gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  30109. }`,
  30110. fragmentShader:
  30111. /* glsl */
  30112. `
  30113. uniform sampler2D tDiffuse;
  30114. uniform float h;
  30115. varying vec2 vUv;
  30116. void main() {
  30117. vec4 sum = vec4( 0.0 );
  30118. sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;
  30119. sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;
  30120. sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;
  30121. sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;
  30122. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
  30123. sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;
  30124. sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;
  30125. sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;
  30126. sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;
  30127. gl_FragColor = sum;
  30128. }`,
  30129. }
  30130. THREE.HorizontalBlurShader = HorizontalBlurShader
  30131. })()
  30132. ;
  30133. ;(function () {
  30134. /**
  30135. * Two pass Gaussian blur filter (horizontal and vertical blur shaders)
  30136. * - see http://www.cake23.de/traveling-wavefronts-lit-up.html
  30137. *
  30138. * - 9 samples per pass
  30139. * - standard deviation 2.7
  30140. * - "h" and "v" parameters should be set to "1 / width" and "1 / height"
  30141. */
  30142. const VerticalBlurShader = {
  30143. uniforms: {
  30144. tDiffuse: {
  30145. value: null,
  30146. },
  30147. v: {
  30148. value: 1.0 / 512.0,
  30149. },
  30150. },
  30151. vertexShader:
  30152. /* glsl */
  30153. `
  30154. varying vec2 vUv;
  30155. void main() {
  30156. vUv = uv;
  30157. gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
  30158. }`,
  30159. fragmentShader:
  30160. /* glsl */
  30161. `
  30162. uniform sampler2D tDiffuse;
  30163. uniform float v;
  30164. varying vec2 vUv;
  30165. void main() {
  30166. vec4 sum = vec4( 0.0 );
  30167. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;
  30168. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;
  30169. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;
  30170. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;
  30171. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;
  30172. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;
  30173. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;
  30174. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;
  30175. sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;
  30176. gl_FragColor = sum;
  30177. }`,
  30178. }
  30179. THREE.VerticalBlurShader = VerticalBlurShader
  30180. })()
  30181. ;
  30182. ;(function () {
  30183. class EffectComposer {
  30184. constructor(renderer, renderTarget) {
  30185. this.renderer = renderer
  30186. if (renderTarget === undefined) {
  30187. const size = renderer.getSize(new THREE.Vector2())
  30188. this._pixelRatio = renderer.getPixelRatio()
  30189. this._width = size.width
  30190. this._height = size.height
  30191. renderTarget = new THREE.WebGLRenderTarget(this._width * this._pixelRatio, this._height * this._pixelRatio)
  30192. renderTarget.texture.name = 'EffectComposer.rt1'
  30193. } else {
  30194. this._pixelRatio = 1
  30195. this._width = renderTarget.width
  30196. this._height = renderTarget.height
  30197. }
  30198. this.renderTarget1 = renderTarget
  30199. this.renderTarget2 = renderTarget.clone()
  30200. this.renderTarget2.texture.name = 'EffectComposer.rt2'
  30201. this.writeBuffer = this.renderTarget1
  30202. this.readBuffer = this.renderTarget2
  30203. this.renderToScreen = true
  30204. this.passes = [] // dependencies
  30205. if (THREE.CopyShader === undefined) {
  30206. console.error('THREE.EffectComposer relies on THREE.CopyShader')
  30207. }
  30208. if (THREE.ShaderPass === undefined) {
  30209. console.error('THREE.EffectComposer relies on THREE.ShaderPass')
  30210. }
  30211. this.copyPass = new THREE.ShaderPass(THREE.CopyShader)
  30212. this.clock = new THREE.Clock()
  30213. }
  30214. swapBuffers() {
  30215. const tmp = this.readBuffer
  30216. this.readBuffer = this.writeBuffer
  30217. this.writeBuffer = tmp
  30218. }
  30219. addPass(pass) {
  30220. this.passes.push(pass)
  30221. pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio)
  30222. }
  30223. insertPass(pass, index) {
  30224. this.passes.splice(index, 0, pass)
  30225. pass.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio)
  30226. }
  30227. removePass(pass) {
  30228. const index = this.passes.indexOf(pass)
  30229. if (index !== -1) {
  30230. this.passes.splice(index, 1)
  30231. }
  30232. }
  30233. isLastEnabledPass(passIndex) {
  30234. for (let i = passIndex + 1; i < this.passes.length; i++) {
  30235. if (this.passes[i].enabled) {
  30236. return false
  30237. }
  30238. }
  30239. return true
  30240. }
  30241. render(deltaTime) {
  30242. // deltaTime value is in seconds
  30243. if (deltaTime === undefined) {
  30244. deltaTime = this.clock.getDelta()
  30245. }
  30246. const currentRenderTarget = this.renderer.getRenderTarget()
  30247. let maskActive = false
  30248. for (let i = 0, il = this.passes.length; i < il; i++) {
  30249. const pass = this.passes[i]
  30250. if (pass.enabled === false) continue
  30251. pass.renderToScreen = this.renderToScreen && this.isLastEnabledPass(i)
  30252. pass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime, maskActive)
  30253. if (pass.needsSwap) {
  30254. if (maskActive) {
  30255. const context = this.renderer.getContext()
  30256. const stencil = this.renderer.state.buffers.stencil //context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );
  30257. stencil.setFunc(context.NOTEQUAL, 1, 0xffffffff)
  30258. this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, deltaTime) //context.stencilFunc( context.EQUAL, 1, 0xffffffff );
  30259. stencil.setFunc(context.EQUAL, 1, 0xffffffff)
  30260. }
  30261. this.swapBuffers()
  30262. }
  30263. if (THREE.MaskPass !== undefined) {
  30264. if (pass instanceof THREE.MaskPass) {
  30265. maskActive = true
  30266. } else if (pass instanceof THREE.ClearMaskPass) {
  30267. maskActive = false
  30268. }
  30269. }
  30270. }
  30271. this.renderer.setRenderTarget(currentRenderTarget)
  30272. }
  30273. reset(renderTarget) {
  30274. if (renderTarget === undefined) {
  30275. const size = this.renderer.getSize(new THREE.Vector2())
  30276. this._pixelRatio = this.renderer.getPixelRatio()
  30277. this._width = size.width
  30278. this._height = size.height
  30279. renderTarget = this.renderTarget1.clone()
  30280. renderTarget.setSize(this._width * this._pixelRatio, this._height * this._pixelRatio)
  30281. }
  30282. this.renderTarget1.dispose()
  30283. this.renderTarget2.dispose()
  30284. this.renderTarget1 = renderTarget
  30285. this.renderTarget2 = renderTarget.clone()
  30286. this.writeBuffer = this.renderTarget1
  30287. this.readBuffer = this.renderTarget2
  30288. }
  30289. setSize(width, height) {
  30290. this._width = width
  30291. this._height = height
  30292. const effectiveWidth = this._width * this._pixelRatio
  30293. const effectiveHeight = this._height * this._pixelRatio
  30294. this.renderTarget1.setSize(effectiveWidth, effectiveHeight)
  30295. this.renderTarget2.setSize(effectiveWidth, effectiveHeight)
  30296. for (let i = 0; i < this.passes.length; i++) {
  30297. this.passes[i].setSize(effectiveWidth, effectiveHeight)
  30298. }
  30299. }
  30300. setPixelRatio(pixelRatio) {
  30301. this._pixelRatio = pixelRatio
  30302. this.setSize(this._width, this._height)
  30303. }
  30304. }
  30305. class Pass {
  30306. constructor() {
  30307. // if set to true, the pass is processed by the composer
  30308. this.enabled = true // if set to true, the pass indicates to swap read and write buffer after rendering
  30309. this.needsSwap = true // if set to true, the pass clears its buffer before rendering
  30310. this.clear = false // if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.
  30311. this.renderToScreen = false
  30312. }
  30313. setSize() {}
  30314. render() {
  30315. console.error('THREE.Pass: .render() must be implemented in derived pass.')
  30316. }
  30317. } // Helper for passes that need to fill the viewport with a single quad.
  30318. const _camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1) // https://github.com/mrdoob/three.js/pull/21358
  30319. const _geometry = new THREE.BufferGeometry()
  30320. _geometry.setAttribute('position', new THREE.Float32BufferAttribute([-1, 3, 0, -1, -1, 0, 3, -1, 0], 3))
  30321. _geometry.setAttribute('uv', new THREE.Float32BufferAttribute([0, 2, 0, 0, 2, 0], 2))
  30322. class FullScreenQuad {
  30323. constructor(material) {
  30324. this._mesh = new THREE.Mesh(_geometry, material)
  30325. }
  30326. dispose() {
  30327. this._mesh.geometry.dispose()
  30328. }
  30329. render(renderer) {
  30330. renderer.render(this._mesh, _camera)
  30331. }
  30332. get material() {
  30333. return this._mesh.material
  30334. }
  30335. set material(value) {
  30336. this._mesh.material = value
  30337. }
  30338. }
  30339. THREE.EffectComposer = EffectComposer
  30340. THREE.FullScreenQuad = FullScreenQuad
  30341. THREE.Pass = Pass
  30342. })()
  30343. ;
  30344. ;(function () {
  30345. class MaskPass extends THREE.Pass {
  30346. constructor(scene, camera) {
  30347. super()
  30348. this.scene = scene
  30349. this.camera = camera
  30350. this.clear = true
  30351. this.needsSwap = false
  30352. this.inverse = false
  30353. }
  30354. render(
  30355. renderer,
  30356. writeBuffer,
  30357. readBuffer
  30358. /*, deltaTime, maskActive */
  30359. ) {
  30360. const context = renderer.getContext()
  30361. const state = renderer.state // don't update color or depth
  30362. state.buffers.color.setMask(false)
  30363. state.buffers.depth.setMask(false) // lock buffers
  30364. state.buffers.color.setLocked(true)
  30365. state.buffers.depth.setLocked(true) // set up stencil
  30366. let writeValue, clearValue
  30367. if (this.inverse) {
  30368. writeValue = 0
  30369. clearValue = 1
  30370. } else {
  30371. writeValue = 1
  30372. clearValue = 0
  30373. }
  30374. state.buffers.stencil.setTest(true)
  30375. state.buffers.stencil.setOp(context.REPLACE, context.REPLACE, context.REPLACE)
  30376. state.buffers.stencil.setFunc(context.ALWAYS, writeValue, 0xffffffff)
  30377. state.buffers.stencil.setClear(clearValue)
  30378. state.buffers.stencil.setLocked(true) // draw into the stencil buffer
  30379. renderer.setRenderTarget(readBuffer)
  30380. if (this.clear) renderer.clear()
  30381. renderer.render(this.scene, this.camera)
  30382. renderer.setRenderTarget(writeBuffer)
  30383. if (this.clear) renderer.clear()
  30384. renderer.render(this.scene, this.camera) // unlock color and depth buffer for subsequent rendering
  30385. state.buffers.color.setLocked(false)
  30386. state.buffers.depth.setLocked(false) // only render where stencil is set to 1
  30387. state.buffers.stencil.setLocked(false)
  30388. state.buffers.stencil.setFunc(context.EQUAL, 1, 0xffffffff) // draw if == 1
  30389. state.buffers.stencil.setOp(context.KEEP, context.KEEP, context.KEEP)
  30390. state.buffers.stencil.setLocked(true)
  30391. }
  30392. }
  30393. class ClearMaskPass extends THREE.Pass {
  30394. constructor() {
  30395. super()
  30396. this.needsSwap = false
  30397. }
  30398. render(
  30399. renderer
  30400. /*, writeBuffer, readBuffer, deltaTime, maskActive */
  30401. ) {
  30402. renderer.state.buffers.stencil.setLocked(false)
  30403. renderer.state.buffers.stencil.setTest(false)
  30404. }
  30405. }
  30406. THREE.ClearMaskPass = ClearMaskPass
  30407. THREE.MaskPass = MaskPass
  30408. })()
  30409. ;
  30410. ;(function () {
  30411. class RenderPass extends THREE.Pass {
  30412. constructor(scene, camera, overrideMaterial, clearColor, clearAlpha) {
  30413. super()
  30414. this.scene = scene
  30415. this.camera = camera
  30416. this.overrideMaterial = overrideMaterial
  30417. this.clearColor = clearColor
  30418. this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 0
  30419. this.clear = true
  30420. this.clearDepth = false
  30421. this.needsSwap = false
  30422. this._oldClearColor = new THREE.Color()
  30423. }
  30424. render(
  30425. renderer,
  30426. writeBuffer,
  30427. readBuffer
  30428. /*, deltaTime, maskActive */
  30429. ) {
  30430. const oldAutoClear = renderer.autoClear
  30431. renderer.autoClear = false
  30432. let oldClearAlpha, oldOverrideMaterial
  30433. if (this.overrideMaterial !== undefined) {
  30434. oldOverrideMaterial = this.scene.overrideMaterial
  30435. this.scene.overrideMaterial = this.overrideMaterial
  30436. }
  30437. if (this.clearColor) {
  30438. renderer.getClearColor(this._oldClearColor)
  30439. oldClearAlpha = renderer.getClearAlpha()
  30440. renderer.setClearColor(this.clearColor, this.clearAlpha)
  30441. }
  30442. if (this.clearDepth) {
  30443. renderer.clearDepth()
  30444. }
  30445. renderer.setRenderTarget(this.renderToScreen ? null : readBuffer) // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
  30446. if (this.clear) renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil)
  30447. renderer.render(this.scene, this.camera)
  30448. if (this.clearColor) {
  30449. renderer.setClearColor(this._oldClearColor, oldClearAlpha)
  30450. }
  30451. if (this.overrideMaterial !== undefined) {
  30452. this.scene.overrideMaterial = oldOverrideMaterial
  30453. }
  30454. renderer.autoClear = oldAutoClear
  30455. }
  30456. }
  30457. THREE.RenderPass = RenderPass
  30458. })()
  30459. ;
  30460. ;(function () {
  30461. class ShaderPass extends THREE.Pass {
  30462. constructor(shader, textureID) {
  30463. super()
  30464. this.textureID = textureID !== undefined ? textureID : 'tDiffuse'
  30465. if (shader instanceof THREE.ShaderMaterial) {
  30466. this.uniforms = shader.uniforms
  30467. this.material = shader
  30468. } else if (shader) {
  30469. this.uniforms = THREE.UniformsUtils.clone(shader.uniforms)
  30470. this.material = new THREE.ShaderMaterial({
  30471. defines: Object.assign({}, shader.defines),
  30472. uniforms: this.uniforms,
  30473. vertexShader: shader.vertexShader,
  30474. fragmentShader: shader.fragmentShader,
  30475. })
  30476. }
  30477. this.fsQuad = new THREE.FullScreenQuad(this.material)
  30478. }
  30479. render(
  30480. renderer,
  30481. writeBuffer,
  30482. readBuffer
  30483. /*, deltaTime, maskActive */
  30484. ) {
  30485. if (this.uniforms[this.textureID]) {
  30486. this.uniforms[this.textureID].value = readBuffer.texture
  30487. }
  30488. this.fsQuad.material = this.material
  30489. if (this.renderToScreen) {
  30490. renderer.setRenderTarget(null)
  30491. this.fsQuad.render(renderer)
  30492. } else {
  30493. renderer.setRenderTarget(writeBuffer) // TODO: Avoid using autoClear properties, see https://github.com/mrdoob/three.js/pull/15571#issuecomment-465669600
  30494. if (this.clear) renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil)
  30495. this.fsQuad.render(renderer)
  30496. }
  30497. }
  30498. }
  30499. THREE.ShaderPass = ShaderPass
  30500. })()
  30501. ;
  30502. ;(function () {
  30503. class GLTFLoader extends THREE.Loader {
  30504. constructor(manager) {
  30505. super(manager)
  30506. this.dracoLoader = null
  30507. this.ktx2Loader = null
  30508. this.meshoptDecoder = null
  30509. this.pluginCallbacks = []
  30510. this.register(function (parser) {
  30511. return new GLTFMaterialsClearcoatExtension(parser)
  30512. })
  30513. this.register(function (parser) {
  30514. return new GLTFTextureBasisUExtension(parser)
  30515. })
  30516. this.register(function (parser) {
  30517. return new GLTFTextureWebPExtension(parser)
  30518. })
  30519. this.register(function (parser) {
  30520. return new GLTFMaterialsSheenExtension(parser)
  30521. })
  30522. this.register(function (parser) {
  30523. return new GLTFMaterialsTransmissionExtension(parser)
  30524. })
  30525. this.register(function (parser) {
  30526. return new GLTFMaterialsVolumeExtension(parser)
  30527. })
  30528. this.register(function (parser) {
  30529. return new GLTFMaterialsIorExtension(parser)
  30530. })
  30531. this.register(function (parser) {
  30532. return new GLTFMaterialsEmissiveStrengthExtension(parser)
  30533. })
  30534. this.register(function (parser) {
  30535. return new GLTFMaterialsSpecularExtension(parser)
  30536. })
  30537. this.register(function (parser) {
  30538. return new GLTFMaterialsIridescenceExtension(parser)
  30539. })
  30540. this.register(function (parser) {
  30541. return new GLTFLightsExtension(parser)
  30542. })
  30543. this.register(function (parser) {
  30544. return new GLTFMeshoptCompression(parser)
  30545. })
  30546. }
  30547. load(url, onLoad, onProgress, onError) {
  30548. const scope = this
  30549. let resourcePath
  30550. if (this.resourcePath !== '') {
  30551. resourcePath = this.resourcePath
  30552. } else if (this.path !== '') {
  30553. resourcePath = this.path
  30554. } else {
  30555. resourcePath = THREE.LoaderUtils.extractUrlBase(url)
  30556. } // Tells the LoadingManager to track an extra item, which resolves after
  30557. // the model is fully loaded. This means the count of items loaded will
  30558. // be incorrect, but ensures manager.onLoad() does not fire early.
  30559. this.manager.itemStart(url)
  30560. const _onError = function (e) {
  30561. if (onError) {
  30562. onError(e)
  30563. } else {
  30564. console.error(e)
  30565. }
  30566. scope.manager.itemError(url)
  30567. scope.manager.itemEnd(url)
  30568. }
  30569. const loader = new THREE.FileLoader(this.manager)
  30570. loader.setPath(this.path)
  30571. loader.setResponseType('arraybuffer')
  30572. loader.setRequestHeader(this.requestHeader)
  30573. loader.setWithCredentials(this.withCredentials)
  30574. loader.load(
  30575. url,
  30576. function (data) {
  30577. try {
  30578. scope.parse(
  30579. data,
  30580. resourcePath,
  30581. function (gltf) {
  30582. onLoad(gltf)
  30583. scope.manager.itemEnd(url)
  30584. },
  30585. _onError
  30586. )
  30587. } catch (e) {
  30588. _onError(e)
  30589. }
  30590. },
  30591. onProgress,
  30592. _onError
  30593. )
  30594. }
  30595. setDRACOLoader(dracoLoader) {
  30596. this.dracoLoader = dracoLoader
  30597. return this
  30598. }
  30599. setDDSLoader() {
  30600. throw new Error('THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".')
  30601. }
  30602. setKTX2Loader(ktx2Loader) {
  30603. this.ktx2Loader = ktx2Loader
  30604. return this
  30605. }
  30606. setMeshoptDecoder(meshoptDecoder) {
  30607. this.meshoptDecoder = meshoptDecoder
  30608. return this
  30609. }
  30610. register(callback) {
  30611. if (this.pluginCallbacks.indexOf(callback) === -1) {
  30612. this.pluginCallbacks.push(callback)
  30613. }
  30614. return this
  30615. }
  30616. unregister(callback) {
  30617. if (this.pluginCallbacks.indexOf(callback) !== -1) {
  30618. this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(callback), 1)
  30619. }
  30620. return this
  30621. }
  30622. parse(data, path, onLoad, onError) {
  30623. let content
  30624. const extensions = {}
  30625. const plugins = {}
  30626. if (typeof data === 'string') {
  30627. content = data
  30628. } else {
  30629. const magic = THREE.LoaderUtils.decodeText(new Uint8Array(data, 0, 4))
  30630. if (magic === BINARY_EXTENSION_HEADER_MAGIC) {
  30631. try {
  30632. extensions[EXTENSIONS.KHR_BINARY_GLTF] = new GLTFBinaryExtension(data)
  30633. } catch (error) {
  30634. if (onError) onError(error)
  30635. return
  30636. }
  30637. content = extensions[EXTENSIONS.KHR_BINARY_GLTF].content
  30638. } else {
  30639. content = THREE.LoaderUtils.decodeText(new Uint8Array(data))
  30640. }
  30641. }
  30642. const json = JSON.parse(content)
  30643. if (json.asset === undefined || json.asset.version[0] < 2) {
  30644. if (onError) onError(new Error('THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported.'))
  30645. return
  30646. }
  30647. const parser = new GLTFParser(json, {
  30648. path: path || this.resourcePath || '',
  30649. crossOrigin: this.crossOrigin,
  30650. requestHeader: this.requestHeader,
  30651. manager: this.manager,
  30652. ktx2Loader: this.ktx2Loader,
  30653. meshoptDecoder: this.meshoptDecoder,
  30654. })
  30655. parser.fileLoader.setRequestHeader(this.requestHeader)
  30656. for (let i = 0; i < this.pluginCallbacks.length; i++) {
  30657. const plugin = this.pluginCallbacks[i](parser)
  30658. plugins[plugin.name] = plugin // Workaround to avoid determining as unknown extension
  30659. // in addUnknownExtensionsToUserData().
  30660. // Remove this workaround if we move all the existing
  30661. // extension handlers to plugin system
  30662. extensions[plugin.name] = true
  30663. }
  30664. if (json.extensionsUsed) {
  30665. for (let i = 0; i < json.extensionsUsed.length; ++i) {
  30666. const extensionName = json.extensionsUsed[i]
  30667. const extensionsRequired = json.extensionsRequired || []
  30668. switch (extensionName) {
  30669. case EXTENSIONS.KHR_MATERIALS_UNLIT:
  30670. extensions[extensionName] = new GLTFMaterialsUnlitExtension()
  30671. break
  30672. case EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS:
  30673. extensions[extensionName] = new GLTFMaterialsPbrSpecularGlossinessExtension()
  30674. break
  30675. case EXTENSIONS.KHR_DRACO_MESH_COMPRESSION:
  30676. extensions[extensionName] = new GLTFDracoMeshCompressionExtension(json, this.dracoLoader)
  30677. break
  30678. case EXTENSIONS.KHR_TEXTURE_TRANSFORM:
  30679. extensions[extensionName] = new GLTFTextureTransformExtension()
  30680. break
  30681. case EXTENSIONS.KHR_MESH_QUANTIZATION:
  30682. extensions[extensionName] = new GLTFMeshQuantizationExtension()
  30683. break
  30684. default:
  30685. if (extensionsRequired.indexOf(extensionName) >= 0 && plugins[extensionName] === undefined) {
  30686. console.warn('THREE.GLTFLoader: Unknown extension "' + extensionName + '".')
  30687. }
  30688. }
  30689. }
  30690. }
  30691. parser.setExtensions(extensions)
  30692. parser.setPlugins(plugins)
  30693. parser.parse(onLoad, onError)
  30694. }
  30695. parseAsync(data, path) {
  30696. const scope = this
  30697. return new Promise(function (resolve, reject) {
  30698. scope.parse(data, path, resolve, reject)
  30699. })
  30700. }
  30701. }
  30702. /* GLTFREGISTRY */
  30703. function GLTFRegistry() {
  30704. let objects = {}
  30705. return {
  30706. get: function (key) {
  30707. return objects[key]
  30708. },
  30709. add: function (key, object) {
  30710. objects[key] = object
  30711. },
  30712. remove: function (key) {
  30713. delete objects[key]
  30714. },
  30715. removeAll: function () {
  30716. objects = {}
  30717. },
  30718. }
  30719. }
  30720. /*********************************/
  30721. /********** EXTENSIONS ***********/
  30722. /*********************************/
  30723. const EXTENSIONS = {
  30724. KHR_BINARY_GLTF: 'KHR_binary_glTF',
  30725. KHR_DRACO_MESH_COMPRESSION: 'KHR_draco_mesh_compression',
  30726. KHR_LIGHTS_PUNCTUAL: 'KHR_lights_punctual',
  30727. KHR_MATERIALS_CLEARCOAT: 'KHR_materials_clearcoat',
  30728. KHR_MATERIALS_IOR: 'KHR_materials_ior',
  30729. KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS: 'KHR_materials_pbrSpecularGlossiness',
  30730. KHR_MATERIALS_SHEEN: 'KHR_materials_sheen',
  30731. KHR_MATERIALS_SPECULAR: 'KHR_materials_specular',
  30732. KHR_MATERIALS_TRANSMISSION: 'KHR_materials_transmission',
  30733. KHR_MATERIALS_IRIDESCENCE: 'KHR_materials_iridescence',
  30734. KHR_MATERIALS_UNLIT: 'KHR_materials_unlit',
  30735. KHR_MATERIALS_VOLUME: 'KHR_materials_volume',
  30736. KHR_TEXTURE_BASISU: 'KHR_texture_basisu',
  30737. KHR_TEXTURE_TRANSFORM: 'KHR_texture_transform',
  30738. KHR_MESH_QUANTIZATION: 'KHR_mesh_quantization',
  30739. KHR_MATERIALS_EMISSIVE_STRENGTH: 'KHR_materials_emissive_strength',
  30740. EXT_TEXTURE_WEBP: 'EXT_texture_webp',
  30741. EXT_MESHOPT_COMPRESSION: 'EXT_meshopt_compression',
  30742. }
  30743. /**
  30744. * Punctual Lights Extension
  30745. *
  30746. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_lights_punctual
  30747. */
  30748. class GLTFLightsExtension {
  30749. constructor(parser) {
  30750. this.parser = parser
  30751. this.name = EXTENSIONS.KHR_LIGHTS_PUNCTUAL // THREE.Object3D instance caches
  30752. this.cache = {
  30753. refs: {},
  30754. uses: {},
  30755. }
  30756. }
  30757. _markDefs() {
  30758. const parser = this.parser
  30759. const nodeDefs = this.parser.json.nodes || []
  30760. for (let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++) {
  30761. const nodeDef = nodeDefs[nodeIndex]
  30762. if (nodeDef.extensions && nodeDef.extensions[this.name] && nodeDef.extensions[this.name].light !== undefined) {
  30763. parser._addNodeRef(this.cache, nodeDef.extensions[this.name].light)
  30764. }
  30765. }
  30766. }
  30767. _loadLight(lightIndex) {
  30768. const parser = this.parser
  30769. const cacheKey = 'light:' + lightIndex
  30770. let dependency = parser.cache.get(cacheKey)
  30771. if (dependency) return dependency
  30772. const json = parser.json
  30773. const extensions = (json.extensions && json.extensions[this.name]) || {}
  30774. const lightDefs = extensions.lights || []
  30775. const lightDef = lightDefs[lightIndex]
  30776. let lightNode
  30777. const color = new THREE.Color(0xffffff)
  30778. if (lightDef.color !== undefined) color.fromArray(lightDef.color)
  30779. const range = lightDef.range !== undefined ? lightDef.range : 0
  30780. switch (lightDef.type) {
  30781. case 'directional':
  30782. lightNode = new THREE.DirectionalLight(color)
  30783. lightNode.target.position.set(0, 0, -1)
  30784. lightNode.add(lightNode.target)
  30785. break
  30786. case 'point':
  30787. lightNode = new THREE.PointLight(color)
  30788. lightNode.distance = range
  30789. break
  30790. case 'spot':
  30791. lightNode = new THREE.SpotLight(color)
  30792. lightNode.distance = range // Handle spotlight properties.
  30793. lightDef.spot = lightDef.spot || {}
  30794. lightDef.spot.innerConeAngle = lightDef.spot.innerConeAngle !== undefined ? lightDef.spot.innerConeAngle : 0
  30795. lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0
  30796. lightNode.angle = lightDef.spot.outerConeAngle
  30797. lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle
  30798. lightNode.target.position.set(0, 0, -1)
  30799. lightNode.add(lightNode.target)
  30800. break
  30801. default:
  30802. throw new Error('THREE.GLTFLoader: Unexpected light type: ' + lightDef.type)
  30803. } // Some lights (e.g. spot) default to a position other than the origin. Reset the position
  30804. // here, because node-level parsing will only override position if explicitly specified.
  30805. lightNode.position.set(0, 0, 0)
  30806. lightNode.decay = 2
  30807. if (lightDef.intensity !== undefined) lightNode.intensity = lightDef.intensity
  30808. lightNode.name = parser.createUniqueName(lightDef.name || 'light_' + lightIndex)
  30809. dependency = Promise.resolve(lightNode)
  30810. parser.cache.add(cacheKey, dependency)
  30811. return dependency
  30812. }
  30813. createNodeAttachment(nodeIndex) {
  30814. const self = this
  30815. const parser = this.parser
  30816. const json = parser.json
  30817. const nodeDef = json.nodes[nodeIndex]
  30818. const lightDef = (nodeDef.extensions && nodeDef.extensions[this.name]) || {}
  30819. const lightIndex = lightDef.light
  30820. if (lightIndex === undefined) return null
  30821. return this._loadLight(lightIndex).then(function (light) {
  30822. return parser._getNodeRef(self.cache, lightIndex, light)
  30823. })
  30824. }
  30825. }
  30826. /**
  30827. * Unlit Materials Extension
  30828. *
  30829. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_unlit
  30830. */
  30831. class GLTFMaterialsUnlitExtension {
  30832. constructor() {
  30833. this.name = EXTENSIONS.KHR_MATERIALS_UNLIT
  30834. }
  30835. getMaterialType() {
  30836. return THREE.MeshBasicMaterial
  30837. }
  30838. extendParams(materialParams, materialDef, parser) {
  30839. const pending = []
  30840. materialParams.color = new THREE.Color(1.0, 1.0, 1.0)
  30841. materialParams.opacity = 1.0
  30842. const metallicRoughness = materialDef.pbrMetallicRoughness
  30843. if (metallicRoughness) {
  30844. if (Array.isArray(metallicRoughness.baseColorFactor)) {
  30845. const array = metallicRoughness.baseColorFactor
  30846. materialParams.color.fromArray(array)
  30847. materialParams.opacity = array[3]
  30848. }
  30849. if (metallicRoughness.baseColorTexture !== undefined) {
  30850. pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture, THREE.sRGBEncoding))
  30851. }
  30852. }
  30853. return Promise.all(pending)
  30854. }
  30855. }
  30856. /**
  30857. * Materials Emissive Strength Extension
  30858. *
  30859. * Specification: https://github.com/KhronosGroup/glTF/blob/5768b3ce0ef32bc39cdf1bef10b948586635ead3/extensions/2.0/Khronos/KHR_materials_emissive_strength/README.md
  30860. */
  30861. class GLTFMaterialsEmissiveStrengthExtension {
  30862. constructor(parser) {
  30863. this.parser = parser
  30864. this.name = EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH
  30865. }
  30866. extendMaterialParams(materialIndex, materialParams) {
  30867. const parser = this.parser
  30868. const materialDef = parser.json.materials[materialIndex]
  30869. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  30870. return Promise.resolve()
  30871. }
  30872. const emissiveStrength = materialDef.extensions[this.name].emissiveStrength
  30873. if (emissiveStrength !== undefined) {
  30874. materialParams.emissiveIntensity = emissiveStrength
  30875. }
  30876. return Promise.resolve()
  30877. }
  30878. }
  30879. /**
  30880. * Clearcoat Materials Extension
  30881. *
  30882. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
  30883. */
  30884. class GLTFMaterialsClearcoatExtension {
  30885. constructor(parser) {
  30886. this.parser = parser
  30887. this.name = EXTENSIONS.KHR_MATERIALS_CLEARCOAT
  30888. }
  30889. getMaterialType(materialIndex) {
  30890. const parser = this.parser
  30891. const materialDef = parser.json.materials[materialIndex]
  30892. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  30893. return THREE.MeshPhysicalMaterial
  30894. }
  30895. extendMaterialParams(materialIndex, materialParams) {
  30896. const parser = this.parser
  30897. const materialDef = parser.json.materials[materialIndex]
  30898. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  30899. return Promise.resolve()
  30900. }
  30901. const pending = []
  30902. const extension = materialDef.extensions[this.name]
  30903. if (extension.clearcoatFactor !== undefined) {
  30904. materialParams.clearcoat = extension.clearcoatFactor
  30905. }
  30906. if (extension.clearcoatTexture !== undefined) {
  30907. pending.push(parser.assignTexture(materialParams, 'clearcoatMap', extension.clearcoatTexture))
  30908. }
  30909. if (extension.clearcoatRoughnessFactor !== undefined) {
  30910. materialParams.clearcoatRoughness = extension.clearcoatRoughnessFactor
  30911. }
  30912. if (extension.clearcoatRoughnessTexture !== undefined) {
  30913. pending.push(parser.assignTexture(materialParams, 'clearcoatRoughnessMap', extension.clearcoatRoughnessTexture))
  30914. }
  30915. if (extension.clearcoatNormalTexture !== undefined) {
  30916. pending.push(parser.assignTexture(materialParams, 'clearcoatNormalMap', extension.clearcoatNormalTexture))
  30917. if (extension.clearcoatNormalTexture.scale !== undefined) {
  30918. const scale = extension.clearcoatNormalTexture.scale
  30919. materialParams.clearcoatNormalScale = new THREE.Vector2(scale, scale)
  30920. }
  30921. }
  30922. return Promise.all(pending)
  30923. }
  30924. }
  30925. /**
  30926. * Iridescence Materials Extension
  30927. *
  30928. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_iridescence
  30929. */
  30930. class GLTFMaterialsIridescenceExtension {
  30931. constructor(parser) {
  30932. this.parser = parser
  30933. this.name = EXTENSIONS.KHR_MATERIALS_IRIDESCENCE
  30934. }
  30935. getMaterialType(materialIndex) {
  30936. const parser = this.parser
  30937. const materialDef = parser.json.materials[materialIndex]
  30938. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  30939. return THREE.MeshPhysicalMaterial
  30940. }
  30941. extendMaterialParams(materialIndex, materialParams) {
  30942. const parser = this.parser
  30943. const materialDef = parser.json.materials[materialIndex]
  30944. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  30945. return Promise.resolve()
  30946. }
  30947. const pending = []
  30948. const extension = materialDef.extensions[this.name]
  30949. if (extension.iridescenceFactor !== undefined) {
  30950. materialParams.iridescence = extension.iridescenceFactor
  30951. }
  30952. if (extension.iridescenceTexture !== undefined) {
  30953. pending.push(parser.assignTexture(materialParams, 'iridescenceMap', extension.iridescenceTexture))
  30954. }
  30955. if (extension.iridescenceIor !== undefined) {
  30956. materialParams.iridescenceIOR = extension.iridescenceIor
  30957. }
  30958. if (materialParams.iridescenceThicknessRange === undefined) {
  30959. materialParams.iridescenceThicknessRange = [100, 400]
  30960. }
  30961. if (extension.iridescenceThicknessMinimum !== undefined) {
  30962. materialParams.iridescenceThicknessRange[0] = extension.iridescenceThicknessMinimum
  30963. }
  30964. if (extension.iridescenceThicknessMaximum !== undefined) {
  30965. materialParams.iridescenceThicknessRange[1] = extension.iridescenceThicknessMaximum
  30966. }
  30967. if (extension.iridescenceThicknessTexture !== undefined) {
  30968. pending.push(parser.assignTexture(materialParams, 'iridescenceThicknessMap', extension.iridescenceThicknessTexture))
  30969. }
  30970. return Promise.all(pending)
  30971. }
  30972. }
  30973. /**
  30974. * Sheen Materials Extension
  30975. *
  30976. * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_sheen
  30977. */
  30978. class GLTFMaterialsSheenExtension {
  30979. constructor(parser) {
  30980. this.parser = parser
  30981. this.name = EXTENSIONS.KHR_MATERIALS_SHEEN
  30982. }
  30983. getMaterialType(materialIndex) {
  30984. const parser = this.parser
  30985. const materialDef = parser.json.materials[materialIndex]
  30986. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  30987. return THREE.MeshPhysicalMaterial
  30988. }
  30989. extendMaterialParams(materialIndex, materialParams) {
  30990. const parser = this.parser
  30991. const materialDef = parser.json.materials[materialIndex]
  30992. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  30993. return Promise.resolve()
  30994. }
  30995. const pending = []
  30996. materialParams.sheenColor = new THREE.Color(0, 0, 0)
  30997. materialParams.sheenRoughness = 0
  30998. materialParams.sheen = 1
  30999. const extension = materialDef.extensions[this.name]
  31000. if (extension.sheenColorFactor !== undefined) {
  31001. materialParams.sheenColor.fromArray(extension.sheenColorFactor)
  31002. }
  31003. if (extension.sheenRoughnessFactor !== undefined) {
  31004. materialParams.sheenRoughness = extension.sheenRoughnessFactor
  31005. }
  31006. if (extension.sheenColorTexture !== undefined) {
  31007. pending.push(parser.assignTexture(materialParams, 'sheenColorMap', extension.sheenColorTexture, THREE.sRGBEncoding))
  31008. }
  31009. if (extension.sheenRoughnessTexture !== undefined) {
  31010. pending.push(parser.assignTexture(materialParams, 'sheenRoughnessMap', extension.sheenRoughnessTexture))
  31011. }
  31012. return Promise.all(pending)
  31013. }
  31014. }
  31015. /**
  31016. * Transmission Materials Extension
  31017. *
  31018. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
  31019. * Draft: https://github.com/KhronosGroup/glTF/pull/1698
  31020. */
  31021. class GLTFMaterialsTransmissionExtension {
  31022. constructor(parser) {
  31023. this.parser = parser
  31024. this.name = EXTENSIONS.KHR_MATERIALS_TRANSMISSION
  31025. }
  31026. getMaterialType(materialIndex) {
  31027. const parser = this.parser
  31028. const materialDef = parser.json.materials[materialIndex]
  31029. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  31030. return THREE.MeshPhysicalMaterial
  31031. }
  31032. extendMaterialParams(materialIndex, materialParams) {
  31033. const parser = this.parser
  31034. const materialDef = parser.json.materials[materialIndex]
  31035. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  31036. return Promise.resolve()
  31037. }
  31038. const pending = []
  31039. const extension = materialDef.extensions[this.name]
  31040. if (extension.transmissionFactor !== undefined) {
  31041. materialParams.transmission = extension.transmissionFactor
  31042. }
  31043. if (extension.transmissionTexture !== undefined) {
  31044. pending.push(parser.assignTexture(materialParams, 'transmissionMap', extension.transmissionTexture))
  31045. }
  31046. return Promise.all(pending)
  31047. }
  31048. }
  31049. /**
  31050. * Materials Volume Extension
  31051. *
  31052. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_volume
  31053. */
  31054. class GLTFMaterialsVolumeExtension {
  31055. constructor(parser) {
  31056. this.parser = parser
  31057. this.name = EXTENSIONS.KHR_MATERIALS_VOLUME
  31058. }
  31059. getMaterialType(materialIndex) {
  31060. const parser = this.parser
  31061. const materialDef = parser.json.materials[materialIndex]
  31062. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  31063. return THREE.MeshPhysicalMaterial
  31064. }
  31065. extendMaterialParams(materialIndex, materialParams) {
  31066. const parser = this.parser
  31067. const materialDef = parser.json.materials[materialIndex]
  31068. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  31069. return Promise.resolve()
  31070. }
  31071. const pending = []
  31072. const extension = materialDef.extensions[this.name]
  31073. materialParams.thickness = extension.thicknessFactor !== undefined ? extension.thicknessFactor : 0
  31074. if (extension.thicknessTexture !== undefined) {
  31075. pending.push(parser.assignTexture(materialParams, 'thicknessMap', extension.thicknessTexture))
  31076. }
  31077. materialParams.attenuationDistance = extension.attenuationDistance || 0
  31078. const colorArray = extension.attenuationColor || [1, 1, 1]
  31079. materialParams.attenuationColor = new THREE.Color(colorArray[0], colorArray[1], colorArray[2])
  31080. return Promise.all(pending)
  31081. }
  31082. }
  31083. /**
  31084. * Materials ior Extension
  31085. *
  31086. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_ior
  31087. */
  31088. class GLTFMaterialsIorExtension {
  31089. constructor(parser) {
  31090. this.parser = parser
  31091. this.name = EXTENSIONS.KHR_MATERIALS_IOR
  31092. }
  31093. getMaterialType(materialIndex) {
  31094. const parser = this.parser
  31095. const materialDef = parser.json.materials[materialIndex]
  31096. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  31097. return THREE.MeshPhysicalMaterial
  31098. }
  31099. extendMaterialParams(materialIndex, materialParams) {
  31100. const parser = this.parser
  31101. const materialDef = parser.json.materials[materialIndex]
  31102. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  31103. return Promise.resolve()
  31104. }
  31105. const extension = materialDef.extensions[this.name]
  31106. materialParams.ior = extension.ior !== undefined ? extension.ior : 1.5
  31107. return Promise.resolve()
  31108. }
  31109. }
  31110. /**
  31111. * Materials specular Extension
  31112. *
  31113. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_specular
  31114. */
  31115. class GLTFMaterialsSpecularExtension {
  31116. constructor(parser) {
  31117. this.parser = parser
  31118. this.name = EXTENSIONS.KHR_MATERIALS_SPECULAR
  31119. }
  31120. getMaterialType(materialIndex) {
  31121. const parser = this.parser
  31122. const materialDef = parser.json.materials[materialIndex]
  31123. if (!materialDef.extensions || !materialDef.extensions[this.name]) return null
  31124. return THREE.MeshPhysicalMaterial
  31125. }
  31126. extendMaterialParams(materialIndex, materialParams) {
  31127. const parser = this.parser
  31128. const materialDef = parser.json.materials[materialIndex]
  31129. if (!materialDef.extensions || !materialDef.extensions[this.name]) {
  31130. return Promise.resolve()
  31131. }
  31132. const pending = []
  31133. const extension = materialDef.extensions[this.name]
  31134. materialParams.specularIntensity = extension.specularFactor !== undefined ? extension.specularFactor : 1.0
  31135. if (extension.specularTexture !== undefined) {
  31136. pending.push(parser.assignTexture(materialParams, 'specularIntensityMap', extension.specularTexture))
  31137. }
  31138. const colorArray = extension.specularColorFactor || [1, 1, 1]
  31139. materialParams.specularColor = new THREE.Color(colorArray[0], colorArray[1], colorArray[2])
  31140. if (extension.specularColorTexture !== undefined) {
  31141. pending.push(parser.assignTexture(materialParams, 'specularColorMap', extension.specularColorTexture, THREE.sRGBEncoding))
  31142. }
  31143. return Promise.all(pending)
  31144. }
  31145. }
  31146. /**
  31147. * BasisU THREE.Texture Extension
  31148. *
  31149. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_basisu
  31150. */
  31151. class GLTFTextureBasisUExtension {
  31152. constructor(parser) {
  31153. this.parser = parser
  31154. this.name = EXTENSIONS.KHR_TEXTURE_BASISU
  31155. }
  31156. loadTexture(textureIndex) {
  31157. const parser = this.parser
  31158. const json = parser.json
  31159. const textureDef = json.textures[textureIndex]
  31160. if (!textureDef.extensions || !textureDef.extensions[this.name]) {
  31161. return null
  31162. }
  31163. const extension = textureDef.extensions[this.name]
  31164. const loader = parser.options.ktx2Loader
  31165. if (!loader) {
  31166. if (json.extensionsRequired && json.extensionsRequired.indexOf(this.name) >= 0) {
  31167. throw new Error('THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures')
  31168. } else {
  31169. // Assumes that the extension is optional and that a fallback texture is present
  31170. return null
  31171. }
  31172. }
  31173. return parser.loadTextureImage(textureIndex, extension.source, loader)
  31174. }
  31175. }
  31176. /**
  31177. * WebP THREE.Texture Extension
  31178. *
  31179. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_texture_webp
  31180. */
  31181. class GLTFTextureWebPExtension {
  31182. constructor(parser) {
  31183. this.parser = parser
  31184. this.name = EXTENSIONS.EXT_TEXTURE_WEBP
  31185. this.isSupported = null
  31186. }
  31187. loadTexture(textureIndex) {
  31188. const name = this.name
  31189. const parser = this.parser
  31190. const json = parser.json
  31191. const textureDef = json.textures[textureIndex]
  31192. if (!textureDef.extensions || !textureDef.extensions[name]) {
  31193. return null
  31194. }
  31195. const extension = textureDef.extensions[name]
  31196. const source = json.images[extension.source]
  31197. let loader = parser.textureLoader
  31198. if (source.uri) {
  31199. const handler = parser.options.manager.getHandler(source.uri)
  31200. if (handler !== null) loader = handler
  31201. }
  31202. return this.detectSupport().then(function (isSupported) {
  31203. if (isSupported) return parser.loadTextureImage(textureIndex, extension.source, loader)
  31204. if (json.extensionsRequired && json.extensionsRequired.indexOf(name) >= 0) {
  31205. throw new Error('THREE.GLTFLoader: WebP required by asset but unsupported.')
  31206. } // Fall back to PNG or JPEG.
  31207. return parser.loadTexture(textureIndex)
  31208. })
  31209. }
  31210. detectSupport() {
  31211. if (!this.isSupported) {
  31212. this.isSupported = new Promise(function (resolve) {
  31213. const image = new Image() // Lossy test image. Support for lossy images doesn't guarantee support for all
  31214. // WebP images, unfortunately.
  31215. image.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA'
  31216. image.onload = image.onerror = function () {
  31217. resolve(image.height === 1)
  31218. }
  31219. })
  31220. }
  31221. return this.isSupported
  31222. }
  31223. }
  31224. /**
  31225. * meshopt BufferView Compression Extension
  31226. *
  31227. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/EXT_meshopt_compression
  31228. */
  31229. class GLTFMeshoptCompression {
  31230. constructor(parser) {
  31231. this.name = EXTENSIONS.EXT_MESHOPT_COMPRESSION
  31232. this.parser = parser
  31233. }
  31234. loadBufferView(index) {
  31235. const json = this.parser.json
  31236. const bufferView = json.bufferViews[index]
  31237. if (bufferView.extensions && bufferView.extensions[this.name]) {
  31238. const extensionDef = bufferView.extensions[this.name]
  31239. const buffer = this.parser.getDependency('buffer', extensionDef.buffer)
  31240. const decoder = this.parser.options.meshoptDecoder
  31241. if (!decoder || !decoder.supported) {
  31242. if (json.extensionsRequired && json.extensionsRequired.indexOf(this.name) >= 0) {
  31243. throw new Error('THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files')
  31244. } else {
  31245. // Assumes that the extension is optional and that fallback buffer data is present
  31246. return null
  31247. }
  31248. }
  31249. return buffer.then(function (res) {
  31250. const byteOffset = extensionDef.byteOffset || 0
  31251. const byteLength = extensionDef.byteLength || 0
  31252. const count = extensionDef.count
  31253. const stride = extensionDef.byteStride
  31254. const source = new Uint8Array(res, byteOffset, byteLength)
  31255. if (decoder.decodeGltfBufferAsync) {
  31256. return decoder.decodeGltfBufferAsync(count, stride, source, extensionDef.mode, extensionDef.filter).then(function (res) {
  31257. return res.buffer
  31258. })
  31259. } else {
  31260. // Support for MeshoptDecoder 0.18 or earlier, without decodeGltfBufferAsync
  31261. return decoder.ready.then(function () {
  31262. const result = new ArrayBuffer(count * stride)
  31263. decoder.decodeGltfBuffer(new Uint8Array(result), count, stride, source, extensionDef.mode, extensionDef.filter)
  31264. return result
  31265. })
  31266. }
  31267. })
  31268. } else {
  31269. return null
  31270. }
  31271. }
  31272. }
  31273. /* BINARY EXTENSION */
  31274. const BINARY_EXTENSION_HEADER_MAGIC = 'glTF'
  31275. const BINARY_EXTENSION_HEADER_LENGTH = 12
  31276. const BINARY_EXTENSION_CHUNK_TYPES = {
  31277. JSON: 0x4e4f534a,
  31278. BIN: 0x004e4942,
  31279. }
  31280. class GLTFBinaryExtension {
  31281. constructor(data) {
  31282. this.name = EXTENSIONS.KHR_BINARY_GLTF
  31283. this.content = null
  31284. this.body = null
  31285. const headerView = new DataView(data, 0, BINARY_EXTENSION_HEADER_LENGTH)
  31286. this.header = {
  31287. magic: THREE.LoaderUtils.decodeText(new Uint8Array(data.slice(0, 4))),
  31288. version: headerView.getUint32(4, true),
  31289. length: headerView.getUint32(8, true),
  31290. }
  31291. if (this.header.magic !== BINARY_EXTENSION_HEADER_MAGIC) {
  31292. throw new Error('THREE.GLTFLoader: Unsupported glTF-Binary header.')
  31293. } else if (this.header.version < 2.0) {
  31294. throw new Error('THREE.GLTFLoader: Legacy binary file detected.')
  31295. }
  31296. const chunkContentsLength = this.header.length - BINARY_EXTENSION_HEADER_LENGTH
  31297. const chunkView = new DataView(data, BINARY_EXTENSION_HEADER_LENGTH)
  31298. let chunkIndex = 0
  31299. while (chunkIndex < chunkContentsLength) {
  31300. const chunkLength = chunkView.getUint32(chunkIndex, true)
  31301. chunkIndex += 4
  31302. const chunkType = chunkView.getUint32(chunkIndex, true)
  31303. chunkIndex += 4
  31304. if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.JSON) {
  31305. const contentArray = new Uint8Array(data, BINARY_EXTENSION_HEADER_LENGTH + chunkIndex, chunkLength)
  31306. this.content = THREE.LoaderUtils.decodeText(contentArray)
  31307. } else if (chunkType === BINARY_EXTENSION_CHUNK_TYPES.BIN) {
  31308. const byteOffset = BINARY_EXTENSION_HEADER_LENGTH + chunkIndex
  31309. this.body = data.slice(byteOffset, byteOffset + chunkLength)
  31310. } // Clients must ignore chunks with unknown types.
  31311. chunkIndex += chunkLength
  31312. }
  31313. if (this.content === null) {
  31314. throw new Error('THREE.GLTFLoader: JSON content not found.')
  31315. }
  31316. }
  31317. }
  31318. /**
  31319. * DRACO THREE.Mesh Compression Extension
  31320. *
  31321. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_draco_mesh_compression
  31322. */
  31323. class GLTFDracoMeshCompressionExtension {
  31324. constructor(json, dracoLoader) {
  31325. if (!dracoLoader) {
  31326. throw new Error('THREE.GLTFLoader: No DRACOLoader instance provided.')
  31327. }
  31328. this.name = EXTENSIONS.KHR_DRACO_MESH_COMPRESSION
  31329. this.json = json
  31330. this.dracoLoader = dracoLoader
  31331. this.dracoLoader.preload()
  31332. }
  31333. decodePrimitive(primitive, parser) {
  31334. const json = this.json
  31335. const dracoLoader = this.dracoLoader
  31336. const bufferViewIndex = primitive.extensions[this.name].bufferView
  31337. const gltfAttributeMap = primitive.extensions[this.name].attributes
  31338. const threeAttributeMap = {}
  31339. const attributeNormalizedMap = {}
  31340. const attributeTypeMap = {}
  31341. for (const attributeName in gltfAttributeMap) {
  31342. const threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase()
  31343. threeAttributeMap[threeAttributeName] = gltfAttributeMap[attributeName]
  31344. }
  31345. for (const attributeName in primitive.attributes) {
  31346. const threeAttributeName = ATTRIBUTES[attributeName] || attributeName.toLowerCase()
  31347. if (gltfAttributeMap[attributeName] !== undefined) {
  31348. const accessorDef = json.accessors[primitive.attributes[attributeName]]
  31349. const componentType = WEBGL_COMPONENT_TYPES[accessorDef.componentType]
  31350. attributeTypeMap[threeAttributeName] = componentType.name
  31351. attributeNormalizedMap[threeAttributeName] = accessorDef.normalized === true
  31352. }
  31353. }
  31354. return parser.getDependency('bufferView', bufferViewIndex).then(function (bufferView) {
  31355. return new Promise(function (resolve) {
  31356. dracoLoader.decodeDracoFile(
  31357. bufferView,
  31358. function (geometry) {
  31359. for (const attributeName in geometry.attributes) {
  31360. const attribute = geometry.attributes[attributeName]
  31361. const normalized = attributeNormalizedMap[attributeName]
  31362. if (normalized !== undefined) attribute.normalized = normalized
  31363. }
  31364. resolve(geometry)
  31365. },
  31366. threeAttributeMap,
  31367. attributeTypeMap
  31368. )
  31369. })
  31370. })
  31371. }
  31372. }
  31373. /**
  31374. * THREE.Texture Transform Extension
  31375. *
  31376. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_texture_transform
  31377. */
  31378. class GLTFTextureTransformExtension {
  31379. constructor() {
  31380. this.name = EXTENSIONS.KHR_TEXTURE_TRANSFORM
  31381. }
  31382. extendTexture(texture, transform) {
  31383. if (transform.texCoord !== undefined) {
  31384. console.warn('THREE.GLTFLoader: Custom UV sets in "' + this.name + '" extension not yet supported.')
  31385. }
  31386. if (transform.offset === undefined && transform.rotation === undefined && transform.scale === undefined) {
  31387. // See https://github.com/mrdoob/three.js/issues/21819.
  31388. return texture
  31389. }
  31390. texture = texture.clone()
  31391. if (transform.offset !== undefined) {
  31392. texture.offset.fromArray(transform.offset)
  31393. }
  31394. if (transform.rotation !== undefined) {
  31395. texture.rotation = transform.rotation
  31396. }
  31397. if (transform.scale !== undefined) {
  31398. texture.repeat.fromArray(transform.scale)
  31399. }
  31400. texture.needsUpdate = true
  31401. return texture
  31402. }
  31403. }
  31404. /**
  31405. * Specular-Glossiness Extension
  31406. *
  31407. * Specification: https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Archived/KHR_materials_pbrSpecularGlossiness
  31408. */
  31409. /**
  31410. * A sub class of StandardMaterial with some of the functionality
  31411. * changed via the `onBeforeCompile` callback
  31412. * @pailhead
  31413. */
  31414. class GLTFMeshStandardSGMaterial extends THREE.MeshStandardMaterial {
  31415. constructor(params) {
  31416. super()
  31417. this.isGLTFSpecularGlossinessMaterial = true //various chunks that need replacing
  31418. const specularMapParsFragmentChunk = ['#ifdef USE_SPECULARMAP', ' uniform sampler2D specularMap;', '#endif'].join('\n')
  31419. const glossinessMapParsFragmentChunk = ['#ifdef USE_GLOSSINESSMAP', ' uniform sampler2D glossinessMap;', '#endif'].join('\n')
  31420. const specularMapFragmentChunk = [
  31421. 'vec3 specularFactor = specular;',
  31422. '#ifdef USE_SPECULARMAP',
  31423. ' vec4 texelSpecular = texture2D( specularMap, vUv );',
  31424. ' // reads channel RGB, compatible with a glTF Specular-Glossiness (RGBA) texture',
  31425. ' specularFactor *= texelSpecular.rgb;',
  31426. '#endif',
  31427. ].join('\n')
  31428. const glossinessMapFragmentChunk = [
  31429. 'float glossinessFactor = glossiness;',
  31430. '#ifdef USE_GLOSSINESSMAP',
  31431. ' vec4 texelGlossiness = texture2D( glossinessMap, vUv );',
  31432. ' // reads channel A, compatible with a glTF Specular-Glossiness (RGBA) texture',
  31433. ' glossinessFactor *= texelGlossiness.a;',
  31434. '#endif',
  31435. ].join('\n')
  31436. const lightPhysicalFragmentChunk = [
  31437. 'PhysicalMaterial material;',
  31438. 'material.diffuseColor = diffuseColor.rgb * ( 1. - max( specularFactor.r, max( specularFactor.g, specularFactor.b ) ) );',
  31439. 'vec3 dxy = max( abs( dFdx( geometryNormal ) ), abs( dFdy( geometryNormal ) ) );',
  31440. 'float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );',
  31441. 'material.roughness = max( 1.0 - glossinessFactor, 0.0525 ); // 0.0525 corresponds to the base mip of a 256 cubemap.',
  31442. 'material.roughness += geometryRoughness;',
  31443. 'material.roughness = min( material.roughness, 1.0 );',
  31444. 'material.specularColor = specularFactor;',
  31445. ].join('\n')
  31446. const uniforms = {
  31447. specular: {
  31448. value: new THREE.Color().setHex(0xffffff),
  31449. },
  31450. glossiness: {
  31451. value: 1,
  31452. },
  31453. specularMap: {
  31454. value: null,
  31455. },
  31456. glossinessMap: {
  31457. value: null,
  31458. },
  31459. }
  31460. this._extraUniforms = uniforms
  31461. this.onBeforeCompile = function (shader) {
  31462. for (const uniformName in uniforms) {
  31463. shader.uniforms[uniformName] = uniforms[uniformName]
  31464. }
  31465. shader.fragmentShader = shader.fragmentShader
  31466. .replace('uniform float roughness;', 'uniform vec3 specular;')
  31467. .replace('uniform float metalness;', 'uniform float glossiness;')
  31468. .replace('#include <roughnessmap_pars_fragment>', specularMapParsFragmentChunk)
  31469. .replace('#include <metalnessmap_pars_fragment>', glossinessMapParsFragmentChunk)
  31470. .replace('#include <roughnessmap_fragment>', specularMapFragmentChunk)
  31471. .replace('#include <metalnessmap_fragment>', glossinessMapFragmentChunk)
  31472. .replace('#include <lights_physical_fragment>', lightPhysicalFragmentChunk)
  31473. }
  31474. Object.defineProperties(this, {
  31475. specular: {
  31476. get: function () {
  31477. return uniforms.specular.value
  31478. },
  31479. set: function (v) {
  31480. uniforms.specular.value = v
  31481. },
  31482. },
  31483. specularMap: {
  31484. get: function () {
  31485. return uniforms.specularMap.value
  31486. },
  31487. set: function (v) {
  31488. uniforms.specularMap.value = v
  31489. if (v) {
  31490. this.defines.USE_SPECULARMAP = '' // USE_UV is set by the renderer for specular maps
  31491. } else {
  31492. delete this.defines.USE_SPECULARMAP
  31493. }
  31494. },
  31495. },
  31496. glossiness: {
  31497. get: function () {
  31498. return uniforms.glossiness.value
  31499. },
  31500. set: function (v) {
  31501. uniforms.glossiness.value = v
  31502. },
  31503. },
  31504. glossinessMap: {
  31505. get: function () {
  31506. return uniforms.glossinessMap.value
  31507. },
  31508. set: function (v) {
  31509. uniforms.glossinessMap.value = v
  31510. if (v) {
  31511. this.defines.USE_GLOSSINESSMAP = ''
  31512. this.defines.USE_UV = ''
  31513. } else {
  31514. delete this.defines.USE_GLOSSINESSMAP
  31515. delete this.defines.USE_UV
  31516. }
  31517. },
  31518. },
  31519. })
  31520. delete this.metalness
  31521. delete this.roughness
  31522. delete this.metalnessMap
  31523. delete this.roughnessMap
  31524. this.setValues(params)
  31525. }
  31526. copy(source) {
  31527. super.copy(source)
  31528. this.specularMap = source.specularMap
  31529. this.specular.copy(source.specular)
  31530. this.glossinessMap = source.glossinessMap
  31531. this.glossiness = source.glossiness
  31532. delete this.metalness
  31533. delete this.roughness
  31534. delete this.metalnessMap
  31535. delete this.roughnessMap
  31536. return this
  31537. }
  31538. }
  31539. class GLTFMaterialsPbrSpecularGlossinessExtension {
  31540. constructor() {
  31541. this.name = EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS
  31542. this.specularGlossinessParams = [
  31543. 'color',
  31544. 'map',
  31545. 'lightMap',
  31546. 'lightMapIntensity',
  31547. 'aoMap',
  31548. 'aoMapIntensity',
  31549. 'emissive',
  31550. 'emissiveIntensity',
  31551. 'emissiveMap',
  31552. 'bumpMap',
  31553. 'bumpScale',
  31554. 'normalMap',
  31555. 'normalMapType',
  31556. 'displacementMap',
  31557. 'displacementScale',
  31558. 'displacementBias',
  31559. 'specularMap',
  31560. 'specular',
  31561. 'glossinessMap',
  31562. 'glossiness',
  31563. 'alphaMap',
  31564. 'envMap',
  31565. 'envMapIntensity',
  31566. ]
  31567. }
  31568. getMaterialType() {
  31569. return GLTFMeshStandardSGMaterial
  31570. }
  31571. extendParams(materialParams, materialDef, parser) {
  31572. const pbrSpecularGlossiness = materialDef.extensions[this.name]
  31573. materialParams.color = new THREE.Color(1.0, 1.0, 1.0)
  31574. materialParams.opacity = 1.0
  31575. const pending = []
  31576. if (Array.isArray(pbrSpecularGlossiness.diffuseFactor)) {
  31577. const array = pbrSpecularGlossiness.diffuseFactor
  31578. materialParams.color.fromArray(array)
  31579. materialParams.opacity = array[3]
  31580. }
  31581. if (pbrSpecularGlossiness.diffuseTexture !== undefined) {
  31582. pending.push(parser.assignTexture(materialParams, 'map', pbrSpecularGlossiness.diffuseTexture, THREE.sRGBEncoding))
  31583. }
  31584. materialParams.emissive = new THREE.Color(0.0, 0.0, 0.0)
  31585. materialParams.glossiness = pbrSpecularGlossiness.glossinessFactor !== undefined ? pbrSpecularGlossiness.glossinessFactor : 1.0
  31586. materialParams.specular = new THREE.Color(1.0, 1.0, 1.0)
  31587. if (Array.isArray(pbrSpecularGlossiness.specularFactor)) {
  31588. materialParams.specular.fromArray(pbrSpecularGlossiness.specularFactor)
  31589. }
  31590. if (pbrSpecularGlossiness.specularGlossinessTexture !== undefined) {
  31591. const specGlossMapDef = pbrSpecularGlossiness.specularGlossinessTexture
  31592. pending.push(parser.assignTexture(materialParams, 'glossinessMap', specGlossMapDef))
  31593. pending.push(parser.assignTexture(materialParams, 'specularMap', specGlossMapDef, THREE.sRGBEncoding))
  31594. }
  31595. return Promise.all(pending)
  31596. }
  31597. createMaterial(materialParams) {
  31598. const material = new GLTFMeshStandardSGMaterial(materialParams)
  31599. material.fog = true
  31600. material.color = materialParams.color
  31601. material.map = materialParams.map === undefined ? null : materialParams.map
  31602. material.lightMap = null
  31603. material.lightMapIntensity = 1.0
  31604. material.aoMap = materialParams.aoMap === undefined ? null : materialParams.aoMap
  31605. material.aoMapIntensity = 1.0
  31606. material.emissive = materialParams.emissive
  31607. material.emissiveIntensity = materialParams.emissiveIntensity === undefined ? 1.0 : materialParams.emissiveIntensity
  31608. material.emissiveMap = materialParams.emissiveMap === undefined ? null : materialParams.emissiveMap
  31609. material.bumpMap = materialParams.bumpMap === undefined ? null : materialParams.bumpMap
  31610. material.bumpScale = 1
  31611. material.normalMap = materialParams.normalMap === undefined ? null : materialParams.normalMap
  31612. material.normalMapType = THREE.TangentSpaceNormalMap
  31613. if (materialParams.normalScale) material.normalScale = materialParams.normalScale
  31614. material.displacementMap = null
  31615. material.displacementScale = 1
  31616. material.displacementBias = 0
  31617. material.specularMap = materialParams.specularMap === undefined ? null : materialParams.specularMap
  31618. material.specular = materialParams.specular
  31619. material.glossinessMap = materialParams.glossinessMap === undefined ? null : materialParams.glossinessMap
  31620. material.glossiness = materialParams.glossiness
  31621. material.alphaMap = null
  31622. material.envMap = materialParams.envMap === undefined ? null : materialParams.envMap
  31623. material.envMapIntensity = 1.0
  31624. return material
  31625. }
  31626. }
  31627. /**
  31628. * THREE.Mesh Quantization Extension
  31629. *
  31630. * Specification: https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization
  31631. */
  31632. class GLTFMeshQuantizationExtension {
  31633. constructor() {
  31634. this.name = EXTENSIONS.KHR_MESH_QUANTIZATION
  31635. }
  31636. }
  31637. /*********************************/
  31638. /********** INTERPOLATION ********/
  31639. /*********************************/
  31640. // Spline Interpolation
  31641. // Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#appendix-c-spline-interpolation
  31642. class GLTFCubicSplineInterpolant extends THREE.Interpolant {
  31643. constructor(parameterPositions, sampleValues, sampleSize, resultBuffer) {
  31644. super(parameterPositions, sampleValues, sampleSize, resultBuffer)
  31645. }
  31646. copySampleValue_(index) {
  31647. // Copies a sample value to the result buffer. See description of glTF
  31648. // CUBICSPLINE values layout in interpolate_() function below.
  31649. const result = this.resultBuffer,
  31650. values = this.sampleValues,
  31651. valueSize = this.valueSize,
  31652. offset = index * valueSize * 3 + valueSize
  31653. for (let i = 0; i !== valueSize; i++) {
  31654. result[i] = values[offset + i]
  31655. }
  31656. return result
  31657. }
  31658. interpolate_(i1, t0, t, t1) {
  31659. const result = this.resultBuffer
  31660. const values = this.sampleValues
  31661. const stride = this.valueSize
  31662. const stride2 = stride * 2
  31663. const stride3 = stride * 3
  31664. const td = t1 - t0
  31665. const p = (t - t0) / td
  31666. const pp = p * p
  31667. const ppp = pp * p
  31668. const offset1 = i1 * stride3
  31669. const offset0 = offset1 - stride3
  31670. const s2 = -2 * ppp + 3 * pp
  31671. const s3 = ppp - pp
  31672. const s0 = 1 - s2
  31673. const s1 = s3 - pp + p // Layout of keyframe output values for CUBICSPLINE animations:
  31674. // [ inTangent_1, splineVertex_1, outTangent_1, inTangent_2, splineVertex_2, ... ]
  31675. for (let i = 0; i !== stride; i++) {
  31676. const p0 = values[offset0 + i + stride] // splineVertex_k
  31677. const m0 = values[offset0 + i + stride2] * td // outTangent_k * (t_k+1 - t_k)
  31678. const p1 = values[offset1 + i + stride] // splineVertex_k+1
  31679. const m1 = values[offset1 + i] * td // inTangent_k+1 * (t_k+1 - t_k)
  31680. result[i] = s0 * p0 + s1 * m0 + s2 * p1 + s3 * m1
  31681. }
  31682. return result
  31683. }
  31684. }
  31685. const _q = new THREE.Quaternion()
  31686. class GLTFCubicSplineQuaternionInterpolant extends GLTFCubicSplineInterpolant {
  31687. interpolate_(i1, t0, t, t1) {
  31688. const result = super.interpolate_(i1, t0, t, t1)
  31689. _q.fromArray(result).normalize().toArray(result)
  31690. return result
  31691. }
  31692. }
  31693. /*********************************/
  31694. /********** INTERNALS ************/
  31695. /*********************************/
  31696. /* CONSTANTS */
  31697. const WEBGL_CONSTANTS = {
  31698. FLOAT: 5126,
  31699. //FLOAT_MAT2: 35674,
  31700. FLOAT_MAT3: 35675,
  31701. FLOAT_MAT4: 35676,
  31702. FLOAT_VEC2: 35664,
  31703. FLOAT_VEC3: 35665,
  31704. FLOAT_VEC4: 35666,
  31705. LINEAR: 9729,
  31706. REPEAT: 10497,
  31707. SAMPLER_2D: 35678,
  31708. POINTS: 0,
  31709. LINES: 1,
  31710. LINE_LOOP: 2,
  31711. LINE_STRIP: 3,
  31712. TRIANGLES: 4,
  31713. TRIANGLE_STRIP: 5,
  31714. TRIANGLE_FAN: 6,
  31715. UNSIGNED_BYTE: 5121,
  31716. UNSIGNED_SHORT: 5123,
  31717. }
  31718. const WEBGL_COMPONENT_TYPES = {
  31719. 5120: Int8Array,
  31720. 5121: Uint8Array,
  31721. 5122: Int16Array,
  31722. 5123: Uint16Array,
  31723. 5125: Uint32Array,
  31724. 5126: Float32Array,
  31725. }
  31726. const WEBGL_FILTERS = {
  31727. 9728: THREE.NearestFilter,
  31728. 9729: THREE.LinearFilter,
  31729. 9984: THREE.NearestMipmapNearestFilter,
  31730. 9985: THREE.LinearMipmapNearestFilter,
  31731. 9986: THREE.NearestMipmapLinearFilter,
  31732. 9987: THREE.LinearMipmapLinearFilter,
  31733. }
  31734. const WEBGL_WRAPPINGS = {
  31735. 33071: THREE.ClampToEdgeWrapping,
  31736. 33648: THREE.MirroredRepeatWrapping,
  31737. 10497: THREE.RepeatWrapping,
  31738. }
  31739. const WEBGL_TYPE_SIZES = {
  31740. SCALAR: 1,
  31741. VEC2: 2,
  31742. VEC3: 3,
  31743. VEC4: 4,
  31744. MAT2: 4,
  31745. MAT3: 9,
  31746. MAT4: 16,
  31747. }
  31748. const ATTRIBUTES = {
  31749. POSITION: 'position',
  31750. NORMAL: 'normal',
  31751. TANGENT: 'tangent',
  31752. TEXCOORD_0: 'uv',
  31753. TEXCOORD_1: 'uv2',
  31754. COLOR_0: 'color',
  31755. WEIGHTS_0: 'skinWeight',
  31756. JOINTS_0: 'skinIndex',
  31757. }
  31758. const PATH_PROPERTIES = {
  31759. scale: 'scale',
  31760. translation: 'position',
  31761. rotation: 'quaternion',
  31762. weights: 'morphTargetInfluences',
  31763. }
  31764. const INTERPOLATION = {
  31765. CUBICSPLINE: undefined,
  31766. // We use a custom interpolant (GLTFCubicSplineInterpolation) for CUBICSPLINE tracks. Each
  31767. // keyframe track will be initialized with a default interpolation type, then modified.
  31768. LINEAR: THREE.InterpolateLinear,
  31769. STEP: THREE.InterpolateDiscrete,
  31770. }
  31771. const ALPHA_MODES = {
  31772. OPAQUE: 'OPAQUE',
  31773. MASK: 'MASK',
  31774. BLEND: 'BLEND',
  31775. }
  31776. /**
  31777. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#default-material
  31778. */
  31779. function createDefaultMaterial(cache) {
  31780. if (cache['DefaultMaterial'] === undefined) {
  31781. cache['DefaultMaterial'] = new THREE.MeshStandardMaterial({
  31782. color: 0xffffff,
  31783. emissive: 0x000000,
  31784. metalness: 1,
  31785. roughness: 1,
  31786. transparent: false,
  31787. depthTest: true,
  31788. side: THREE.FrontSide,
  31789. })
  31790. }
  31791. return cache['DefaultMaterial']
  31792. }
  31793. function addUnknownExtensionsToUserData(knownExtensions, object, objectDef) {
  31794. // Add unknown glTF extensions to an object's userData.
  31795. for (const name in objectDef.extensions) {
  31796. if (knownExtensions[name] === undefined) {
  31797. object.userData.gltfExtensions = object.userData.gltfExtensions || {}
  31798. object.userData.gltfExtensions[name] = objectDef.extensions[name]
  31799. }
  31800. }
  31801. }
  31802. /**
  31803. * @param {Object3D|Material|BufferGeometry} object
  31804. * @param {GLTF.definition} gltfDef
  31805. */
  31806. function assignExtrasToUserData(object, gltfDef) {
  31807. if (gltfDef.extras !== undefined) {
  31808. if (typeof gltfDef.extras === 'object') {
  31809. Object.assign(object.userData, gltfDef.extras)
  31810. } else {
  31811. console.warn('THREE.GLTFLoader: Ignoring primitive type .extras, ' + gltfDef.extras)
  31812. }
  31813. }
  31814. }
  31815. /**
  31816. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#morph-targets
  31817. *
  31818. * @param {BufferGeometry} geometry
  31819. * @param {Array<GLTF.Target>} targets
  31820. * @param {GLTFParser} parser
  31821. * @return {Promise<BufferGeometry>}
  31822. */
  31823. function addMorphTargets(geometry, targets, parser) {
  31824. let hasMorphPosition = false
  31825. let hasMorphNormal = false
  31826. let hasMorphColor = false
  31827. for (let i = 0, il = targets.length; i < il; i++) {
  31828. const target = targets[i]
  31829. if (target.POSITION !== undefined) hasMorphPosition = true
  31830. if (target.NORMAL !== undefined) hasMorphNormal = true
  31831. if (target.COLOR_0 !== undefined) hasMorphColor = true
  31832. if (hasMorphPosition && hasMorphNormal && hasMorphColor) break
  31833. }
  31834. if (!hasMorphPosition && !hasMorphNormal && !hasMorphColor) return Promise.resolve(geometry)
  31835. const pendingPositionAccessors = []
  31836. const pendingNormalAccessors = []
  31837. const pendingColorAccessors = []
  31838. for (let i = 0, il = targets.length; i < il; i++) {
  31839. const target = targets[i]
  31840. if (hasMorphPosition) {
  31841. const pendingAccessor = target.POSITION !== undefined ? parser.getDependency('accessor', target.POSITION) : geometry.attributes.position
  31842. pendingPositionAccessors.push(pendingAccessor)
  31843. }
  31844. if (hasMorphNormal) {
  31845. const pendingAccessor = target.NORMAL !== undefined ? parser.getDependency('accessor', target.NORMAL) : geometry.attributes.normal
  31846. pendingNormalAccessors.push(pendingAccessor)
  31847. }
  31848. if (hasMorphColor) {
  31849. const pendingAccessor = target.COLOR_0 !== undefined ? parser.getDependency('accessor', target.COLOR_0) : geometry.attributes.color
  31850. pendingColorAccessors.push(pendingAccessor)
  31851. }
  31852. }
  31853. return Promise.all([Promise.all(pendingPositionAccessors), Promise.all(pendingNormalAccessors), Promise.all(pendingColorAccessors)]).then(function (accessors) {
  31854. const morphPositions = accessors[0]
  31855. const morphNormals = accessors[1]
  31856. const morphColors = accessors[2]
  31857. if (hasMorphPosition) geometry.morphAttributes.position = morphPositions
  31858. if (hasMorphNormal) geometry.morphAttributes.normal = morphNormals
  31859. if (hasMorphColor) geometry.morphAttributes.color = morphColors
  31860. geometry.morphTargetsRelative = true
  31861. return geometry
  31862. })
  31863. }
  31864. /**
  31865. * @param {Mesh} mesh
  31866. * @param {GLTF.Mesh} meshDef
  31867. */
  31868. function updateMorphTargets(mesh, meshDef) {
  31869. mesh.updateMorphTargets()
  31870. if (meshDef.weights !== undefined) {
  31871. for (let i = 0, il = meshDef.weights.length; i < il; i++) {
  31872. mesh.morphTargetInfluences[i] = meshDef.weights[i]
  31873. }
  31874. } // .extras has user-defined data, so check that .extras.targetNames is an array.
  31875. if (meshDef.extras && Array.isArray(meshDef.extras.targetNames)) {
  31876. const targetNames = meshDef.extras.targetNames
  31877. if (mesh.morphTargetInfluences.length === targetNames.length) {
  31878. mesh.morphTargetDictionary = {}
  31879. for (let i = 0, il = targetNames.length; i < il; i++) {
  31880. mesh.morphTargetDictionary[targetNames[i]] = i
  31881. }
  31882. } else {
  31883. console.warn('THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.')
  31884. }
  31885. }
  31886. }
  31887. function createPrimitiveKey(primitiveDef) {
  31888. const dracoExtension = primitiveDef.extensions && primitiveDef.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]
  31889. let geometryKey
  31890. if (dracoExtension) {
  31891. geometryKey = 'draco:' + dracoExtension.bufferView + ':' + dracoExtension.indices + ':' + createAttributesKey(dracoExtension.attributes)
  31892. } else {
  31893. geometryKey = primitiveDef.indices + ':' + createAttributesKey(primitiveDef.attributes) + ':' + primitiveDef.mode
  31894. }
  31895. return geometryKey
  31896. }
  31897. function createAttributesKey(attributes) {
  31898. let attributesKey = ''
  31899. const keys = Object.keys(attributes).sort()
  31900. for (let i = 0, il = keys.length; i < il; i++) {
  31901. attributesKey += keys[i] + ':' + attributes[keys[i]] + ';'
  31902. }
  31903. return attributesKey
  31904. }
  31905. function getNormalizedComponentScale(constructor) {
  31906. // Reference:
  31907. // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization#encoding-quantized-data
  31908. switch (constructor) {
  31909. case Int8Array:
  31910. return 1 / 127
  31911. case Uint8Array:
  31912. return 1 / 255
  31913. case Int16Array:
  31914. return 1 / 32767
  31915. case Uint16Array:
  31916. return 1 / 65535
  31917. default:
  31918. throw new Error('THREE.GLTFLoader: Unsupported normalized accessor component type.')
  31919. }
  31920. }
  31921. function getImageURIMimeType(uri) {
  31922. if (uri.search(/\.jpe?g($|\?)/i) > 0 || uri.search(/^data\:image\/jpeg/) === 0) return 'image/jpeg'
  31923. if (uri.search(/\.webp($|\?)/i) > 0 || uri.search(/^data\:image\/webp/) === 0) return 'image/webp'
  31924. return 'image/png'
  31925. }
  31926. /* GLTF PARSER */
  31927. class GLTFParser {
  31928. constructor(json = {}, options = {}) {
  31929. this.json = json
  31930. this.extensions = {}
  31931. this.plugins = {}
  31932. this.options = options // loader object cache
  31933. this.cache = new GLTFRegistry() // associations between Three.js objects and glTF elements
  31934. this.associations = new Map() // THREE.BufferGeometry caching
  31935. this.primitiveCache = {} // THREE.Object3D instance caches
  31936. this.meshCache = {
  31937. refs: {},
  31938. uses: {},
  31939. }
  31940. this.cameraCache = {
  31941. refs: {},
  31942. uses: {},
  31943. }
  31944. this.lightCache = {
  31945. refs: {},
  31946. uses: {},
  31947. }
  31948. this.sourceCache = {}
  31949. this.textureCache = {} // Track node names, to ensure no duplicates
  31950. this.nodeNamesUsed = {} // Use an THREE.ImageBitmapLoader if imageBitmaps are supported. Moves much of the
  31951. // expensive work of uploading a texture to the GPU off the main thread.
  31952. const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) === true
  31953. const isFirefox = navigator.userAgent.indexOf('Firefox') > -1
  31954. const firefoxVersion = isFirefox ? navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1] : -1
  31955. if (typeof createImageBitmap === 'undefined' || isSafari || (isFirefox && firefoxVersion < 98)) {
  31956. this.textureLoader = new THREE.TextureLoader(this.options.manager)
  31957. } else {
  31958. this.textureLoader = new THREE.ImageBitmapLoader(this.options.manager)
  31959. }
  31960. this.textureLoader.setCrossOrigin(this.options.crossOrigin)
  31961. this.textureLoader.setRequestHeader(this.options.requestHeader)
  31962. this.fileLoader = new THREE.FileLoader(this.options.manager)
  31963. this.fileLoader.setResponseType('arraybuffer')
  31964. if (this.options.crossOrigin === 'use-credentials') {
  31965. this.fileLoader.setWithCredentials(true)
  31966. }
  31967. }
  31968. setExtensions(extensions) {
  31969. this.extensions = extensions
  31970. }
  31971. setPlugins(plugins) {
  31972. this.plugins = plugins
  31973. }
  31974. parse(onLoad, onError) {
  31975. const parser = this
  31976. const json = this.json
  31977. const extensions = this.extensions // Clear the loader cache
  31978. this.cache.removeAll() // Mark the special nodes/meshes in json for efficient parse
  31979. this._invokeAll(function (ext) {
  31980. return ext._markDefs && ext._markDefs()
  31981. })
  31982. Promise.all(
  31983. this._invokeAll(function (ext) {
  31984. return ext.beforeRoot && ext.beforeRoot()
  31985. })
  31986. )
  31987. .then(function () {
  31988. return Promise.all([parser.getDependencies('scene'), parser.getDependencies('animation'), parser.getDependencies('camera')])
  31989. })
  31990. .then(function (dependencies) {
  31991. const result = {
  31992. scene: dependencies[0][json.scene || 0],
  31993. scenes: dependencies[0],
  31994. animations: dependencies[1],
  31995. cameras: dependencies[2],
  31996. asset: json.asset,
  31997. parser: parser,
  31998. userData: {},
  31999. }
  32000. addUnknownExtensionsToUserData(extensions, result, json)
  32001. assignExtrasToUserData(result, json)
  32002. Promise.all(
  32003. parser._invokeAll(function (ext) {
  32004. return ext.afterRoot && ext.afterRoot(result)
  32005. })
  32006. ).then(function () {
  32007. onLoad(result)
  32008. })
  32009. })
  32010. .catch(onError)
  32011. }
  32012. /**
  32013. * Marks the special nodes/meshes in json for efficient parse.
  32014. */
  32015. _markDefs() {
  32016. const nodeDefs = this.json.nodes || []
  32017. const skinDefs = this.json.skins || []
  32018. const meshDefs = this.json.meshes || [] // Nothing in the node definition indicates whether it is a THREE.Bone or an
  32019. // THREE.Object3D. Use the skins' joint references to mark bones.
  32020. for (let skinIndex = 0, skinLength = skinDefs.length; skinIndex < skinLength; skinIndex++) {
  32021. const joints = skinDefs[skinIndex].joints
  32022. for (let i = 0, il = joints.length; i < il; i++) {
  32023. nodeDefs[joints[i]].isBone = true
  32024. }
  32025. } // Iterate over all nodes, marking references to shared resources,
  32026. // as well as skeleton joints.
  32027. for (let nodeIndex = 0, nodeLength = nodeDefs.length; nodeIndex < nodeLength; nodeIndex++) {
  32028. const nodeDef = nodeDefs[nodeIndex]
  32029. if (nodeDef.mesh !== undefined) {
  32030. this._addNodeRef(this.meshCache, nodeDef.mesh) // Nothing in the mesh definition indicates whether it is
  32031. // a THREE.SkinnedMesh or THREE.Mesh. Use the node's mesh reference
  32032. // to mark THREE.SkinnedMesh if node has skin.
  32033. if (nodeDef.skin !== undefined) {
  32034. meshDefs[nodeDef.mesh].isSkinnedMesh = true
  32035. }
  32036. }
  32037. if (nodeDef.camera !== undefined) {
  32038. this._addNodeRef(this.cameraCache, nodeDef.camera)
  32039. }
  32040. }
  32041. }
  32042. /**
  32043. * Counts references to shared node / THREE.Object3D resources. These resources
  32044. * can be reused, or "instantiated", at multiple nodes in the scene
  32045. * hierarchy. THREE.Mesh, Camera, and Light instances are instantiated and must
  32046. * be marked. Non-scenegraph resources (like Materials, Geometries, and
  32047. * Textures) can be reused directly and are not marked here.
  32048. *
  32049. * Example: CesiumMilkTruck sample model reuses "Wheel" meshes.
  32050. */
  32051. _addNodeRef(cache, index) {
  32052. if (index === undefined) return
  32053. if (cache.refs[index] === undefined) {
  32054. cache.refs[index] = cache.uses[index] = 0
  32055. }
  32056. cache.refs[index]++
  32057. }
  32058. /** Returns a reference to a shared resource, cloning it if necessary. */
  32059. _getNodeRef(cache, index, object) {
  32060. if (cache.refs[index] <= 1) return object
  32061. const ref = object.clone() // Propagates mappings to the cloned object, prevents mappings on the
  32062. // original object from being lost.
  32063. const updateMappings = (original, clone) => {
  32064. const mappings = this.associations.get(original)
  32065. if (mappings != null) {
  32066. this.associations.set(clone, mappings)
  32067. }
  32068. for (const [i, child] of original.children.entries()) {
  32069. updateMappings(child, clone.children[i])
  32070. }
  32071. }
  32072. updateMappings(object, ref)
  32073. ref.name += '_instance_' + cache.uses[index]++
  32074. return ref
  32075. }
  32076. _invokeOne(func) {
  32077. const extensions = Object.values(this.plugins)
  32078. extensions.push(this)
  32079. for (let i = 0; i < extensions.length; i++) {
  32080. const result = func(extensions[i])
  32081. if (result) return result
  32082. }
  32083. return null
  32084. }
  32085. _invokeAll(func) {
  32086. const extensions = Object.values(this.plugins)
  32087. extensions.unshift(this)
  32088. const pending = []
  32089. for (let i = 0; i < extensions.length; i++) {
  32090. const result = func(extensions[i])
  32091. if (result) pending.push(result)
  32092. }
  32093. return pending
  32094. }
  32095. /**
  32096. * Requests the specified dependency asynchronously, with caching.
  32097. * @param {string} type
  32098. * @param {number} index
  32099. * @return {Promise<Object3D|Material|THREE.Texture|AnimationClip|ArrayBuffer|Object>}
  32100. */
  32101. getDependency(type, index) {
  32102. const cacheKey = type + ':' + index
  32103. let dependency = this.cache.get(cacheKey)
  32104. if (!dependency) {
  32105. switch (type) {
  32106. case 'scene':
  32107. dependency = this.loadScene(index)
  32108. break
  32109. case 'node':
  32110. dependency = this.loadNode(index)
  32111. break
  32112. case 'mesh':
  32113. dependency = this._invokeOne(function (ext) {
  32114. return ext.loadMesh && ext.loadMesh(index)
  32115. })
  32116. break
  32117. case 'accessor':
  32118. dependency = this.loadAccessor(index)
  32119. break
  32120. case 'bufferView':
  32121. dependency = this._invokeOne(function (ext) {
  32122. return ext.loadBufferView && ext.loadBufferView(index)
  32123. })
  32124. break
  32125. case 'buffer':
  32126. dependency = this.loadBuffer(index)
  32127. break
  32128. case 'material':
  32129. dependency = this._invokeOne(function (ext) {
  32130. return ext.loadMaterial && ext.loadMaterial(index)
  32131. })
  32132. break
  32133. case 'texture':
  32134. dependency = this._invokeOne(function (ext) {
  32135. return ext.loadTexture && ext.loadTexture(index)
  32136. })
  32137. break
  32138. case 'skin':
  32139. dependency = this.loadSkin(index)
  32140. break
  32141. case 'animation':
  32142. dependency = this._invokeOne(function (ext) {
  32143. return ext.loadAnimation && ext.loadAnimation(index)
  32144. })
  32145. break
  32146. case 'camera':
  32147. dependency = this.loadCamera(index)
  32148. break
  32149. default:
  32150. throw new Error('Unknown type: ' + type)
  32151. }
  32152. this.cache.add(cacheKey, dependency)
  32153. }
  32154. return dependency
  32155. }
  32156. /**
  32157. * Requests all dependencies of the specified type asynchronously, with caching.
  32158. * @param {string} type
  32159. * @return {Promise<Array<Object>>}
  32160. */
  32161. getDependencies(type) {
  32162. let dependencies = this.cache.get(type)
  32163. if (!dependencies) {
  32164. const parser = this
  32165. const defs = this.json[type + (type === 'mesh' ? 'es' : 's')] || []
  32166. dependencies = Promise.all(
  32167. defs.map(function (def, index) {
  32168. return parser.getDependency(type, index)
  32169. })
  32170. )
  32171. this.cache.add(type, dependencies)
  32172. }
  32173. return dependencies
  32174. }
  32175. /**
  32176. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
  32177. * @param {number} bufferIndex
  32178. * @return {Promise<ArrayBuffer>}
  32179. */
  32180. loadBuffer(bufferIndex) {
  32181. const bufferDef = this.json.buffers[bufferIndex]
  32182. const loader = this.fileLoader
  32183. if (bufferDef.type && bufferDef.type !== 'arraybuffer') {
  32184. throw new Error('THREE.GLTFLoader: ' + bufferDef.type + ' buffer type is not supported.')
  32185. } // If present, GLB container is required to be the first buffer.
  32186. if (bufferDef.uri === undefined && bufferIndex === 0) {
  32187. return Promise.resolve(this.extensions[EXTENSIONS.KHR_BINARY_GLTF].body)
  32188. }
  32189. const options = this.options
  32190. return new Promise(function (resolve, reject) {
  32191. loader.load(THREE.LoaderUtils.resolveURL(bufferDef.uri, options.path), resolve, undefined, function () {
  32192. reject(new Error('THREE.GLTFLoader: Failed to load buffer "' + bufferDef.uri + '".'))
  32193. })
  32194. })
  32195. }
  32196. /**
  32197. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#buffers-and-buffer-views
  32198. * @param {number} bufferViewIndex
  32199. * @return {Promise<ArrayBuffer>}
  32200. */
  32201. loadBufferView(bufferViewIndex) {
  32202. const bufferViewDef = this.json.bufferViews[bufferViewIndex]
  32203. return this.getDependency('buffer', bufferViewDef.buffer).then(function (buffer) {
  32204. const byteLength = bufferViewDef.byteLength || 0
  32205. const byteOffset = bufferViewDef.byteOffset || 0
  32206. return buffer.slice(byteOffset, byteOffset + byteLength)
  32207. })
  32208. }
  32209. /**
  32210. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#accessors
  32211. * @param {number} accessorIndex
  32212. * @return {Promise<BufferAttribute|InterleavedBufferAttribute>}
  32213. */
  32214. loadAccessor(accessorIndex) {
  32215. const parser = this
  32216. const json = this.json
  32217. const accessorDef = this.json.accessors[accessorIndex]
  32218. if (accessorDef.bufferView === undefined && accessorDef.sparse === undefined) {
  32219. // Ignore empty accessors, which may be used to declare runtime
  32220. // information about attributes coming from another source (e.g. Draco
  32221. // compression extension).
  32222. return Promise.resolve(null)
  32223. }
  32224. const pendingBufferViews = []
  32225. if (accessorDef.bufferView !== undefined) {
  32226. pendingBufferViews.push(this.getDependency('bufferView', accessorDef.bufferView))
  32227. } else {
  32228. pendingBufferViews.push(null)
  32229. }
  32230. if (accessorDef.sparse !== undefined) {
  32231. pendingBufferViews.push(this.getDependency('bufferView', accessorDef.sparse.indices.bufferView))
  32232. pendingBufferViews.push(this.getDependency('bufferView', accessorDef.sparse.values.bufferView))
  32233. }
  32234. return Promise.all(pendingBufferViews).then(function (bufferViews) {
  32235. const bufferView = bufferViews[0]
  32236. const itemSize = WEBGL_TYPE_SIZES[accessorDef.type]
  32237. const TypedArray = WEBGL_COMPONENT_TYPES[accessorDef.componentType] // For VEC3: itemSize is 3, elementBytes is 4, itemBytes is 12.
  32238. const elementBytes = TypedArray.BYTES_PER_ELEMENT
  32239. const itemBytes = elementBytes * itemSize
  32240. const byteOffset = accessorDef.byteOffset || 0
  32241. const byteStride = accessorDef.bufferView !== undefined ? json.bufferViews[accessorDef.bufferView].byteStride : undefined
  32242. const normalized = accessorDef.normalized === true
  32243. let array, bufferAttribute // The buffer is not interleaved if the stride is the item size in bytes.
  32244. if (byteStride && byteStride !== itemBytes) {
  32245. // Each "slice" of the buffer, as defined by 'count' elements of 'byteStride' bytes, gets its own THREE.InterleavedBuffer
  32246. // This makes sure that IBA.count reflects accessor.count properly
  32247. const ibSlice = Math.floor(byteOffset / byteStride)
  32248. const ibCacheKey = 'InterleavedBuffer:' + accessorDef.bufferView + ':' + accessorDef.componentType + ':' + ibSlice + ':' + accessorDef.count
  32249. let ib = parser.cache.get(ibCacheKey)
  32250. if (!ib) {
  32251. array = new TypedArray(bufferView, ibSlice * byteStride, (accessorDef.count * byteStride) / elementBytes) // Integer parameters to IB/IBA are in array elements, not bytes.
  32252. ib = new THREE.InterleavedBuffer(array, byteStride / elementBytes)
  32253. parser.cache.add(ibCacheKey, ib)
  32254. }
  32255. bufferAttribute = new THREE.InterleavedBufferAttribute(ib, itemSize, (byteOffset % byteStride) / elementBytes, normalized)
  32256. } else {
  32257. if (bufferView === null) {
  32258. array = new TypedArray(accessorDef.count * itemSize)
  32259. } else {
  32260. array = new TypedArray(bufferView, byteOffset, accessorDef.count * itemSize)
  32261. }
  32262. bufferAttribute = new THREE.BufferAttribute(array, itemSize, normalized)
  32263. } // https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#sparse-accessors
  32264. if (accessorDef.sparse !== undefined) {
  32265. const itemSizeIndices = WEBGL_TYPE_SIZES.SCALAR
  32266. const TypedArrayIndices = WEBGL_COMPONENT_TYPES[accessorDef.sparse.indices.componentType]
  32267. const byteOffsetIndices = accessorDef.sparse.indices.byteOffset || 0
  32268. const byteOffsetValues = accessorDef.sparse.values.byteOffset || 0
  32269. const sparseIndices = new TypedArrayIndices(bufferViews[1], byteOffsetIndices, accessorDef.sparse.count * itemSizeIndices)
  32270. const sparseValues = new TypedArray(bufferViews[2], byteOffsetValues, accessorDef.sparse.count * itemSize)
  32271. if (bufferView !== null) {
  32272. // Avoid modifying the original ArrayBuffer, if the bufferView wasn't initialized with zeroes.
  32273. bufferAttribute = new THREE.BufferAttribute(bufferAttribute.array.slice(), bufferAttribute.itemSize, bufferAttribute.normalized)
  32274. }
  32275. for (let i = 0, il = sparseIndices.length; i < il; i++) {
  32276. const index = sparseIndices[i]
  32277. bufferAttribute.setX(index, sparseValues[i * itemSize])
  32278. if (itemSize >= 2) bufferAttribute.setY(index, sparseValues[i * itemSize + 1])
  32279. if (itemSize >= 3) bufferAttribute.setZ(index, sparseValues[i * itemSize + 2])
  32280. if (itemSize >= 4) bufferAttribute.setW(index, sparseValues[i * itemSize + 3])
  32281. if (itemSize >= 5) throw new Error('THREE.GLTFLoader: Unsupported itemSize in sparse THREE.BufferAttribute.')
  32282. }
  32283. }
  32284. return bufferAttribute
  32285. })
  32286. }
  32287. /**
  32288. * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#textures
  32289. * @param {number} textureIndex
  32290. * @return {Promise<THREE.Texture>}
  32291. */
  32292. loadTexture(textureIndex) {
  32293. const json = this.json
  32294. const options = this.options
  32295. const textureDef = json.textures[textureIndex]
  32296. const sourceIndex = textureDef.source
  32297. const sourceDef = json.images[sourceIndex]
  32298. let loader = this.textureLoader
  32299. if (sourceDef.uri) {
  32300. const handler = options.manager.getHandler(sourceDef.uri)
  32301. if (handler !== null) loader = handler
  32302. }
  32303. return this.loadTextureImage(textureIndex, sourceIndex, loader)
  32304. }
  32305. loadTextureImage(textureIndex, sourceIndex, loader) {
  32306. const parser = this
  32307. const json = this.json
  32308. const textureDef = json.textures[textureIndex]
  32309. const sourceDef = json.images[sourceIndex]
  32310. const cacheKey = (sourceDef.uri || sourceDef.bufferView) + ':' + textureDef.sampler
  32311. if (this.textureCache[cacheKey]) {
  32312. // See https://github.com/mrdoob/three.js/issues/21559.
  32313. return this.textureCache[cacheKey]
  32314. }
  32315. const promise = this.loadImageSource(sourceIndex, loader)
  32316. .then(function (texture) {
  32317. texture.flipY = false
  32318. if (textureDef.name) texture.name = textureDef.name
  32319. const samplers = json.samplers || {}
  32320. const sampler = samplers[textureDef.sampler] || {}
  32321. texture.magFilter = WEBGL_FILTERS[sampler.magFilter] || THREE.LinearFilter
  32322. texture.minFilter = WEBGL_FILTERS[sampler.minFilter] || THREE.LinearMipmapLinearFilter
  32323. texture.wrapS = WEBGL_WRAPPINGS[sampler.wrapS] || THREE.RepeatWrapping
  32324. texture.wrapT = WEBGL_WRAPPINGS[sampler.wrapT] || THREE.RepeatWrapping
  32325. parser.associations.set(texture, {
  32326. textures: textureIndex,
  32327. })
  32328. return texture
  32329. })
  32330. .catch(function () {
  32331. return null
  32332. })
  32333. this.textureCache[cacheKey] = promise
  32334. return promise
  32335. }
  32336. loadImageSource(sourceIndex, loader) {
  32337. const parser = this
  32338. const json = this.json
  32339. const options = this.options
  32340. if (this.sourceCache[sourceIndex] !== undefined) {
  32341. return this.sourceCache[sourceIndex].then(texture => texture.clone())
  32342. }
  32343. const sourceDef = json.images[sourceIndex]
  32344. const URL = self.URL || self.webkitURL
  32345. let sourceURI = sourceDef.uri || ''
  32346. let isObjectURL = false
  32347. if (sourceDef.bufferView !== undefined) {
  32348. // Load binary image data from bufferView, if provided.
  32349. sourceURI = parser.getDependency('bufferView', sourceDef.bufferView).then(function (bufferView) {
  32350. isObjectURL = true
  32351. const blob = new Blob([bufferView], {
  32352. type: sourceDef.mimeType,
  32353. })
  32354. sourceURI = URL.createObjectURL(blob)
  32355. return sourceURI
  32356. })
  32357. } else if (sourceDef.uri === undefined) {
  32358. throw new Error('THREE.GLTFLoader: Image ' + sourceIndex + ' is missing URI and bufferView')
  32359. }
  32360. const promise = Promise.resolve(sourceURI)
  32361. .then(function (sourceURI) {
  32362. return new Promise(function (resolve, reject) {
  32363. let onLoad = resolve
  32364. if (loader.isImageBitmapLoader === true) {
  32365. onLoad = function (imageBitmap) {
  32366. const texture = new THREE.Texture(imageBitmap)
  32367. texture.needsUpdate = true
  32368. resolve(texture)
  32369. }
  32370. }
  32371. loader.load(THREE.LoaderUtils.resolveURL(sourceURI, options.path), onLoad, undefined, reject)
  32372. })
  32373. })
  32374. .then(function (texture) {
  32375. // Clean up resources and configure THREE.Texture.
  32376. if (isObjectURL === true) {
  32377. URL.revokeObjectURL(sourceURI)
  32378. }
  32379. texture.userData.mimeType = sourceDef.mimeType || getImageURIMimeType(sourceDef.uri)
  32380. return texture
  32381. })
  32382. .catch(function (error) {
  32383. console.error("THREE.GLTFLoader: Couldn't load texture", sourceURI)
  32384. throw error
  32385. })
  32386. this.sourceCache[sourceIndex] = promise
  32387. return promise
  32388. }
  32389. /**
  32390. * Asynchronously assigns a texture to the given material parameters.
  32391. * @param {Object} materialParams
  32392. * @param {string} mapName
  32393. * @param {Object} mapDef
  32394. * @return {Promise<Texture>}
  32395. */
  32396. assignTexture(materialParams, mapName, mapDef, encoding) {
  32397. const parser = this
  32398. return this.getDependency('texture', mapDef.index).then(function (texture) {
  32399. // Materials sample aoMap from UV set 1 and other maps from UV set 0 - this can't be configured
  32400. // However, we will copy UV set 0 to UV set 1 on demand for aoMap
  32401. if (mapDef.texCoord !== undefined && mapDef.texCoord != 0 && !(mapName === 'aoMap' && mapDef.texCoord == 1)) {
  32402. console.warn('THREE.GLTFLoader: Custom UV set ' + mapDef.texCoord + ' for texture ' + mapName + ' not yet supported.')
  32403. }
  32404. if (parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM]) {
  32405. const transform = mapDef.extensions !== undefined ? mapDef.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM] : undefined
  32406. if (transform) {
  32407. const gltfReference = parser.associations.get(texture)
  32408. texture = parser.extensions[EXTENSIONS.KHR_TEXTURE_TRANSFORM].extendTexture(texture, transform)
  32409. parser.associations.set(texture, gltfReference)
  32410. }
  32411. }
  32412. if (encoding !== undefined) {
  32413. texture.encoding = encoding
  32414. }
  32415. materialParams[mapName] = texture
  32416. return texture
  32417. })
  32418. }
  32419. /**
  32420. * Assigns final material to a THREE.Mesh, THREE.Line, or THREE.Points instance. The instance
  32421. * already has a material (generated from the glTF material options alone)
  32422. * but reuse of the same glTF material may require multiple threejs materials
  32423. * to accommodate different primitive types, defines, etc. New materials will
  32424. * be created if necessary, and reused from a cache.
  32425. * @param {Object3D} mesh THREE.Mesh, THREE.Line, or THREE.Points instance.
  32426. */
  32427. assignFinalMaterial(mesh) {
  32428. const geometry = mesh.geometry
  32429. let material = mesh.material
  32430. const useDerivativeTangents = geometry.attributes.tangent === undefined
  32431. const useVertexColors = geometry.attributes.color !== undefined
  32432. const useFlatShading = geometry.attributes.normal === undefined
  32433. if (mesh.isPoints) {
  32434. const cacheKey = 'PointsMaterial:' + material.uuid
  32435. let pointsMaterial = this.cache.get(cacheKey)
  32436. if (!pointsMaterial) {
  32437. pointsMaterial = new THREE.PointsMaterial()
  32438. THREE.Material.prototype.copy.call(pointsMaterial, material)
  32439. pointsMaterial.color.copy(material.color)
  32440. pointsMaterial.map = material.map
  32441. pointsMaterial.sizeAttenuation = false // glTF spec says points should be 1px
  32442. this.cache.add(cacheKey, pointsMaterial)
  32443. }
  32444. material = pointsMaterial
  32445. } else if (mesh.isLine) {
  32446. const cacheKey = 'LineBasicMaterial:' + material.uuid
  32447. let lineMaterial = this.cache.get(cacheKey)
  32448. if (!lineMaterial) {
  32449. lineMaterial = new THREE.LineBasicMaterial()
  32450. THREE.Material.prototype.copy.call(lineMaterial, material)
  32451. lineMaterial.color.copy(material.color)
  32452. this.cache.add(cacheKey, lineMaterial)
  32453. }
  32454. material = lineMaterial
  32455. } // Clone the material if it will be modified
  32456. if (useDerivativeTangents || useVertexColors || useFlatShading) {
  32457. let cacheKey = 'ClonedMaterial:' + material.uuid + ':'
  32458. if (material.isGLTFSpecularGlossinessMaterial) cacheKey += 'specular-glossiness:'
  32459. if (useDerivativeTangents) cacheKey += 'derivative-tangents:'
  32460. if (useVertexColors) cacheKey += 'vertex-colors:'
  32461. if (useFlatShading) cacheKey += 'flat-shading:'
  32462. let cachedMaterial = this.cache.get(cacheKey)
  32463. if (!cachedMaterial) {
  32464. cachedMaterial = material.clone()
  32465. if (useVertexColors) cachedMaterial.vertexColors = true
  32466. if (useFlatShading) cachedMaterial.flatShading = true
  32467. if (useDerivativeTangents) {
  32468. // https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
  32469. if (cachedMaterial.normalScale) cachedMaterial.normalScale.y *= -1
  32470. if (cachedMaterial.clearcoatNormalScale) cachedMaterial.clearcoatNormalScale.y *= -1
  32471. }
  32472. this.cache.add(cacheKey, cachedMaterial)
  32473. this.associations.set(cachedMaterial, this.associations.get(material))
  32474. }
  32475. material = cachedMaterial
  32476. } // workarounds for mesh and geometry
  32477. if (material.aoMap && geometry.attributes.uv2 === undefined && geometry.attributes.uv !== undefined) {
  32478. geometry.setAttribute('uv2', geometry.attributes.uv)
  32479. }
  32480. mesh.material = material
  32481. }
  32482. getMaterialType() {
  32483. return THREE.MeshStandardMaterial
  32484. }
  32485. /**
  32486. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#materials
  32487. * @param {number} materialIndex
  32488. * @return {Promise<Material>}
  32489. */
  32490. loadMaterial(materialIndex) {
  32491. const parser = this
  32492. const json = this.json
  32493. const extensions = this.extensions
  32494. const materialDef = json.materials[materialIndex]
  32495. let materialType
  32496. const materialParams = {}
  32497. const materialExtensions = materialDef.extensions || {}
  32498. const pending = []
  32499. if (materialExtensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS]) {
  32500. const sgExtension = extensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS]
  32501. materialType = sgExtension.getMaterialType()
  32502. pending.push(sgExtension.extendParams(materialParams, materialDef, parser))
  32503. } else if (materialExtensions[EXTENSIONS.KHR_MATERIALS_UNLIT]) {
  32504. const kmuExtension = extensions[EXTENSIONS.KHR_MATERIALS_UNLIT]
  32505. materialType = kmuExtension.getMaterialType()
  32506. pending.push(kmuExtension.extendParams(materialParams, materialDef, parser))
  32507. } else {
  32508. // Specification:
  32509. // https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#metallic-roughness-material
  32510. const metallicRoughness = materialDef.pbrMetallicRoughness || {}
  32511. materialParams.color = new THREE.Color(1.0, 1.0, 1.0)
  32512. materialParams.opacity = 1.0
  32513. if (Array.isArray(metallicRoughness.baseColorFactor)) {
  32514. const array = metallicRoughness.baseColorFactor
  32515. materialParams.color.fromArray(array)
  32516. materialParams.opacity = array[3]
  32517. }
  32518. if (metallicRoughness.baseColorTexture !== undefined) {
  32519. pending.push(parser.assignTexture(materialParams, 'map', metallicRoughness.baseColorTexture, THREE.sRGBEncoding))
  32520. }
  32521. materialParams.metalness = metallicRoughness.metallicFactor !== undefined ? metallicRoughness.metallicFactor : 1.0
  32522. materialParams.roughness = metallicRoughness.roughnessFactor !== undefined ? metallicRoughness.roughnessFactor : 1.0
  32523. if (metallicRoughness.metallicRoughnessTexture !== undefined) {
  32524. pending.push(parser.assignTexture(materialParams, 'metalnessMap', metallicRoughness.metallicRoughnessTexture))
  32525. pending.push(parser.assignTexture(materialParams, 'roughnessMap', metallicRoughness.metallicRoughnessTexture))
  32526. }
  32527. materialType = this._invokeOne(function (ext) {
  32528. return ext.getMaterialType && ext.getMaterialType(materialIndex)
  32529. })
  32530. pending.push(
  32531. Promise.all(
  32532. this._invokeAll(function (ext) {
  32533. return ext.extendMaterialParams && ext.extendMaterialParams(materialIndex, materialParams)
  32534. })
  32535. )
  32536. )
  32537. }
  32538. if (materialDef.doubleSided === true) {
  32539. materialParams.side = THREE.DoubleSide
  32540. }
  32541. const alphaMode = materialDef.alphaMode || ALPHA_MODES.OPAQUE
  32542. if (alphaMode === ALPHA_MODES.BLEND) {
  32543. materialParams.transparent = true // See: https://github.com/mrdoob/three.js/issues/17706
  32544. materialParams.depthWrite = false
  32545. } else {
  32546. materialParams.transparent = false
  32547. if (alphaMode === ALPHA_MODES.MASK) {
  32548. materialParams.alphaTest = materialDef.alphaCutoff !== undefined ? materialDef.alphaCutoff : 0.5
  32549. }
  32550. }
  32551. if (materialDef.normalTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
  32552. pending.push(parser.assignTexture(materialParams, 'normalMap', materialDef.normalTexture))
  32553. materialParams.normalScale = new THREE.Vector2(1, 1)
  32554. if (materialDef.normalTexture.scale !== undefined) {
  32555. const scale = materialDef.normalTexture.scale
  32556. materialParams.normalScale.set(scale, scale)
  32557. }
  32558. }
  32559. if (materialDef.occlusionTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
  32560. pending.push(parser.assignTexture(materialParams, 'aoMap', materialDef.occlusionTexture))
  32561. if (materialDef.occlusionTexture.strength !== undefined) {
  32562. materialParams.aoMapIntensity = materialDef.occlusionTexture.strength
  32563. }
  32564. }
  32565. if (materialDef.emissiveFactor !== undefined && materialType !== THREE.MeshBasicMaterial) {
  32566. materialParams.emissive = new THREE.Color().fromArray(materialDef.emissiveFactor)
  32567. }
  32568. if (materialDef.emissiveTexture !== undefined && materialType !== THREE.MeshBasicMaterial) {
  32569. pending.push(parser.assignTexture(materialParams, 'emissiveMap', materialDef.emissiveTexture, THREE.sRGBEncoding))
  32570. }
  32571. return Promise.all(pending).then(function () {
  32572. let material
  32573. if (materialType === GLTFMeshStandardSGMaterial) {
  32574. material = extensions[EXTENSIONS.KHR_MATERIALS_PBR_SPECULAR_GLOSSINESS].createMaterial(materialParams)
  32575. } else {
  32576. material = new materialType(materialParams)
  32577. }
  32578. if (materialDef.name) material.name = materialDef.name
  32579. assignExtrasToUserData(material, materialDef)
  32580. parser.associations.set(material, {
  32581. materials: materialIndex,
  32582. })
  32583. if (materialDef.extensions) addUnknownExtensionsToUserData(extensions, material, materialDef)
  32584. return material
  32585. })
  32586. }
  32587. /** When THREE.Object3D instances are targeted by animation, they need unique names. */
  32588. createUniqueName(originalName) {
  32589. const sanitizedName = THREE.PropertyBinding.sanitizeNodeName(originalName || '')
  32590. let name = sanitizedName
  32591. for (let i = 1; this.nodeNamesUsed[name]; ++i) {
  32592. name = sanitizedName + '_' + i
  32593. }
  32594. this.nodeNamesUsed[name] = true
  32595. return name
  32596. }
  32597. /**
  32598. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#geometry
  32599. *
  32600. * Creates BufferGeometries from primitives.
  32601. *
  32602. * @param {Array<GLTF.Primitive>} primitives
  32603. * @return {Promise<Array<BufferGeometry>>}
  32604. */
  32605. loadGeometries(primitives) {
  32606. const parser = this
  32607. const extensions = this.extensions
  32608. const cache = this.primitiveCache
  32609. function createDracoPrimitive(primitive) {
  32610. return extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(primitive, parser).then(function (geometry) {
  32611. return addPrimitiveAttributes(geometry, primitive, parser)
  32612. })
  32613. }
  32614. const pending = []
  32615. for (let i = 0, il = primitives.length; i < il; i++) {
  32616. const primitive = primitives[i]
  32617. const cacheKey = createPrimitiveKey(primitive) // See if we've already created this geometry
  32618. const cached = cache[cacheKey]
  32619. if (cached) {
  32620. // Use the cached geometry if it exists
  32621. pending.push(cached.promise)
  32622. } else {
  32623. let geometryPromise
  32624. if (primitive.extensions && primitive.extensions[EXTENSIONS.KHR_DRACO_MESH_COMPRESSION]) {
  32625. // Use DRACO geometry if available
  32626. geometryPromise = createDracoPrimitive(primitive)
  32627. } else {
  32628. // Otherwise create a new geometry
  32629. geometryPromise = addPrimitiveAttributes(new THREE.BufferGeometry(), primitive, parser)
  32630. } // Cache this geometry
  32631. cache[cacheKey] = {
  32632. primitive: primitive,
  32633. promise: geometryPromise,
  32634. }
  32635. pending.push(geometryPromise)
  32636. }
  32637. }
  32638. return Promise.all(pending)
  32639. }
  32640. /**
  32641. * Specification: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#meshes
  32642. * @param {number} meshIndex
  32643. * @return {Promise<Group|Mesh|SkinnedMesh>}
  32644. */
  32645. loadMesh(meshIndex) {
  32646. const parser = this
  32647. const json = this.json
  32648. const extensions = this.extensions
  32649. const meshDef = json.meshes[meshIndex]
  32650. const primitives = meshDef.primitives
  32651. const pending = []
  32652. for (let i = 0, il = primitives.length; i < il; i++) {
  32653. const material = primitives[i].material === undefined ? createDefaultMaterial(this.cache) : this.getDependency('material', primitives[i].material)
  32654. pending.push(material)
  32655. }
  32656. pending.push(parser.loadGeometries(primitives))
  32657. return Promise.all(pending).then(function (results) {
  32658. const materials = results.slice(0, results.length - 1)
  32659. const geometries = results[results.length - 1]
  32660. const meshes = []
  32661. for (let i = 0, il = geometries.length; i < il; i++) {
  32662. const geometry = geometries[i]
  32663. const primitive = primitives[i] // 1. create THREE.Mesh
  32664. let mesh
  32665. const material = materials[i]
  32666. if (
  32667. primitive.mode === WEBGL_CONSTANTS.TRIANGLES ||
  32668. primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP ||
  32669. primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN ||
  32670. primitive.mode === undefined
  32671. ) {
  32672. // .isSkinnedMesh isn't in glTF spec. See ._markDefs()
  32673. mesh = meshDef.isSkinnedMesh === true ? new THREE.SkinnedMesh(geometry, material) : new THREE.Mesh(geometry, material)
  32674. if (mesh.isSkinnedMesh === true && !mesh.geometry.attributes.skinWeight.normalized) {
  32675. // we normalize floating point skin weight array to fix malformed assets (see #15319)
  32676. // it's important to skip this for non-float32 data since normalizeSkinWeights assumes non-normalized inputs
  32677. mesh.normalizeSkinWeights()
  32678. }
  32679. if (primitive.mode === WEBGL_CONSTANTS.TRIANGLE_STRIP) {
  32680. mesh.geometry = toTrianglesDrawMode(mesh.geometry, THREE.TriangleStripDrawMode)
  32681. } else if (primitive.mode === WEBGL_CONSTANTS.TRIANGLE_FAN) {
  32682. mesh.geometry = toTrianglesDrawMode(mesh.geometry, THREE.TriangleFanDrawMode)
  32683. }
  32684. } else if (primitive.mode === WEBGL_CONSTANTS.LINES) {
  32685. mesh = new THREE.LineSegments(geometry, material)
  32686. } else if (primitive.mode === WEBGL_CONSTANTS.LINE_STRIP) {
  32687. mesh = new THREE.Line(geometry, material)
  32688. } else if (primitive.mode === WEBGL_CONSTANTS.LINE_LOOP) {
  32689. mesh = new THREE.LineLoop(geometry, material)
  32690. } else if (primitive.mode === WEBGL_CONSTANTS.POINTS) {
  32691. mesh = new THREE.Points(geometry, material)
  32692. } else {
  32693. throw new Error('THREE.GLTFLoader: Primitive mode unsupported: ' + primitive.mode)
  32694. }
  32695. if (Object.keys(mesh.geometry.morphAttributes).length > 0) {
  32696. updateMorphTargets(mesh, meshDef)
  32697. }
  32698. mesh.name = parser.createUniqueName(meshDef.name || 'mesh_' + meshIndex)
  32699. assignExtrasToUserData(mesh, meshDef)
  32700. if (primitive.extensions) addUnknownExtensionsToUserData(extensions, mesh, primitive)
  32701. parser.assignFinalMaterial(mesh)
  32702. meshes.push(mesh)
  32703. }
  32704. for (let i = 0, il = meshes.length; i < il; i++) {
  32705. parser.associations.set(meshes[i], {
  32706. meshes: meshIndex,
  32707. primitives: i,
  32708. })
  32709. }
  32710. if (meshes.length === 1) {
  32711. return meshes[0]
  32712. }
  32713. const group = new THREE.Group()
  32714. parser.associations.set(group, {
  32715. meshes: meshIndex,
  32716. })
  32717. for (let i = 0, il = meshes.length; i < il; i++) {
  32718. group.add(meshes[i])
  32719. }
  32720. return group
  32721. })
  32722. }
  32723. /**
  32724. * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#cameras
  32725. * @param {number} cameraIndex
  32726. * @return {Promise<THREE.Camera>}
  32727. */
  32728. loadCamera(cameraIndex) {
  32729. let camera
  32730. const cameraDef = this.json.cameras[cameraIndex]
  32731. const params = cameraDef[cameraDef.type]
  32732. if (!params) {
  32733. console.warn('THREE.GLTFLoader: Missing camera parameters.')
  32734. return
  32735. }
  32736. if (cameraDef.type === 'perspective') {
  32737. camera = new THREE.PerspectiveCamera(THREE.MathUtils.radToDeg(params.yfov), params.aspectRatio || 1, params.znear || 1, params.zfar || 2e6)
  32738. } else if (cameraDef.type === 'orthographic') {
  32739. camera = new THREE.OrthographicCamera(-params.xmag, params.xmag, params.ymag, -params.ymag, params.znear, params.zfar)
  32740. }
  32741. if (cameraDef.name) camera.name = this.createUniqueName(cameraDef.name)
  32742. assignExtrasToUserData(camera, cameraDef)
  32743. return Promise.resolve(camera)
  32744. }
  32745. /**
  32746. * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#skins
  32747. * @param {number} skinIndex
  32748. * @return {Promise<Object>}
  32749. */
  32750. loadSkin(skinIndex) {
  32751. const skinDef = this.json.skins[skinIndex]
  32752. const skinEntry = {
  32753. joints: skinDef.joints,
  32754. }
  32755. if (skinDef.inverseBindMatrices === undefined) {
  32756. return Promise.resolve(skinEntry)
  32757. }
  32758. return this.getDependency('accessor', skinDef.inverseBindMatrices).then(function (accessor) {
  32759. skinEntry.inverseBindMatrices = accessor
  32760. return skinEntry
  32761. })
  32762. }
  32763. /**
  32764. * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations
  32765. * @param {number} animationIndex
  32766. * @return {Promise<AnimationClip>}
  32767. */
  32768. loadAnimation(animationIndex) {
  32769. const json = this.json
  32770. const animationDef = json.animations[animationIndex]
  32771. const pendingNodes = []
  32772. const pendingInputAccessors = []
  32773. const pendingOutputAccessors = []
  32774. const pendingSamplers = []
  32775. const pendingTargets = []
  32776. for (let i = 0, il = animationDef.channels.length; i < il; i++) {
  32777. const channel = animationDef.channels[i]
  32778. const sampler = animationDef.samplers[channel.sampler]
  32779. const target = channel.target
  32780. const name = target.node
  32781. const input = animationDef.parameters !== undefined ? animationDef.parameters[sampler.input] : sampler.input
  32782. const output = animationDef.parameters !== undefined ? animationDef.parameters[sampler.output] : sampler.output
  32783. pendingNodes.push(this.getDependency('node', name))
  32784. pendingInputAccessors.push(this.getDependency('accessor', input))
  32785. pendingOutputAccessors.push(this.getDependency('accessor', output))
  32786. pendingSamplers.push(sampler)
  32787. pendingTargets.push(target)
  32788. }
  32789. return Promise.all([Promise.all(pendingNodes), Promise.all(pendingInputAccessors), Promise.all(pendingOutputAccessors), Promise.all(pendingSamplers), Promise.all(pendingTargets)]).then(
  32790. function (dependencies) {
  32791. const nodes = dependencies[0]
  32792. const inputAccessors = dependencies[1]
  32793. const outputAccessors = dependencies[2]
  32794. const samplers = dependencies[3]
  32795. const targets = dependencies[4]
  32796. const tracks = []
  32797. for (let i = 0, il = nodes.length; i < il; i++) {
  32798. const node = nodes[i]
  32799. const inputAccessor = inputAccessors[i]
  32800. const outputAccessor = outputAccessors[i]
  32801. const sampler = samplers[i]
  32802. const target = targets[i]
  32803. if (node === undefined) continue
  32804. node.updateMatrix()
  32805. let TypedKeyframeTrack
  32806. switch (PATH_PROPERTIES[target.path]) {
  32807. case PATH_PROPERTIES.weights:
  32808. TypedKeyframeTrack = THREE.NumberKeyframeTrack
  32809. break
  32810. case PATH_PROPERTIES.rotation:
  32811. TypedKeyframeTrack = THREE.QuaternionKeyframeTrack
  32812. break
  32813. case PATH_PROPERTIES.position:
  32814. case PATH_PROPERTIES.scale:
  32815. default:
  32816. TypedKeyframeTrack = THREE.VectorKeyframeTrack
  32817. break
  32818. }
  32819. const targetName = node.name ? node.name : node.uuid
  32820. const interpolation = sampler.interpolation !== undefined ? INTERPOLATION[sampler.interpolation] : THREE.InterpolateLinear
  32821. const targetNames = []
  32822. if (PATH_PROPERTIES[target.path] === PATH_PROPERTIES.weights) {
  32823. node.traverse(function (object) {
  32824. if (object.morphTargetInfluences) {
  32825. targetNames.push(object.name ? object.name : object.uuid)
  32826. }
  32827. })
  32828. } else {
  32829. targetNames.push(targetName)
  32830. }
  32831. let outputArray = outputAccessor.array
  32832. if (outputAccessor.normalized) {
  32833. const scale = getNormalizedComponentScale(outputArray.constructor)
  32834. const scaled = new Float32Array(outputArray.length)
  32835. for (let j = 0, jl = outputArray.length; j < jl; j++) {
  32836. scaled[j] = outputArray[j] * scale
  32837. }
  32838. outputArray = scaled
  32839. }
  32840. for (let j = 0, jl = targetNames.length; j < jl; j++) {
  32841. const track = new TypedKeyframeTrack(targetNames[j] + '.' + PATH_PROPERTIES[target.path], inputAccessor.array, outputArray, interpolation) // Override interpolation with custom factory method.
  32842. if (sampler.interpolation === 'CUBICSPLINE') {
  32843. track.createInterpolant = function InterpolantFactoryMethodGLTFCubicSpline(result) {
  32844. // A CUBICSPLINE keyframe in glTF has three output values for each input value,
  32845. // representing inTangent, splineVertex, and outTangent. As a result, track.getValueSize()
  32846. // must be divided by three to get the interpolant's sampleSize argument.
  32847. const interpolantType = this instanceof THREE.QuaternionKeyframeTrack ? GLTFCubicSplineQuaternionInterpolant : GLTFCubicSplineInterpolant
  32848. return new interpolantType(this.times, this.values, this.getValueSize() / 3, result)
  32849. } // Mark as CUBICSPLINE. `track.getInterpolation()` doesn't support custom interpolants.
  32850. track.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline = true
  32851. }
  32852. tracks.push(track)
  32853. }
  32854. }
  32855. const name = animationDef.name ? animationDef.name : 'animation_' + animationIndex
  32856. return new THREE.AnimationClip(name, undefined, tracks)
  32857. }
  32858. )
  32859. }
  32860. createNodeMesh(nodeIndex) {
  32861. const json = this.json
  32862. const parser = this
  32863. const nodeDef = json.nodes[nodeIndex]
  32864. if (nodeDef.mesh === undefined) return null
  32865. return parser.getDependency('mesh', nodeDef.mesh).then(function (mesh) {
  32866. const node = parser._getNodeRef(parser.meshCache, nodeDef.mesh, mesh) // if weights are provided on the node, override weights on the mesh.
  32867. if (nodeDef.weights !== undefined) {
  32868. node.traverse(function (o) {
  32869. if (!o.isMesh) return
  32870. for (let i = 0, il = nodeDef.weights.length; i < il; i++) {
  32871. o.morphTargetInfluences[i] = nodeDef.weights[i]
  32872. }
  32873. })
  32874. }
  32875. return node
  32876. })
  32877. }
  32878. /**
  32879. * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#nodes-and-hierarchy
  32880. * @param {number} nodeIndex
  32881. * @return {Promise<Object3D>}
  32882. */
  32883. loadNode(nodeIndex) {
  32884. const json = this.json
  32885. const extensions = this.extensions
  32886. const parser = this
  32887. const nodeDef = json.nodes[nodeIndex] // reserve node's name before its dependencies, so the root has the intended name.
  32888. const nodeName = nodeDef.name ? parser.createUniqueName(nodeDef.name) : ''
  32889. return (function () {
  32890. const pending = []
  32891. const meshPromise = parser._invokeOne(function (ext) {
  32892. return ext.createNodeMesh && ext.createNodeMesh(nodeIndex)
  32893. })
  32894. if (meshPromise) {
  32895. pending.push(meshPromise)
  32896. }
  32897. if (nodeDef.camera !== undefined) {
  32898. pending.push(
  32899. parser.getDependency('camera', nodeDef.camera).then(function (camera) {
  32900. return parser._getNodeRef(parser.cameraCache, nodeDef.camera, camera)
  32901. })
  32902. )
  32903. }
  32904. parser
  32905. ._invokeAll(function (ext) {
  32906. return ext.createNodeAttachment && ext.createNodeAttachment(nodeIndex)
  32907. })
  32908. .forEach(function (promise) {
  32909. pending.push(promise)
  32910. })
  32911. return Promise.all(pending)
  32912. })().then(function (objects) {
  32913. let node // .isBone isn't in glTF spec. See ._markDefs
  32914. if (nodeDef.isBone === true) {
  32915. node = new THREE.Bone()
  32916. } else if (objects.length > 1) {
  32917. node = new THREE.Group()
  32918. } else if (objects.length === 1) {
  32919. node = objects[0]
  32920. } else {
  32921. node = new THREE.Object3D()
  32922. }
  32923. if (node !== objects[0]) {
  32924. for (let i = 0, il = objects.length; i < il; i++) {
  32925. node.add(objects[i])
  32926. }
  32927. }
  32928. if (nodeDef.name) {
  32929. node.userData.name = nodeDef.name
  32930. node.name = nodeName
  32931. }
  32932. assignExtrasToUserData(node, nodeDef)
  32933. if (nodeDef.extensions) addUnknownExtensionsToUserData(extensions, node, nodeDef)
  32934. if (nodeDef.matrix !== undefined) {
  32935. const matrix = new THREE.Matrix4()
  32936. matrix.fromArray(nodeDef.matrix)
  32937. node.applyMatrix4(matrix)
  32938. } else {
  32939. if (nodeDef.translation !== undefined) {
  32940. node.position.fromArray(nodeDef.translation)
  32941. }
  32942. if (nodeDef.rotation !== undefined) {
  32943. node.quaternion.fromArray(nodeDef.rotation)
  32944. }
  32945. if (nodeDef.scale !== undefined) {
  32946. node.scale.fromArray(nodeDef.scale)
  32947. }
  32948. }
  32949. if (!parser.associations.has(node)) {
  32950. parser.associations.set(node, {})
  32951. }
  32952. parser.associations.get(node).nodes = nodeIndex
  32953. return node
  32954. })
  32955. }
  32956. /**
  32957. * Specification: https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#scenes
  32958. * @param {number} sceneIndex
  32959. * @return {Promise<Group>}
  32960. */
  32961. loadScene(sceneIndex) {
  32962. const json = this.json
  32963. const extensions = this.extensions
  32964. const sceneDef = this.json.scenes[sceneIndex]
  32965. const parser = this // THREE.Loader returns THREE.Group, not Scene.
  32966. // See: https://github.com/mrdoob/three.js/issues/18342#issuecomment-578981172
  32967. const scene = new THREE.Group()
  32968. if (sceneDef.name) scene.name = parser.createUniqueName(sceneDef.name)
  32969. assignExtrasToUserData(scene, sceneDef)
  32970. if (sceneDef.extensions) addUnknownExtensionsToUserData(extensions, scene, sceneDef)
  32971. const nodeIds = sceneDef.nodes || []
  32972. const pending = []
  32973. for (let i = 0, il = nodeIds.length; i < il; i++) {
  32974. pending.push(buildNodeHierarchy(nodeIds[i], scene, json, parser))
  32975. }
  32976. return Promise.all(pending).then(function () {
  32977. // Removes dangling associations, associations that reference a node that
  32978. // didn't make it into the scene.
  32979. const reduceAssociations = node => {
  32980. const reducedAssociations = new Map()
  32981. for (const [key, value] of parser.associations) {
  32982. if (key instanceof THREE.Material || key instanceof THREE.Texture) {
  32983. reducedAssociations.set(key, value)
  32984. }
  32985. }
  32986. node.traverse(node => {
  32987. const mappings = parser.associations.get(node)
  32988. if (mappings != null) {
  32989. reducedAssociations.set(node, mappings)
  32990. }
  32991. })
  32992. return reducedAssociations
  32993. }
  32994. parser.associations = reduceAssociations(scene)
  32995. return scene
  32996. })
  32997. }
  32998. }
  32999. function buildNodeHierarchy(nodeId, parentObject, json, parser) {
  33000. const nodeDef = json.nodes[nodeId]
  33001. return parser
  33002. .getDependency('node', nodeId)
  33003. .then(function (node) {
  33004. if (nodeDef.skin === undefined) return node // build skeleton here as well
  33005. let skinEntry
  33006. return parser
  33007. .getDependency('skin', nodeDef.skin)
  33008. .then(function (skin) {
  33009. skinEntry = skin
  33010. const pendingJoints = []
  33011. for (let i = 0, il = skinEntry.joints.length; i < il; i++) {
  33012. pendingJoints.push(parser.getDependency('node', skinEntry.joints[i]))
  33013. }
  33014. return Promise.all(pendingJoints)
  33015. })
  33016. .then(function (jointNodes) {
  33017. node.traverse(function (mesh) {
  33018. if (!mesh.isMesh) return
  33019. const bones = []
  33020. const boneInverses = []
  33021. for (let j = 0, jl = jointNodes.length; j < jl; j++) {
  33022. const jointNode = jointNodes[j]
  33023. if (jointNode) {
  33024. bones.push(jointNode)
  33025. const mat = new THREE.Matrix4()
  33026. if (skinEntry.inverseBindMatrices !== undefined) {
  33027. mat.fromArray(skinEntry.inverseBindMatrices.array, j * 16)
  33028. }
  33029. boneInverses.push(mat)
  33030. } else {
  33031. console.warn('THREE.GLTFLoader: Joint "%s" could not be found.', skinEntry.joints[j])
  33032. }
  33033. }
  33034. mesh.bind(new THREE.Skeleton(bones, boneInverses), mesh.matrixWorld)
  33035. })
  33036. return node
  33037. })
  33038. })
  33039. .then(function (node) {
  33040. // build node hierachy
  33041. parentObject.add(node)
  33042. const pending = []
  33043. if (nodeDef.children) {
  33044. const children = nodeDef.children
  33045. for (let i = 0, il = children.length; i < il; i++) {
  33046. const child = children[i]
  33047. pending.push(buildNodeHierarchy(child, node, json, parser))
  33048. }
  33049. }
  33050. return Promise.all(pending)
  33051. })
  33052. }
  33053. /**
  33054. * @param {BufferGeometry} geometry
  33055. * @param {GLTF.Primitive} primitiveDef
  33056. * @param {GLTFParser} parser
  33057. */
  33058. function computeBounds(geometry, primitiveDef, parser) {
  33059. const attributes = primitiveDef.attributes
  33060. const box = new THREE.Box3()
  33061. if (attributes.POSITION !== undefined) {
  33062. const accessor = parser.json.accessors[attributes.POSITION]
  33063. const min = accessor.min
  33064. const max = accessor.max // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
  33065. if (min !== undefined && max !== undefined) {
  33066. box.set(new THREE.Vector3(min[0], min[1], min[2]), new THREE.Vector3(max[0], max[1], max[2]))
  33067. if (accessor.normalized) {
  33068. const boxScale = getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType])
  33069. box.min.multiplyScalar(boxScale)
  33070. box.max.multiplyScalar(boxScale)
  33071. }
  33072. } else {
  33073. console.warn('THREE.GLTFLoader: Missing min/max properties for accessor POSITION.')
  33074. return
  33075. }
  33076. } else {
  33077. return
  33078. }
  33079. const targets = primitiveDef.targets
  33080. if (targets !== undefined) {
  33081. const maxDisplacement = new THREE.Vector3()
  33082. const vector = new THREE.Vector3()
  33083. for (let i = 0, il = targets.length; i < il; i++) {
  33084. const target = targets[i]
  33085. if (target.POSITION !== undefined) {
  33086. const accessor = parser.json.accessors[target.POSITION]
  33087. const min = accessor.min
  33088. const max = accessor.max // glTF requires 'min' and 'max', but VRM (which extends glTF) currently ignores that requirement.
  33089. if (min !== undefined && max !== undefined) {
  33090. // we need to get max of absolute components because target weight is [-1,1]
  33091. vector.setX(Math.max(Math.abs(min[0]), Math.abs(max[0])))
  33092. vector.setY(Math.max(Math.abs(min[1]), Math.abs(max[1])))
  33093. vector.setZ(Math.max(Math.abs(min[2]), Math.abs(max[2])))
  33094. if (accessor.normalized) {
  33095. const boxScale = getNormalizedComponentScale(WEBGL_COMPONENT_TYPES[accessor.componentType])
  33096. vector.multiplyScalar(boxScale)
  33097. } // Note: this assumes that the sum of all weights is at most 1. This isn't quite correct - it's more conservative
  33098. // to assume that each target can have a max weight of 1. However, for some use cases - notably, when morph targets
  33099. // are used to implement key-frame animations and as such only two are active at a time - this results in very large
  33100. // boxes. So for now we make a box that's sometimes a touch too small but is hopefully mostly of reasonable size.
  33101. maxDisplacement.max(vector)
  33102. } else {
  33103. console.warn('THREE.GLTFLoader: Missing min/max properties for accessor POSITION.')
  33104. }
  33105. }
  33106. } // As per comment above this box isn't conservative, but has a reasonable size for a very large number of morph targets.
  33107. box.expandByVector(maxDisplacement)
  33108. }
  33109. geometry.boundingBox = box
  33110. const sphere = new THREE.Sphere()
  33111. box.getCenter(sphere.center)
  33112. sphere.radius = box.min.distanceTo(box.max) / 2
  33113. geometry.boundingSphere = sphere
  33114. }
  33115. /**
  33116. * @param {BufferGeometry} geometry
  33117. * @param {GLTF.Primitive} primitiveDef
  33118. * @param {GLTFParser} parser
  33119. * @return {Promise<BufferGeometry>}
  33120. */
  33121. function addPrimitiveAttributes(geometry, primitiveDef, parser) {
  33122. const attributes = primitiveDef.attributes
  33123. const pending = []
  33124. function assignAttributeAccessor(accessorIndex, attributeName) {
  33125. return parser.getDependency('accessor', accessorIndex).then(function (accessor) {
  33126. geometry.setAttribute(attributeName, accessor)
  33127. })
  33128. }
  33129. for (const gltfAttributeName in attributes) {
  33130. const threeAttributeName = ATTRIBUTES[gltfAttributeName] || gltfAttributeName.toLowerCase() // Skip attributes already provided by e.g. Draco extension.
  33131. if (threeAttributeName in geometry.attributes) continue
  33132. pending.push(assignAttributeAccessor(attributes[gltfAttributeName], threeAttributeName))
  33133. }
  33134. if (primitiveDef.indices !== undefined && !geometry.index) {
  33135. const accessor = parser.getDependency('accessor', primitiveDef.indices).then(function (accessor) {
  33136. geometry.setIndex(accessor)
  33137. })
  33138. pending.push(accessor)
  33139. }
  33140. assignExtrasToUserData(geometry, primitiveDef)
  33141. computeBounds(geometry, primitiveDef, parser)
  33142. return Promise.all(pending).then(function () {
  33143. return primitiveDef.targets !== undefined ? addMorphTargets(geometry, primitiveDef.targets, parser) : geometry
  33144. })
  33145. }
  33146. /**
  33147. * @param {BufferGeometry} geometry
  33148. * @param {Number} drawMode
  33149. * @return {BufferGeometry}
  33150. */
  33151. function toTrianglesDrawMode(geometry, drawMode) {
  33152. let index = geometry.getIndex() // generate index if not present
  33153. if (index === null) {
  33154. const indices = []
  33155. const position = geometry.getAttribute('position')
  33156. if (position !== undefined) {
  33157. for (let i = 0; i < position.count; i++) {
  33158. indices.push(i)
  33159. }
  33160. geometry.setIndex(indices)
  33161. index = geometry.getIndex()
  33162. } else {
  33163. console.error('THREE.GLTFLoader.toTrianglesDrawMode(): Undefined position attribute. Processing not possible.')
  33164. return geometry
  33165. }
  33166. } //
  33167. const numberOfTriangles = index.count - 2
  33168. const newIndices = []
  33169. if (drawMode === THREE.TriangleFanDrawMode) {
  33170. // gl.TRIANGLE_FAN
  33171. for (let i = 1; i <= numberOfTriangles; i++) {
  33172. newIndices.push(index.getX(0))
  33173. newIndices.push(index.getX(i))
  33174. newIndices.push(index.getX(i + 1))
  33175. }
  33176. } else {
  33177. // gl.TRIANGLE_STRIP
  33178. for (let i = 0; i < numberOfTriangles; i++) {
  33179. if (i % 2 === 0) {
  33180. newIndices.push(index.getX(i))
  33181. newIndices.push(index.getX(i + 1))
  33182. newIndices.push(index.getX(i + 2))
  33183. } else {
  33184. newIndices.push(index.getX(i + 2))
  33185. newIndices.push(index.getX(i + 1))
  33186. newIndices.push(index.getX(i))
  33187. }
  33188. }
  33189. }
  33190. if (newIndices.length / 3 !== numberOfTriangles) {
  33191. console.error('THREE.GLTFLoader.toTrianglesDrawMode(): Unable to generate correct amount of triangles.')
  33192. } // build final geometry
  33193. const newGeometry = geometry.clone()
  33194. newGeometry.setIndex(newIndices)
  33195. return newGeometry
  33196. }
  33197. THREE.GLTFLoader = GLTFLoader
  33198. })()
  33199. ;
  33200. /*! howler.js v2.2.3 | (c) 2013-2020, James Simpson of GoldFire Studios | MIT License | howlerjs.com */
  33201. !function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._html5AudioPool=[],e.html5PoolSize=10,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.autoUnlock=!0,e._setup(),e},volume:function(e){var o=this||n;if(e=parseFloat(e),o.ctx||_(),void 0!==e&&e>=0&&e<=1){if(o._volume=e,o._muted)return o;o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var t=0;t<o._howls.length;t++)if(!o._howls[t]._webAudio)for(var r=o._howls[t]._getSoundIds(),a=0;a<r.length;a++){var u=o._howls[t]._soundById(r[a]);u&&u._node&&(u._node.volume=u._volume*e)}return o}return o._volume},mute:function(e){var o=this||n;o.ctx||_(),o._muted=e,o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e?0:o._volume,n.ctx.currentTime);for(var t=0;t<o._howls.length;t++)if(!o._howls[t]._webAudio)for(var r=o._howls[t]._getSoundIds(),a=0;a<r.length;a++){var u=o._howls[t]._soundById(r[a]);u&&u._node&&(u._node.muted=!!e||u._muted)}return o},stop:function(){for(var e=this||n,o=0;o<e._howls.length;o++)e._howls[o].stop();return e},unload:function(){for(var e=this||n,o=e._howls.length-1;o>=0;o--)e._howls[o].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"suspended":"suspended",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var o=new Audio;void 0===o.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var o=new Audio;o.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,o=null;try{o="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!o||"function"!=typeof o.canPlayType)return e;var t=o.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator?e._navigator.userAgent:"",a=r.match(/OPR\/([0-6].)/g),u=a&&parseInt(a[0].split("/")[1],10)<33,d=-1!==r.indexOf("Safari")&&-1===r.indexOf("Chrome"),i=r.match(/Version\/(.*?) /),_=d&&i&&parseInt(i[1],10)<15;return e._codecs={mp3:!(u||!t&&!o.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!t,opus:!!o.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!(o.canPlayType('audio/wav; codecs="1"')||o.canPlayType("audio/wav")).replace(/^no$/,""),aac:!!o.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!o.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(o.canPlayType("audio/x-m4a;")||o.canPlayType("audio/m4a;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),m4b:!!(o.canPlayType("audio/x-m4b;")||o.canPlayType("audio/m4b;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(o.canPlayType("audio/x-mp4;")||o.canPlayType("audio/mp4;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!(_||!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),webm:!(_||!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")),dolby:!!o.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(o.canPlayType("audio/x-flac;")||o.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_unlockAudio:function(){var e=this||n;if(!e._audioUnlocked&&e.ctx){e._audioUnlocked=!1,e.autoUnlock=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var o=function(n){for(;e._html5AudioPool.length<e.html5PoolSize;)try{var t=new Audio;t._unlocked=!0,e._releaseHtml5Audio(t)}catch(n){e.noAudio=!0;break}for(var r=0;r<e._howls.length;r++)if(!e._howls[r]._webAudio)for(var a=e._howls[r]._getSoundIds(),u=0;u<a.length;u++){var d=e._howls[r]._soundById(a[u]);d&&d._node&&!d._node._unlocked&&(d._node._unlocked=!0,d._node.load())}e._autoResume();var i=e.ctx.createBufferSource();i.buffer=e._scratchBuffer,i.connect(e.ctx.destination),void 0===i.start?i.noteOn(0):i.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),i.onended=function(){i.disconnect(0),e._audioUnlocked=!0,document.removeEventListener("touchstart",o,!0),document.removeEventListener("touchend",o,!0),document.removeEventListener("click",o,!0),document.removeEventListener("keydown",o,!0);for(var n=0;n<e._howls.length;n++)e._howls[n]._emit("unlock")}};return document.addEventListener("touchstart",o,!0),document.addEventListener("touchend",o,!0),document.addEventListener("click",o,!0),document.addEventListener("keydown",o,!0),e}},_obtainHtml5Audio:function(){var e=this||n;if(e._html5AudioPool.length)return e._html5AudioPool.pop();var o=(new Audio).play();return o&&"undefined"!=typeof Promise&&(o instanceof Promise||"function"==typeof o.then)&&o.catch(function(){console.warn("HTML5 Audio pool exhausted, returning potentially locked audio object.")}),new Audio},_releaseHtml5Audio:function(e){var o=this||n;return e._unlocked&&o._html5AudioPool.push(e),o},_autoSuspend:function(){var e=this;if(e.autoSuspend&&e.ctx&&void 0!==e.ctx.suspend&&n.usingWebAudio){for(var o=0;o<e._howls.length;o++)if(e._howls[o]._webAudio)for(var t=0;t<e._howls[o]._sounds.length;t++)if(!e._howls[o]._sounds[t]._paused)return e;return e._suspendTimer&&clearTimeout(e._suspendTimer),e._suspendTimer=setTimeout(function(){if(e.autoSuspend){e._suspendTimer=null,e.state="suspending";var n=function(){e.state="suspended",e._resumeAfterSuspend&&(delete e._resumeAfterSuspend,e._autoResume())};e.ctx.suspend().then(n,n)}},3e4),e}},_autoResume:function(){var e=this;if(e.ctx&&void 0!==e.ctx.resume&&n.usingWebAudio)return"running"===e.state&&"interrupted"!==e.ctx.state&&e._suspendTimer?(clearTimeout(e._suspendTimer),e._suspendTimer=null):"suspended"===e.state||"running"===e.state&&"interrupted"===e.ctx.state?(e.ctx.resume().then(function(){e.state="running";for(var n=0;n<e._howls.length;n++)e._howls[n]._emit("resume")}),e._suspendTimer&&(clearTimeout(e._suspendTimer),e._suspendTimer=null)):"suspending"===e.state&&(e._resumeAfterSuspend=!0),e}};var n=new e,o=function(e){var n=this;if(!e.src||0===e.src.length)return void console.error("An array of source files must be passed with any new Howl.");n.init(e)};o.prototype={init:function(e){var o=this;return n.ctx||_(),o._autoplay=e.autoplay||!1,o._format="string"!=typeof e.format?e.format:[e.format],o._html5=e.html5||!1,o._muted=e.mute||!1,o._loop=e.loop||!1,o._pool=e.pool||5,o._preload="boolean"!=typeof e.preload&&"metadata"!==e.preload||e.preload,o._rate=e.rate||1,o._sprite=e.sprite||{},o._src="string"!=typeof e.src?e.src:[e.src],o._volume=void 0!==e.volume?e.volume:1,o._xhr={method:e.xhr&&e.xhr.method?e.xhr.method:"GET",headers:e.xhr&&e.xhr.headers?e.xhr.headers:null,withCredentials:!(!e.xhr||!e.xhr.withCredentials)&&e.xhr.withCredentials},o._duration=0,o._state="unloaded",o._sounds=[],o._endTimers={},o._queue=[],o._playLock=!1,o._onend=e.onend?[{fn:e.onend}]:[],o._onfade=e.onfade?[{fn:e.onfade}]:[],o._onload=e.onload?[{fn:e.onload}]:[],o._onloaderror=e.onloaderror?[{fn:e.onloaderror}]:[],o._onplayerror=e.onplayerror?[{fn:e.onplayerror}]:[],o._onpause=e.onpause?[{fn:e.onpause}]:[],o._onplay=e.onplay?[{fn:e.onplay}]:[],o._onstop=e.onstop?[{fn:e.onstop}]:[],o._onmute=e.onmute?[{fn:e.onmute}]:[],o._onvolume=e.onvolume?[{fn:e.onvolume}]:[],o._onrate=e.onrate?[{fn:e.onrate}]:[],o._onseek=e.onseek?[{fn:e.onseek}]:[],o._onunlock=e.onunlock?[{fn:e.onunlock}]:[],o._onresume=[],o._webAudio=n.usingWebAudio&&!o._html5,void 0!==n.ctx&&n.ctx&&n.autoUnlock&&n._unlockAudio(),n._howls.push(o),o._autoplay&&o._queue.push({event:"play",action:function(){o.play()}}),o._preload&&"none"!==o._preload&&o.load(),o},load:function(){var e=this,o=null;if(n.noAudio)return void e._emit("loaderror",null,"No audio support.");"string"==typeof e._src&&(e._src=[e._src]);for(var r=0;r<e._src.length;r++){var u,d;if(e._format&&e._format[r])u=e._format[r];else{if("string"!=typeof(d=e._src[r])){e._emit("loaderror",null,"Non-string found in selected audio sources - ignoring.");continue}u=/^data:audio\/([^;,]+);/i.exec(d),u||(u=/\.([^.]+)$/.exec(d.split("?",1)[0])),u&&(u=u[1].toLowerCase())}if(u||console.warn('No file extension was found. Consider using the "format" property or specify an extension.'),u&&n.codecs(u)){o=e._src[r];break}}return o?(e._src=o,e._state="loading","https:"===window.location.protocol&&"http:"===o.slice(0,5)&&(e._html5=!0,e._webAudio=!1),new t(e),e._webAudio&&a(e),e):void e._emit("loaderror",null,"No codec support for selected audio sources.")},play:function(e,o){var t=this,r=null;if("number"==typeof e)r=e,e=null;else{if("string"==typeof e&&"loaded"===t._state&&!t._sprite[e])return null;if(void 0===e&&(e="__default",!t._playLock)){for(var a=0,u=0;u<t._sounds.length;u++)t._sounds[u]._paused&&!t._sounds[u]._ended&&(a++,r=t._sounds[u]._id);1===a?e=null:r=null}}var d=r?t._soundById(r):t._inactiveSound();if(!d)return null;if(r&&!e&&(e=d._sprite||"__default"),"loaded"!==t._state){d._sprite=e,d._ended=!1;var i=d._id;return t._queue.push({event:"play",action:function(){t.play(i)}}),i}if(r&&!d._paused)return o||t._loadQueue("play"),d._id;t._webAudio&&n._autoResume();var _=Math.max(0,d._seek>0?d._seek:t._sprite[e][0]/1e3),s=Math.max(0,(t._sprite[e][0]+t._sprite[e][1])/1e3-_),l=1e3*s/Math.abs(d._rate),c=t._sprite[e][0]/1e3,f=(t._sprite[e][0]+t._sprite[e][1])/1e3;d._sprite=e,d._ended=!1;var p=function(){d._paused=!1,d._seek=_,d._start=c,d._stop=f,d._loop=!(!d._loop&&!t._sprite[e][2])};if(_>=f)return void t._ended(d);var m=d._node;if(t._webAudio){var v=function(){t._playLock=!1,p(),t._refreshBuffer(d);var e=d._muted||t._muted?0:d._volume;m.gain.setValueAtTime(e,n.ctx.currentTime),d._playStart=n.ctx.currentTime,void 0===m.bufferSource.start?d._loop?m.bufferSource.noteGrainOn(0,_,86400):m.bufferSource.noteGrainOn(0,_,s):d._loop?m.bufferSource.start(0,_,86400):m.bufferSource.start(0,_,s),l!==1/0&&(t._endTimers[d._id]=setTimeout(t._ended.bind(t,d),l)),o||setTimeout(function(){t._emit("play",d._id),t._loadQueue()},0)};"running"===n.state&&"interrupted"!==n.ctx.state?v():(t._playLock=!0,t.once("resume",v),t._clearTimer(d._id))}else{var h=function(){m.currentTime=_,m.muted=d._muted||t._muted||n._muted||m.muted,m.volume=d._volume*n.volume(),m.playbackRate=d._rate;try{var r=m.play();if(r&&"undefined"!=typeof Promise&&(r instanceof Promise||"function"==typeof r.then)?(t._playLock=!0,p(),r.then(function(){t._playLock=!1,m._unlocked=!0,o?t._loadQueue():t._emit("play",d._id)}).catch(function(){t._playLock=!1,t._emit("playerror",d._id,"Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction."),d._ended=!0,d._paused=!0})):o||(t._playLock=!1,p(),t._emit("play",d._id)),m.playbackRate=d._rate,m.paused)return void t._emit("playerror",d._id,"Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.");"__default"!==e||d._loop?t._endTimers[d._id]=setTimeout(t._ended.bind(t,d),l):(t._endTimers[d._id]=function(){t._ended(d),m.removeEventListener("ended",t._endTimers[d._id],!1)},m.addEventListener("ended",t._endTimers[d._id],!1))}catch(e){t._emit("playerror",d._id,e)}};"data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA"===m.src&&(m.src=t._src,m.load());var y=window&&window.ejecta||!m.readyState&&n._navigator.isCocoonJS;if(m.readyState>=3||y)h();else{t._playLock=!0,t._state="loading";var g=function(){t._state="loaded",h(),m.removeEventListener(n._canPlayEvent,g,!1)};m.addEventListener(n._canPlayEvent,g,!1),t._clearTimer(d._id)}}return d._id},pause:function(e){var n=this;if("loaded"!==n._state||n._playLock)return n._queue.push({event:"pause",action:function(){n.pause(e)}}),n;for(var o=n._getSoundIds(e),t=0;t<o.length;t++){n._clearTimer(o[t]);var r=n._soundById(o[t]);if(r&&!r._paused&&(r._seek=n.seek(o[t]),r._rateSeek=0,r._paused=!0,n._stopFade(o[t]),r._node))if(n._webAudio){if(!r._node.bufferSource)continue;void 0===r._node.bufferSource.stop?r._node.bufferSource.noteOff(0):r._node.bufferSource.stop(0),n._cleanBuffer(r._node)}else isNaN(r._node.duration)&&r._node.duration!==1/0||r._node.pause();arguments[1]||n._emit("pause",r?r._id:null)}return n},stop:function(e,n){var o=this;if("loaded"!==o._state||o._playLock)return o._queue.push({event:"stop",action:function(){o.stop(e)}}),o;for(var t=o._getSoundIds(e),r=0;r<t.length;r++){o._clearTimer(t[r]);var a=o._soundById(t[r]);a&&(a._seek=a._start||0,a._rateSeek=0,a._paused=!0,a._ended=!0,o._stopFade(t[r]),a._node&&(o._webAudio?a._node.bufferSource&&(void 0===a._node.bufferSource.stop?a._node.bufferSource.noteOff(0):a._node.bufferSource.stop(0),o._cleanBuffer(a._node)):isNaN(a._node.duration)&&a._node.duration!==1/0||(a._node.currentTime=a._start||0,a._node.pause(),a._node.duration===1/0&&o._clearSound(a._node))),n||o._emit("stop",a._id))}return o},mute:function(e,o){var t=this;if("loaded"!==t._state||t._playLock)return t._queue.push({event:"mute",action:function(){t.mute(e,o)}}),t;if(void 0===o){if("boolean"!=typeof e)return t._muted;t._muted=e}for(var r=t._getSoundIds(o),a=0;a<r.length;a++){var u=t._soundById(r[a]);u&&(u._muted=e,u._interval&&t._stopFade(u._id),t._webAudio&&u._node?u._node.gain.setValueAtTime(e?0:u._volume,n.ctx.currentTime):u._node&&(u._node.muted=!!n._muted||e),t._emit("mute",u._id))}return t},volume:function(){var e,o,t=this,r=arguments;if(0===r.length)return t._volume;if(1===r.length||2===r.length&&void 0===r[1]){t._getSoundIds().indexOf(r[0])>=0?o=parseInt(r[0],10):e=parseFloat(r[0])}else r.length>=2&&(e=parseFloat(r[0]),o=parseInt(r[1],10));var a;if(!(void 0!==e&&e>=0&&e<=1))return a=o?t._soundById(o):t._sounds[0],a?a._volume:0;if("loaded"!==t._state||t._playLock)return t._queue.push({event:"volume",action:function(){t.volume.apply(t,r)}}),t;void 0===o&&(t._volume=e),o=t._getSoundIds(o);for(var u=0;u<o.length;u++)(a=t._soundById(o[u]))&&(a._volume=e,r[2]||t._stopFade(o[u]),t._webAudio&&a._node&&!a._muted?a._node.gain.setValueAtTime(e,n.ctx.currentTime):a._node&&!a._muted&&(a._node.volume=e*n.volume()),t._emit("volume",a._id));return t},fade:function(e,o,t,r){var a=this;if("loaded"!==a._state||a._playLock)return a._queue.push({event:"fade",action:function(){a.fade(e,o,t,r)}}),a;e=Math.min(Math.max(0,parseFloat(e)),1),o=Math.min(Math.max(0,parseFloat(o)),1),t=parseFloat(t),a.volume(e,r);for(var u=a._getSoundIds(r),d=0;d<u.length;d++){var i=a._soundById(u[d]);if(i){if(r||a._stopFade(u[d]),a._webAudio&&!i._muted){var _=n.ctx.currentTime,s=_+t/1e3;i._volume=e,i._node.gain.setValueAtTime(e,_),i._node.gain.linearRampToValueAtTime(o,s)}a._startFadeInterval(i,e,o,t,u[d],void 0===r)}}return a},_startFadeInterval:function(e,n,o,t,r,a){var u=this,d=n,i=o-n,_=Math.abs(i/.01),s=Math.max(4,_>0?t/_:t),l=Date.now();e._fadeTo=o,e._interval=setInterval(function(){var r=(Date.now()-l)/t;l=Date.now(),d+=i*r,d=Math.round(100*d)/100,d=i<0?Math.max(o,d):Math.min(o,d),u._webAudio?e._volume=d:u.volume(d,e._id,!0),a&&(u._volume=d),(o<n&&d<=o||o>n&&d>=o)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,u.volume(o,e._id),u._emit("fade",e._id))},s)},_stopFade:function(e){var o=this,t=o._soundById(e);return t&&t._interval&&(o._webAudio&&t._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(t._interval),t._interval=null,o.volume(t._fadeTo,e),t._fadeTo=null,o._emit("fade",e)),o},loop:function(){var e,n,o,t=this,r=arguments;if(0===r.length)return t._loop;if(1===r.length){if("boolean"!=typeof r[0])return!!(o=t._soundById(parseInt(r[0],10)))&&o._loop;e=r[0],t._loop=e}else 2===r.length&&(e=r[0],n=parseInt(r[1],10));for(var a=t._getSoundIds(n),u=0;u<a.length;u++)(o=t._soundById(a[u]))&&(o._loop=e,t._webAudio&&o._node&&o._node.bufferSource&&(o._node.bufferSource.loop=e,e&&(o._node.bufferSource.loopStart=o._start||0,o._node.bufferSource.loopEnd=o._stop,t.playing(a[u])&&(t.pause(a[u],!0),t.play(a[u],!0)))));return t},rate:function(){var e,o,t=this,r=arguments;if(0===r.length)o=t._sounds[0]._id;else if(1===r.length){var a=t._getSoundIds(),u=a.indexOf(r[0]);u>=0?o=parseInt(r[0],10):e=parseFloat(r[0])}else 2===r.length&&(e=parseFloat(r[0]),o=parseInt(r[1],10));var d;if("number"!=typeof e)return d=t._soundById(o),d?d._rate:t._rate;if("loaded"!==t._state||t._playLock)return t._queue.push({event:"rate",action:function(){t.rate.apply(t,r)}}),t;void 0===o&&(t._rate=e),o=t._getSoundIds(o);for(var i=0;i<o.length;i++)if(d=t._soundById(o[i])){t.playing(o[i])&&(d._rateSeek=t.seek(o[i]),d._playStart=t._webAudio?n.ctx.currentTime:d._playStart),d._rate=e,t._webAudio&&d._node&&d._node.bufferSource?d._node.bufferSource.playbackRate.setValueAtTime(e,n.ctx.currentTime):d._node&&(d._node.playbackRate=e);var _=t.seek(o[i]),s=(t._sprite[d._sprite][0]+t._sprite[d._sprite][1])/1e3-_,l=1e3*s/Math.abs(d._rate);!t._endTimers[o[i]]&&d._paused||(t._clearTimer(o[i]),t._endTimers[o[i]]=setTimeout(t._ended.bind(t,d),l)),t._emit("rate",d._id)}return t},seek:function(){var e,o,t=this,r=arguments;if(0===r.length)t._sounds.length&&(o=t._sounds[0]._id);else if(1===r.length){var a=t._getSoundIds(),u=a.indexOf(r[0]);u>=0?o=parseInt(r[0],10):t._sounds.length&&(o=t._sounds[0]._id,e=parseFloat(r[0]))}else 2===r.length&&(e=parseFloat(r[0]),o=parseInt(r[1],10));if(void 0===o)return 0;if("number"==typeof e&&("loaded"!==t._state||t._playLock))return t._queue.push({event:"seek",action:function(){t.seek.apply(t,r)}}),t;var d=t._soundById(o);if(d){if(!("number"==typeof e&&e>=0)){if(t._webAudio){var i=t.playing(o)?n.ctx.currentTime-d._playStart:0,_=d._rateSeek?d._rateSeek-d._seek:0;return d._seek+(_+i*Math.abs(d._rate))}return d._node.currentTime}var s=t.playing(o);s&&t.pause(o,!0),d._seek=e,d._ended=!1,t._clearTimer(o),t._webAudio||!d._node||isNaN(d._node.duration)||(d._node.currentTime=e);var l=function(){s&&t.play(o,!0),t._emit("seek",o)};if(s&&!t._webAudio){var c=function(){t._playLock?setTimeout(c,0):l()};setTimeout(c,0)}else l()}return t},playing:function(e){var n=this;if("number"==typeof e){var o=n._soundById(e);return!!o&&!o._paused}for(var t=0;t<n._sounds.length;t++)if(!n._sounds[t]._paused)return!0;return!1},duration:function(e){var n=this,o=n._duration,t=n._soundById(e);return t&&(o=n._sprite[t._sprite][1]/1e3),o},state:function(){return this._state},unload:function(){for(var e=this,o=e._sounds,t=0;t<o.length;t++)o[t]._paused||e.stop(o[t]._id),e._webAudio||(e._clearSound(o[t]._node),o[t]._node.removeEventListener("error",o[t]._errorFn,!1),o[t]._node.removeEventListener(n._canPlayEvent,o[t]._loadFn,!1),o[t]._node.removeEventListener("ended",o[t]._endFn,!1),n._releaseHtml5Audio(o[t]._node)),delete o[t]._node,e._clearTimer(o[t]._id);var a=n._howls.indexOf(e);a>=0&&n._howls.splice(a,1);var u=!0;for(t=0;t<n._howls.length;t++)if(n._howls[t]._src===e._src||e._src.indexOf(n._howls[t]._src)>=0){u=!1;break}return r&&u&&delete r[e._src],n.noAudio=!1,e._state="unloaded",e._sounds=[],e=null,null},on:function(e,n,o,t){var r=this,a=r["_on"+e];return"function"==typeof n&&a.push(t?{id:o,fn:n,once:t}:{id:o,fn:n}),r},off:function(e,n,o){var t=this,r=t["_on"+e],a=0;if("number"==typeof n&&(o=n,n=null),n||o)for(a=0;a<r.length;a++){var u=o===r[a].id;if(n===r[a].fn&&u||!n&&u){r.splice(a,1);break}}else if(e)t["_on"+e]=[];else{var d=Object.keys(t);for(a=0;a<d.length;a++)0===d[a].indexOf("_on")&&Array.isArray(t[d[a]])&&(t[d[a]]=[])}return t},once:function(e,n,o){var t=this;return t.on(e,n,o,1),t},_emit:function(e,n,o){for(var t=this,r=t["_on"+e],a=r.length-1;a>=0;a--)r[a].id&&r[a].id!==n&&"load"!==e||(setTimeout(function(e){e.call(this,n,o)}.bind(t,r[a].fn),0),r[a].once&&t.off(e,r[a].fn,r[a].id));return t._loadQueue(e),t},_loadQueue:function(e){var n=this;if(n._queue.length>0){var o=n._queue[0];o.event===e&&(n._queue.shift(),n._loadQueue()),e||o.action()}return n},_ended:function(e){var o=this,t=e._sprite;if(!o._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime<e._stop)return setTimeout(o._ended.bind(o,e),100),o;var r=!(!e._loop&&!o._sprite[t][2]);if(o._emit("end",e._id),!o._webAudio&&r&&o.stop(e._id,!0).play(e._id),o._webAudio&&r){o._emit("play",e._id),e._seek=e._start||0,e._rateSeek=0,e._playStart=n.ctx.currentTime;var a=1e3*(e._stop-e._start)/Math.abs(e._rate);o._endTimers[e._id]=setTimeout(o._ended.bind(o,e),a)}return o._webAudio&&!r&&(e._paused=!0,e._ended=!0,e._seek=e._start||0,e._rateSeek=0,o._clearTimer(e._id),o._cleanBuffer(e._node),n._autoSuspend()),o._webAudio||r||o.stop(e._id,!0),o},_clearTimer:function(e){var n=this;if(n._endTimers[e]){if("function"!=typeof n._endTimers[e])clearTimeout(n._endTimers[e]);else{var o=n._soundById(e);o&&o._node&&o._node.removeEventListener("ended",n._endTimers[e],!1)}delete n._endTimers[e]}return n},_soundById:function(e){for(var n=this,o=0;o<n._sounds.length;o++)if(e===n._sounds[o]._id)return n._sounds[o];return null},_inactiveSound:function(){var e=this;e._drain();for(var n=0;n<e._sounds.length;n++)if(e._sounds[n]._ended)return e._sounds[n].reset();return new t(e)},_drain:function(){var e=this,n=e._pool,o=0,t=0;if(!(e._sounds.length<n)){for(t=0;t<e._sounds.length;t++)e._sounds[t]._ended&&o++;for(t=e._sounds.length-1;t>=0;t--){if(o<=n)return;e._sounds[t]._ended&&(e._webAudio&&e._sounds[t]._node&&e._sounds[t]._node.disconnect(0),e._sounds.splice(t,1),o--)}}},_getSoundIds:function(e){var n=this;if(void 0===e){for(var o=[],t=0;t<n._sounds.length;t++)o.push(n._sounds[t]._id);return o}return[e]},_refreshBuffer:function(e){var o=this;return e._node.bufferSource=n.ctx.createBufferSource(),e._node.bufferSource.buffer=r[o._src],e._panner?e._node.bufferSource.connect(e._panner):e._node.bufferSource.connect(e._node),e._node.bufferSource.loop=e._loop,e._loop&&(e._node.bufferSource.loopStart=e._start||0,e._node.bufferSource.loopEnd=e._stop||0),e._node.bufferSource.playbackRate.setValueAtTime(e._rate,n.ctx.currentTime),o},_cleanBuffer:function(e){var o=this,t=n._navigator&&n._navigator.vendor.indexOf("Apple")>=0;if(n._scratchBuffer&&e.bufferSource&&(e.bufferSource.onended=null,e.bufferSource.disconnect(0),t))try{e.bufferSource.buffer=n._scratchBuffer}catch(e){}return e.bufferSource=null,o},_clearSound:function(e){/MSIE |Trident\//.test(n._navigator&&n._navigator.userAgent)||(e.src="data:audio/wav;base64,UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA")}};var t=function(e){this._parent=e,this.init()};t.prototype={init:function(){var e=this,o=e._parent;return e._muted=o._muted,e._loop=o._loop,e._volume=o._volume,e._rate=o._rate,e._seek=0,e._paused=!0,e._ended=!0,e._sprite="__default",e._id=++n._counter,o._sounds.push(e),e.create(),e},create:function(){var e=this,o=e._parent,t=n._muted||e._muted||e._parent._muted?0:e._volume;return o._webAudio?(e._node=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),e._node.gain.setValueAtTime(t,n.ctx.currentTime),e._node.paused=!0,e._node.connect(n.masterGain)):n.noAudio||(e._node=n._obtainHtml5Audio(),e._errorFn=e._errorListener.bind(e),e._node.addEventListener("error",e._errorFn,!1),e._loadFn=e._loadListener.bind(e),e._node.addEventListener(n._canPlayEvent,e._loadFn,!1),e._endFn=e._endListener.bind(e),e._node.addEventListener("ended",e._endFn,!1),e._node.src=o._src,e._node.preload=!0===o._preload?"auto":o._preload,e._node.volume=t*n.volume(),e._node.load()),e},reset:function(){var e=this,o=e._parent;return e._muted=o._muted,e._loop=o._loop,e._volume=o._volume,e._rate=o._rate,e._seek=0,e._rateSeek=0,e._paused=!0,e._ended=!0,e._sprite="__default",e._id=++n._counter,e},_errorListener:function(){var e=this;e._parent._emit("loaderror",e._id,e._node.error?e._node.error.code:0),e._node.removeEventListener("error",e._errorFn,!1)},_loadListener:function(){var e=this,o=e._parent;o._duration=Math.ceil(10*e._node.duration)/10,0===Object.keys(o._sprite).length&&(o._sprite={__default:[0,1e3*o._duration]}),"loaded"!==o._state&&(o._state="loaded",o._emit("load"),o._loadQueue()),e._node.removeEventListener(n._canPlayEvent,e._loadFn,!1)},_endListener:function(){var e=this,n=e._parent;n._duration===1/0&&(n._duration=Math.ceil(10*e._node.duration)/10,n._sprite.__default[1]===1/0&&(n._sprite.__default[1]=1e3*n._duration),n._ended(e)),e._node.removeEventListener("ended",e._endFn,!1)}};var r={},a=function(e){var n=e._src;if(r[n])return e._duration=r[n].duration,void i(e);if(/^data:[^;]+;base64,/.test(n)){for(var o=atob(n.split(",")[1]),t=new Uint8Array(o.length),a=0;a<o.length;++a)t[a]=o.charCodeAt(a);d(t.buffer,e)}else{var _=new XMLHttpRequest;_.open(e._xhr.method,n,!0),_.withCredentials=e._xhr.withCredentials,_.responseType="arraybuffer",e._xhr.headers&&Object.keys(e._xhr.headers).forEach(function(n){_.setRequestHeader(n,e._xhr.headers[n])}),_.onload=function(){var n=(_.status+"")[0];if("0"!==n&&"2"!==n&&"3"!==n)return void e._emit("loaderror",null,"Failed loading audio file with status: "+_.status+".");d(_.response,e)},_.onerror=function(){e._webAudio&&(e._html5=!0,e._webAudio=!1,e._sounds=[],delete r[n],e.load())},u(_)}},u=function(e){try{e.send()}catch(n){e.onerror()}},d=function(e,o){var t=function(){o._emit("loaderror",null,"Decoding audio data failed.")},a=function(e){e&&o._sounds.length>0?(r[o._src]=e,i(o,e)):t()};"undefined"!=typeof Promise&&1===n.ctx.decodeAudioData.length?n.ctx.decodeAudioData(e).then(a).catch(t):n.ctx.decodeAudioData(e,a,t)},i=function(e,n){n&&!e._duration&&(e._duration=n.duration),0===Object.keys(e._sprite).length&&(e._sprite={__default:[0,1e3*e._duration]}),"loaded"!==e._state&&(e._state="loaded",e._emit("load"),e._loadQueue())},_=function(){if(n.usingWebAudio){try{"undefined"!=typeof AudioContext?n.ctx=new AudioContext:"undefined"!=typeof webkitAudioContext?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch(e){n.usingWebAudio=!1}n.ctx||(n.usingWebAudio=!1);var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),o=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),t=o?parseInt(o[1],10):null;if(e&&t&&t<9){var r=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());n._navigator&&!r&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:n._volume,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()}};"function"==typeof define&&define.amd&&define([],function(){return{Howler:n,Howl:o}}),"undefined"!=typeof exports&&(exports.Howler=n,exports.Howl=o),"undefined"!=typeof global?(global.HowlerGlobal=e,global.Howler=n,global.Howl=o,global.Sound=t):"undefined"!=typeof window&&(window.HowlerGlobal=e,window.Howler=n,window.Howl=o,window.Sound=t)}();
  33202. /*! Spatial Plugin */
  33203. !function(){"use strict";HowlerGlobal.prototype._pos=[0,0,0],HowlerGlobal.prototype._orientation=[0,0,-1,0,1,0],HowlerGlobal.prototype.stereo=function(e){var n=this;if(!n.ctx||!n.ctx.listener)return n;for(var t=n._howls.length-1;t>=0;t--)n._howls[t].stereo(e);return n},HowlerGlobal.prototype.pos=function(e,n,t){var r=this;return r.ctx&&r.ctx.listener?(n="number"!=typeof n?r._pos[1]:n,t="number"!=typeof t?r._pos[2]:t,"number"!=typeof e?r._pos:(r._pos=[e,n,t],void 0!==r.ctx.listener.positionX?(r.ctx.listener.positionX.setTargetAtTime(r._pos[0],Howler.ctx.currentTime,.1),r.ctx.listener.positionY.setTargetAtTime(r._pos[1],Howler.ctx.currentTime,.1),r.ctx.listener.positionZ.setTargetAtTime(r._pos[2],Howler.ctx.currentTime,.1)):r.ctx.listener.setPosition(r._pos[0],r._pos[1],r._pos[2]),r)):r},HowlerGlobal.prototype.orientation=function(e,n,t,r,o,i){var a=this;if(!a.ctx||!a.ctx.listener)return a;var s=a._orientation;return n="number"!=typeof n?s[1]:n,t="number"!=typeof t?s[2]:t,r="number"!=typeof r?s[3]:r,o="number"!=typeof o?s[4]:o,i="number"!=typeof i?s[5]:i,"number"!=typeof e?s:(a._orientation=[e,n,t,r,o,i],void 0!==a.ctx.listener.forwardX?(a.ctx.listener.forwardX.setTargetAtTime(e,Howler.ctx.currentTime,.1),a.ctx.listener.forwardY.setTargetAtTime(n,Howler.ctx.currentTime,.1),a.ctx.listener.forwardZ.setTargetAtTime(t,Howler.ctx.currentTime,.1),a.ctx.listener.upX.setTargetAtTime(r,Howler.ctx.currentTime,.1),a.ctx.listener.upY.setTargetAtTime(o,Howler.ctx.currentTime,.1),a.ctx.listener.upZ.setTargetAtTime(i,Howler.ctx.currentTime,.1)):a.ctx.listener.setOrientation(e,n,t,r,o,i),a)},Howl.prototype.init=function(e){return function(n){var t=this;return t._orientation=n.orientation||[1,0,0],t._stereo=n.stereo||null,t._pos=n.pos||null,t._pannerAttr={coneInnerAngle:void 0!==n.coneInnerAngle?n.coneInnerAngle:360,coneOuterAngle:void 0!==n.coneOuterAngle?n.coneOuterAngle:360,coneOuterGain:void 0!==n.coneOuterGain?n.coneOuterGain:0,distanceModel:void 0!==n.distanceModel?n.distanceModel:"inverse",maxDistance:void 0!==n.maxDistance?n.maxDistance:1e4,panningModel:void 0!==n.panningModel?n.panningModel:"HRTF",refDistance:void 0!==n.refDistance?n.refDistance:1,rolloffFactor:void 0!==n.rolloffFactor?n.rolloffFactor:1},t._onstereo=n.onstereo?[{fn:n.onstereo}]:[],t._onpos=n.onpos?[{fn:n.onpos}]:[],t._onorientation=n.onorientation?[{fn:n.onorientation}]:[],e.call(this,n)}}(Howl.prototype.init),Howl.prototype.stereo=function(n,t){var r=this;if(!r._webAudio)return r;if("loaded"!==r._state)return r._queue.push({event:"stereo",action:function(){r.stereo(n,t)}}),r;var o=void 0===Howler.ctx.createStereoPanner?"spatial":"stereo";if(void 0===t){if("number"!=typeof n)return r._stereo;r._stereo=n,r._pos=[n,0,0]}for(var i=r._getSoundIds(t),a=0;a<i.length;a++){var s=r._soundById(i[a]);if(s){if("number"!=typeof n)return s._stereo;s._stereo=n,s._pos=[n,0,0],s._node&&(s._pannerAttr.panningModel="equalpower",s._panner&&s._panner.pan||e(s,o),"spatial"===o?void 0!==s._panner.positionX?(s._panner.positionX.setValueAtTime(n,Howler.ctx.currentTime),s._panner.positionY.setValueAtTime(0,Howler.ctx.currentTime),s._panner.positionZ.setValueAtTime(0,Howler.ctx.currentTime)):s._panner.setPosition(n,0,0):s._panner.pan.setValueAtTime(n,Howler.ctx.currentTime)),r._emit("stereo",s._id)}}return r},Howl.prototype.pos=function(n,t,r,o){var i=this;if(!i._webAudio)return i;if("loaded"!==i._state)return i._queue.push({event:"pos",action:function(){i.pos(n,t,r,o)}}),i;if(t="number"!=typeof t?0:t,r="number"!=typeof r?-.5:r,void 0===o){if("number"!=typeof n)return i._pos;i._pos=[n,t,r]}for(var a=i._getSoundIds(o),s=0;s<a.length;s++){var p=i._soundById(a[s]);if(p){if("number"!=typeof n)return p._pos;p._pos=[n,t,r],p._node&&(p._panner&&!p._panner.pan||e(p,"spatial"),void 0!==p._panner.positionX?(p._panner.positionX.setValueAtTime(n,Howler.ctx.currentTime),p._panner.positionY.setValueAtTime(t,Howler.ctx.currentTime),p._panner.positionZ.setValueAtTime(r,Howler.ctx.currentTime)):p._panner.setPosition(n,t,r)),i._emit("pos",p._id)}}return i},Howl.prototype.orientation=function(n,t,r,o){var i=this;if(!i._webAudio)return i;if("loaded"!==i._state)return i._queue.push({event:"orientation",action:function(){i.orientation(n,t,r,o)}}),i;if(t="number"!=typeof t?i._orientation[1]:t,r="number"!=typeof r?i._orientation[2]:r,void 0===o){if("number"!=typeof n)return i._orientation;i._orientation=[n,t,r]}for(var a=i._getSoundIds(o),s=0;s<a.length;s++){var p=i._soundById(a[s]);if(p){if("number"!=typeof n)return p._orientation;p._orientation=[n,t,r],p._node&&(p._panner||(p._pos||(p._pos=i._pos||[0,0,-.5]),e(p,"spatial")),void 0!==p._panner.orientationX?(p._panner.orientationX.setValueAtTime(n,Howler.ctx.currentTime),p._panner.orientationY.setValueAtTime(t,Howler.ctx.currentTime),p._panner.orientationZ.setValueAtTime(r,Howler.ctx.currentTime)):p._panner.setOrientation(n,t,r)),i._emit("orientation",p._id)}}return i},Howl.prototype.pannerAttr=function(){var n,t,r,o=this,i=arguments;if(!o._webAudio)return o;if(0===i.length)return o._pannerAttr;if(1===i.length){if("object"!=typeof i[0])return r=o._soundById(parseInt(i[0],10)),r?r._pannerAttr:o._pannerAttr;n=i[0],void 0===t&&(n.pannerAttr||(n.pannerAttr={coneInnerAngle:n.coneInnerAngle,coneOuterAngle:n.coneOuterAngle,coneOuterGain:n.coneOuterGain,distanceModel:n.distanceModel,maxDistance:n.maxDistance,refDistance:n.refDistance,rolloffFactor:n.rolloffFactor,panningModel:n.panningModel}),o._pannerAttr={coneInnerAngle:void 0!==n.pannerAttr.coneInnerAngle?n.pannerAttr.coneInnerAngle:o._coneInnerAngle,coneOuterAngle:void 0!==n.pannerAttr.coneOuterAngle?n.pannerAttr.coneOuterAngle:o._coneOuterAngle,coneOuterGain:void 0!==n.pannerAttr.coneOuterGain?n.pannerAttr.coneOuterGain:o._coneOuterGain,distanceModel:void 0!==n.pannerAttr.distanceModel?n.pannerAttr.distanceModel:o._distanceModel,maxDistance:void 0!==n.pannerAttr.maxDistance?n.pannerAttr.maxDistance:o._maxDistance,refDistance:void 0!==n.pannerAttr.refDistance?n.pannerAttr.refDistance:o._refDistance,rolloffFactor:void 0!==n.pannerAttr.rolloffFactor?n.pannerAttr.rolloffFactor:o._rolloffFactor,panningModel:void 0!==n.pannerAttr.panningModel?n.pannerAttr.panningModel:o._panningModel})}else 2===i.length&&(n=i[0],t=parseInt(i[1],10));for(var a=o._getSoundIds(t),s=0;s<a.length;s++)if(r=o._soundById(a[s])){var p=r._pannerAttr;p={coneInnerAngle:void 0!==n.coneInnerAngle?n.coneInnerAngle:p.coneInnerAngle,coneOuterAngle:void 0!==n.coneOuterAngle?n.coneOuterAngle:p.coneOuterAngle,coneOuterGain:void 0!==n.coneOuterGain?n.coneOuterGain:p.coneOuterGain,distanceModel:void 0!==n.distanceModel?n.distanceModel:p.distanceModel,maxDistance:void 0!==n.maxDistance?n.maxDistance:p.maxDistance,refDistance:void 0!==n.refDistance?n.refDistance:p.refDistance,rolloffFactor:void 0!==n.rolloffFactor?n.rolloffFactor:p.rolloffFactor,panningModel:void 0!==n.panningModel?n.panningModel:p.panningModel};var c=r._panner;c?(c.coneInnerAngle=p.coneInnerAngle,c.coneOuterAngle=p.coneOuterAngle,c.coneOuterGain=p.coneOuterGain,c.distanceModel=p.distanceModel,c.maxDistance=p.maxDistance,c.refDistance=p.refDistance,c.rolloffFactor=p.rolloffFactor,c.panningModel=p.panningModel):(r._pos||(r._pos=o._pos||[0,0,-.5]),e(r,"spatial"))}return o},Sound.prototype.init=function(e){return function(){var n=this,t=n._parent;n._orientation=t._orientation,n._stereo=t._stereo,n._pos=t._pos,n._pannerAttr=t._pannerAttr,e.call(this),n._stereo?t.stereo(n._stereo):n._pos&&t.pos(n._pos[0],n._pos[1],n._pos[2],n._id)}}(Sound.prototype.init),Sound.prototype.reset=function(e){return function(){var n=this,t=n._parent;return n._orientation=t._orientation,n._stereo=t._stereo,n._pos=t._pos,n._pannerAttr=t._pannerAttr,n._stereo?t.stereo(n._stereo):n._pos?t.pos(n._pos[0],n._pos[1],n._pos[2],n._id):n._panner&&(n._panner.disconnect(0),n._panner=void 0,t._refreshBuffer(n)),e.call(this)}}(Sound.prototype.reset);var e=function(e,n){n=n||"spatial","spatial"===n?(e._panner=Howler.ctx.createPanner(),e._panner.coneInnerAngle=e._pannerAttr.coneInnerAngle,e._panner.coneOuterAngle=e._pannerAttr.coneOuterAngle,e._panner.coneOuterGain=e._pannerAttr.coneOuterGain,e._panner.distanceModel=e._pannerAttr.distanceModel,e._panner.maxDistance=e._pannerAttr.maxDistance,e._panner.refDistance=e._pannerAttr.refDistance,e._panner.rolloffFactor=e._pannerAttr.rolloffFactor,e._panner.panningModel=e._pannerAttr.panningModel,void 0!==e._panner.positionX?(e._panner.positionX.setValueAtTime(e._pos[0],Howler.ctx.currentTime),e._panner.positionY.setValueAtTime(e._pos[1],Howler.ctx.currentTime),e._panner.positionZ.setValueAtTime(e._pos[2],Howler.ctx.currentTime)):e._panner.setPosition(e._pos[0],e._pos[1],e._pos[2]),void 0!==e._panner.orientationX?(e._panner.orientationX.setValueAtTime(e._orientation[0],Howler.ctx.currentTime),e._panner.orientationY.setValueAtTime(e._orientation[1],Howler.ctx.currentTime),e._panner.orientationZ.setValueAtTime(e._orientation[2],Howler.ctx.currentTime)):e._panner.setOrientation(e._orientation[0],e._orientation[1],e._orientation[2])):(e._panner=Howler.ctx.createStereoPanner(),e._panner.pan.setValueAtTime(e._stereo,Howler.ctx.currentTime)),e._panner.connect(e._node),e._paused||e._parent.pause(e._id,!0).play(e._id,!0)}}();;
  33204. var pn=Object.defineProperty,hn=(e,t,n)=>t in e?pn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,C=(e,t,n)=>(hn(e,"symbol"!=typeof t?t+"":t,n),n),PetiteVue=function(e){"use strict";function t(e){if(a(e)){const n={};for(let s=0;s<e.length;s++){const i=e[s],o=d(i)?r(i):t(i);if(o)for(const e in o)n[e]=o[e]}return n}return d(e)||g(e)?e:void 0}const n=/;(?![^(]*\))/g,s=/:(.+)/;function r(e){const t={};return e.split(n).forEach((e=>{if(e){const n=e.split(s);n.length>1&&(t[n[0].trim()]=n[1].trim())}})),t}function i(e){let t="";if(d(e))t=e;else if(a(e))for(let n=0;n<e.length;n++){const s=i(e[n]);s&&(t+=s+" ")}else if(g(e))for(const n in e)e[n]&&(t+=n+" ");return t.trim()}function o(e,t){if(e===t)return!0;let n=h(e),s=h(t);if(n||s)return!(!n||!s)&&e.getTime()===t.getTime();if(n=a(e),s=a(t),n||s)return!(!n||!s)&&function(e,t){if(e.length!==t.length)return!1;let n=!0;for(let s=0;n&&s<e.length;s++)n=o(e[s],t[s]);return n}(e,t);if(n=g(e),s=g(t),n||s){if(!n||!s)return!1;if(Object.keys(e).length!==Object.keys(t).length)return!1;for(const n in e){const s=e.hasOwnProperty(n),r=t.hasOwnProperty(n);if(s&&!r||!s&&r||!o(e[n],t[n]))return!1}}return String(e)===String(t)}function c(e,t){return e.findIndex((e=>o(e,t)))}const l=Object.assign,f=Object.prototype.hasOwnProperty,u=(e,t)=>f.call(e,t),a=Array.isArray,p=e=>"[object Map]"===y(e),h=e=>e instanceof Date,d=e=>"string"==typeof e,m=e=>"symbol"==typeof e,g=e=>null!==e&&"object"==typeof e,v=Object.prototype.toString,y=e=>v.call(e),b=e=>d(e)&&"NaN"!==e&&"-"!==e[0]&&""+parseInt(e,10)===e,x=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},_=/-(\w)/g,w=x((e=>e.replace(_,((e,t)=>t?t.toUpperCase():"")))),$=/\B([A-Z])/g,k=x((e=>e.replace($,"-$1").toLowerCase())),O=e=>{const t=parseFloat(e);return isNaN(t)?e:t};function S(e,t){(t=t||undefined)&&t.active&&t.effects.push(e)}const E=e=>{const t=new Set(e);return t.w=0,t.n=0,t},j=e=>(e.w&N)>0,A=e=>(e.n&N)>0,P=new WeakMap;let R=0,N=1;const T=[];let M;const B=Symbol(""),L=Symbol("");class W{constructor(e,t=null,n){this.fn=e,this.scheduler=t,this.active=!0,this.deps=[],S(this,n)}run(){if(!this.active)return this.fn();if(!T.includes(this))try{return T.push(M=this),F.push(V),V=!0,N=1<<++R,R<=30?(({deps:e})=>{if(e.length)for(let t=0;t<e.length;t++)e[t].w|=N})(this):I(this),this.fn()}finally{R<=30&&(e=>{const{deps:t}=e;if(t.length){let n=0;for(let s=0;s<t.length;s++){const r=t[s];j(r)&&!A(r)?r.delete(e):t[n++]=r,r.w&=~N,r.n&=~N}t.length=n}})(this),N=1<<--R,z(),T.pop();const e=T.length;M=e>0?T[e-1]:void 0}}stop(){this.active&&(I(this),this.onStop&&this.onStop(),this.active=!1)}}function I(e){const{deps:t}=e;if(t.length){for(let n=0;n<t.length;n++)t[n].delete(e);t.length=0}}function K(e){e.effect.stop()}let V=!0;const F=[];function z(){const e=F.pop();V=void 0===e||e}function H(e,t,n){if(!V||void 0===M)return;let s=P.get(e);s||P.set(e,s=new Map);let r=s.get(n);r||s.set(n,r=E()),function(e,t){let n=!1;R<=30?A(e)||(e.n|=N,n=!j(e)):n=!e.has(M),n&&(e.add(M),M.deps.push(e))}(r)}function J(e,t,n,s,r,i){const o=P.get(e);if(!o)return;let c=[];if("clear"===t)c=[...o.values()];else if("length"===n&&a(e))o.forEach(((e,t)=>{("length"===t||t>=s)&&c.push(e)}));else switch(void 0!==n&&c.push(o.get(n)),t){case"add":a(e)?b(n)&&c.push(o.get("length")):(c.push(o.get(B)),p(e)&&c.push(o.get(L)));break;case"delete":a(e)||(c.push(o.get(B)),p(e)&&c.push(o.get(L)));break;case"set":p(e)&&c.push(o.get(B))}if(1===c.length)c[0]&&Z(c[0]);else{const e=[];for(const t of c)t&&e.push(...t);Z(E(e))}}function Z(e,t){for(const n of a(e)?e:[...e])(n!==M||n.allowRecurse)&&(n.scheduler?n.scheduler():n.run())}const q=function(e,t){const n=Object.create(null),s=e.split(",");for(let r=0;r<s.length;r++)n[s[r]]=!0;return t?e=>!!n[e.toLowerCase()]:e=>!!n[e]}("__proto__,__v_isRef,__isVue"),D=new Set(Object.getOwnPropertyNames(Symbol).map((e=>Symbol[e])).filter(m)),G=X(),U=X(!0),Q=function(){const e={};return["includes","indexOf","lastIndexOf"].forEach((t=>{e[t]=function(...e){const n=le(this);for(let t=0,r=this.length;t<r;t++)H(n,0,t+"");const s=n[t](...e);return-1===s||!1===s?n[t](...e.map(le)):s}})),["push","pop","shift","unshift","splice"].forEach((t=>{e[t]=function(...e){F.push(V),V=!1;const n=le(this)[t].apply(this,e);return z(),n}})),e}();function X(e=!1,t=!1){return function(n,s,r){if("__v_isReactive"===s)return!e;if("__v_isReadonly"===s)return e;if("__v_raw"===s&&r===(e?t?re:se:t?ne:te).get(n))return n;const i=a(n);if(!e&&i&&u(Q,s))return Reflect.get(Q,s,r);const o=Reflect.get(n,s,r);return(m(s)?D.has(s):q(s))||(e||H(n,0,s),t)?o:fe(o)?i&&b(s)?o:o.value:g(o)?e?function(e){return ce(e,!0,ee,null,se)}(o):oe(o):o}}const Y={get:G,set:function(e=!1){return function(t,n,s,r){let i=t[n];if(!e&&!function(e){return!(!e||!e.__v_isReadonly)}(s)&&(s=le(s),i=le(i),!a(t)&&fe(i)&&!fe(s)))return i.value=s,!0;const o=a(t)&&b(n)?Number(n)<t.length:u(t,n),c=Reflect.set(t,n,s,r);return t===le(r)&&(o?((e,t)=>!Object.is(e,t))(s,i)&&J(t,"set",n,s):J(t,"add",n,s)),c}}(),deleteProperty:function(e,t){const n=u(e,t);e[t];const s=Reflect.deleteProperty(e,t);return s&&n&&J(e,"delete",t,void 0),s},has:function(e,t){const n=Reflect.has(e,t);return(!m(t)||!D.has(t))&&H(e,0,t),n},ownKeys:function(e){return H(e,0,a(e)?"length":B),Reflect.ownKeys(e)}},ee={get:U,set:(e,t)=>!0,deleteProperty:(e,t)=>!0},te=new WeakMap,ne=new WeakMap,se=new WeakMap,re=new WeakMap;function ie(e){return e.__v_skip||!Object.isExtensible(e)?0:function(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}((e=>y(e).slice(8,-1))(e))}function oe(e){return e&&e.__v_isReadonly?e:ce(e,!1,Y,null,te)}function ce(e,t,n,s,r){if(!g(e)||e.__v_raw&&(!t||!e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=ie(e);if(0===o)return e;const c=new Proxy(e,2===o?s:n);return r.set(e,c),c}function le(e){const t=e&&e.__v_raw;return t?le(t):e}function fe(e){return Boolean(e&&!0===e.__v_isRef)}Promise.resolve();let ue=!1;const ae=[],pe=Promise.resolve(),he=e=>pe.then(e),de=e=>{ae.includes(e)||ae.push(e),ue||(ue=!0,he(me))},me=()=>{for(const e of ae)e();ae.length=0,ue=!1},ge=/^(spellcheck|draggable|form|list|type)$/,ve=({el:e,get:t,effect:n,arg:s,modifiers:r})=>{let i;"class"===s&&(e._class=e.className),n((()=>{let n=t();if(s)(null==r?void 0:r.camel)&&(s=w(s)),ye(e,s,n,i);else{for(const t in n)ye(e,t,n[t],i&&i[t]);for(const t in i)(!n||!(t in n))&&ye(e,t,null)}i=n}))},ye=(e,n,s,r)=>{if("class"===n)e.setAttribute("class",i(e._class?[e._class,s]:s)||"");else if("style"===n){s=t(s);const{style:n}=e;if(s)if(d(s))s!==r&&(n.cssText=s);else{for(const e in s)xe(n,e,s[e]);if(r&&!d(r))for(const e in r)null==s[e]&&xe(n,e,"")}else e.removeAttribute("style")}else e instanceof SVGElement||!(n in e)||ge.test(n)?"true-value"===n?e._trueValue=s:"false-value"===n?e._falseValue=s:null!=s?e.setAttribute(n,s):e.removeAttribute(n):(e[n]=s,"value"===n&&(e._value=s))},be=/\s*!important$/,xe=(e,t,n)=>{a(n)?n.forEach((n=>xe(e,t,n))):t.startsWith("--")?e.setProperty(t,n):be.test(n)?e.setProperty(k(t),n.replace(be,""),"important"):e[t]=n},_e=(e,t)=>{const n=e.getAttribute(t);return null!=n&&e.removeAttribute(t),n},we=(e,t,n,s)=>{e.addEventListener(t,n,s)},$e=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,ke=["ctrl","shift","alt","meta"],Oe={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&0!==e.button,middle:e=>"button"in e&&1!==e.button,right:e=>"button"in e&&2!==e.button,exact:(e,t)=>ke.some((n=>e[`${n}Key`]&&!t[n]))},Se=({el:e,get:t,exp:n,arg:s,modifiers:r})=>{if(!s)return;let i=$e.test(n)?t(`(e => ${n}(e))`):t(`($event => { ${n} })`);if("vue:mounted"!==s){if("vue:unmounted"===s)return()=>i();if(r){"click"===s&&(r.right&&(s="contextmenu"),r.middle&&(s="mouseup"));const e=i;i=t=>{if(!("key"in t)||k(t.key)in r){for(const e in r){const n=Oe[e];if(n&&n(t,r))return}return e(t)}}}we(e,s,i,r)}else he(i)},Ee=({el:e,get:t,effect:n})=>{n((()=>{e.textContent=Ce(t())}))},Ce=e=>null==e?"":g(e)?JSON.stringify(e,null,2):String(e),je=e=>"_value"in e?e._value:e.value,Ae=(e,t)=>{const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t},Pe=e=>{e.target.composing=!0},Re=e=>{const t=e.target;t.composing&&(t.composing=!1,Ne(t,"input"))},Ne=(e,t)=>{const n=document.createEvent("HTMLEvents");n.initEvent(t,!0,!0),e.dispatchEvent(n)},Te=Object.create(null),Me=(e,t,n)=>Be(e,`return(${t})`,n),Be=(e,t,n)=>{const s=Te[t]||(Te[t]=Le(t));try{return s(e,n)}catch(r){console.error(r)}},Le=e=>{try{return new Function("$data","$el",`with($data){${e}}`)}catch(t){return console.error(`${t.message} in expression: ${e}`),()=>{}}},We={bind:ve,on:Se,show:({el:e,get:t,effect:n})=>{const s=e.style.display;n((()=>{e.style.display=t()?s:"none"}))},text:Ee,html:({el:e,get:t,effect:n})=>{n((()=>{e.innerHTML=t()}))},model:({el:e,exp:t,get:n,effect:s,modifiers:r})=>{const i=e.type,l=n(`(val) => { ${t} = val }`),{trim:f,number:u="number"===i}=r||{};if("SELECT"===e.tagName){const t=e;we(e,"change",(()=>{const e=Array.prototype.filter.call(t.options,(e=>e.selected)).map((e=>u?O(je(e)):je(e)));l(t.multiple?e:e[0])})),s((()=>{const e=n(),s=t.multiple;for(let n=0,r=t.options.length;n<r;n++){const r=t.options[n],i=je(r);if(s)a(e)?r.selected=c(e,i)>-1:r.selected=e.has(i);else if(o(je(r),e))return void(t.selectedIndex!==n&&(t.selectedIndex=n))}!s&&-1!==t.selectedIndex&&(t.selectedIndex=-1)}))}else if("checkbox"===i){let t;we(e,"change",(()=>{const t=n(),s=e.checked;if(a(t)){const n=je(e),r=c(t,n),i=-1!==r;if(s&&!i)l(t.concat(n));else if(!s&&i){const e=[...t];e.splice(r,1),l(e)}}else l(Ae(e,s))})),s((()=>{const s=n();a(s)?e.checked=c(s,je(e))>-1:s!==t&&(e.checked=o(s,Ae(e,!0))),t=s}))}else if("radio"===i){let t;we(e,"change",(()=>{l(je(e))})),s((()=>{const s=n();s!==t&&(e.checked=o(s,je(e)))}))}else{const t=e=>f?e.trim():u?O(e):e;we(e,"compositionstart",Pe),we(e,"compositionend",Re),we(e,(null==r?void 0:r.lazy)?"change":"input",(()=>{e.composing||l(t(e.value))})),f&&we(e,"change",(()=>{e.value=e.value.trim()})),s((()=>{if(e.composing)return;const s=e.value,r=n();document.activeElement===e&&t(s)===r||s!==r&&(e.value=r)}))}},effect:({el:e,ctx:t,exp:n,effect:s})=>{he((()=>s((()=>Be(t.scope,n,e)))))}},Ie=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,Ke=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Ve=/^\(|\)$/g,Fe=/^[{[]\s*((?:[\w_$]+\s*,?\s*)+)[\]}]$/,ze=(e,t,n)=>{const s=t.match(Ie);if(!s)return;const r=e.nextSibling,i=e.parentElement,o=new Text("");i.insertBefore(o,e),i.removeChild(e);const c=s[2].trim();let l,f,u,p,h=s[1].trim().replace(Ve,"").trim(),d=!1,m="key",v=e.getAttribute(m)||e.getAttribute(m=":key")||e.getAttribute(m="v-bind:key");v&&(e.removeAttribute(m),"key"===m&&(v=JSON.stringify(v))),(p=h.match(Ke))&&(h=h.replace(Ke,"").trim(),f=p[1].trim(),p[2]&&(u=p[2].trim())),(p=h.match(Fe))&&(l=p[1].split(",").map((e=>e.trim())),d="["===h[0]);let y,b,x,_=!1;const w=(e,t,s,r)=>{const i={};l?l.forEach(((e,n)=>i[e]=t[d?n:e])):i[h]=t,r?(f&&(i[f]=r),u&&(i[u]=s)):f&&(i[f]=s);const o=et(n,i),c=v?Me(o.scope,v):s;return e.set(c,s),o.key=c,o},$=(t,n)=>{const s=new nt(e,t);return s.key=t.key,s.insert(i,n),s};return n.effect((()=>{const e=Me(n.scope,c),t=x;if([b,x]=(e=>{const t=new Map,n=[];if(a(e))for(let s=0;s<e.length;s++)n.push(w(t,e[s],s));else if("number"==typeof e)for(let s=0;s<e;s++)n.push(w(t,s+1,s));else if(g(e)){let s=0;for(const r in e)n.push(w(t,e[r],s++,r))}return[n,t]})(e),_){for(let t=0;t<y.length;t++)x.has(y[t].key)||y[t].remove();const e=[];let n,s,r=b.length;for(;r--;){const c=b[r],l=t.get(c.key);let f;null==l?f=$(c,n?n.el:o):(f=y[l],Object.assign(f.ctx.scope,c.scope),l!==r&&(y[l+1]!==n||s===n)&&(s=f,f.insert(i,n?n.el:o))),e.unshift(n=f)}y=e}else y=b.map((e=>$(e,o))),_=!0})),r},He=({el:e,ctx:{scope:{$refs:t}},get:n,effect:s})=>{let r;return s((()=>{const s=n();t[s]=e,r&&s!==r&&delete t[r],r=s})),()=>{r&&delete t[r]}},Je=/^(?:v-|:|@)/,Ze=/\.([\w-]+)/g;let qe=!1;const De=(e,t)=>{const n=e.nodeType;if(1===n){const n=e;if(n.hasAttribute("v-pre"))return;let s;if(_e(n,"v-cloak"),s=_e(n,"v-if"))return((e,t,n)=>{const s=e.parentElement,r=new Comment("v-if");s.insertBefore(r,e);const i=[{exp:t,el:e}];let o,c;for(;(o=e.nextElementSibling)&&(c=null,""===_e(o,"v-else")||(c=_e(o,"v-else-if")));)s.removeChild(o),i.push({exp:c,el:o});const l=e.nextSibling;s.removeChild(e);let f,u=-1;const a=()=>{f&&(s.insertBefore(r,f.el),f.remove(),f=void 0)};return n.effect((()=>{for(let e=0;e<i.length;e++){const{exp:t,el:o}=i[e];if(!t||Me(n.scope,t))return void(e!==u&&(a(),f=new nt(o,n),f.insert(s,r),s.removeChild(r),u=e))}u=-1,a()})),l})(n,s,t);if(s=_e(n,"v-for"))return ze(n,s,t);if((s=_e(n,"v-scope"))||""===s){const e=s?Me(t.scope,s):{};t=et(t,e),e.$template&&Xe(n,e.$template)}const r=null!=_e(n,"v-once");r&&(qe=!0),(s=_e(n,"ref"))&&Qe(n,He,`"${s}"`,t),Ge(n,t);const i=[];for(const{name:e,value:o}of[...n.attributes])Je.test(e)&&"v-cloak"!==e&&("v-model"===e?i.unshift([e,o]):"@"===e[0]||/^v-on\b/.test(e)?i.push([e,o]):Ue(n,e,o,t));for(const[e,o]of i)Ue(n,e,o,t);r&&(qe=!1)}else if(3===n){const n=e.data;if(n.includes(t.delimiters[0])){let s,r=[],i=0;for(;s=t.delimitersRE.exec(n);){const e=n.slice(i,s.index);e&&r.push(JSON.stringify(e)),r.push(`$s(${s[1]})`),i=s.index+s[0].length}i<n.length&&r.push(JSON.stringify(n.slice(i))),Qe(e,Ee,r.join("+"),t)}}else 11===n&&Ge(e,t)},Ge=(e,t)=>{let n=e.firstChild;for(;n;)n=De(n,t)||n.nextSibling},Ue=(e,t,n,s)=>{let r,i,o;if(":"===(t=t.replace(Ze,((e,t)=>((o||(o={}))[t]=!0,""))))[0])r=ve,i=t.slice(1);else if("@"===t[0])r=Se,i=t.slice(1);else{const e=t.indexOf(":"),n=e>0?t.slice(2,e):t.slice(2);r=We[n]||s.dirs[n],i=e>0?t.slice(e+1):void 0}r&&(r===ve&&"ref"===i&&(r=He),Qe(e,r,n,s,i,o),e.removeAttribute(t))},Qe=(e,t,n,s,r,i)=>{const o=t({el:e,get:(t=n)=>Me(s.scope,t,e),effect:s.effect,ctx:s,exp:n,arg:r,modifiers:i});o&&s.cleanups.push(o)},Xe=(e,t)=>{if("#"!==t[0])e.innerHTML=t;else{const n=document.querySelector(t);e.appendChild(n.content.cloneNode(!0))}},Ye=e=>{const t={delimiters:["{{","}}"],delimitersRE:/\{\{([^]+?)\}\}/g,...e,scope:e?e.scope:oe({}),dirs:e?e.dirs:{},effects:[],blocks:[],cleanups:[],effect:e=>{if(qe)return de(e),e;const n=function(e,t){e.effect&&(e=e.effect.fn);const n=new W(e);t&&(l(n,t),t.scope&&S(n,t.scope)),(!t||!t.lazy)&&n.run();const s=n.run.bind(n);return s.effect=n,s}(e,{scheduler:()=>de(n)});return t.effects.push(n),n}};return t},et=(e,t={})=>{const n=e.scope,s=Object.create(n);Object.defineProperties(s,Object.getOwnPropertyDescriptors(t)),s.$refs=Object.create(n.$refs);const r=oe(new Proxy(s,{set:(e,t,s,i)=>i!==r||e.hasOwnProperty(t)?Reflect.set(e,t,s,i):Reflect.set(n,t,s)}));return tt(r),{...e,scope:r}},tt=e=>{for(const t of Object.keys(e))"function"==typeof e[t]&&(e[t]=e[t].bind(e))};class nt{constructor(e,t,n=!1){C(this,"template"),C(this,"ctx"),C(this,"key"),C(this,"parentCtx"),C(this,"isFragment"),C(this,"start"),C(this,"end"),this.isFragment=e instanceof HTMLTemplateElement,n?this.template=e:this.isFragment?this.template=e.content.cloneNode(!0):this.template=e.cloneNode(!0),n?this.ctx=t:(this.parentCtx=t,t.blocks.push(this),this.ctx=Ye(t)),De(this.template,this.ctx)}get el(){return this.start||this.template}insert(e,t=null){if(this.isFragment)if(this.start){let n,s=this.start;for(;s&&(n=s.nextSibling,e.insertBefore(s,t),s!==this.end);)s=n}else this.start=new Text(""),this.end=new Text(""),e.insertBefore(this.end,t),e.insertBefore(this.start,this.end),e.insertBefore(this.template,this.end);else e.insertBefore(this.template,t)}remove(){if(this.parentCtx&&((e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)})(this.parentCtx.blocks,this),this.start){const e=this.start.parentNode;let t,n=this.start;for(;n&&(t=n.nextSibling,e.removeChild(n),n!==this.end);)n=t}else this.template.parentNode.removeChild(this.template);this.teardown()}teardown(){this.ctx.blocks.forEach((e=>{e.teardown()})),this.ctx.effects.forEach(K),this.ctx.cleanups.forEach((e=>e()))}}const st=e=>e.replace(/[-.*+?^${}()|[\]\/\\]/g,"\\$&"),rt=e=>{const t=Ye();if(e&&(t.scope=oe(e),tt(t.scope),e.$delimiters)){const[n,s]=t.delimiters=e.$delimiters;t.delimitersRE=new RegExp(st(n)+"([^]+?)"+st(s),"g")}let n;return t.scope.$s=Ce,t.scope.$nextTick=he,t.scope.$refs=Object.create(null),{directive(e,n){return n?(t.dirs[e]=n,this):t.dirs[e]},mount(e){if("string"==typeof e&&!(e=document.querySelector(e)))return;let s;return s=(e=e||document.documentElement).hasAttribute("v-scope")?[e]:[...e.querySelectorAll("[v-scope]")].filter((e=>!e.matches("[v-scope] [v-scope]"))),s.length||(s=[e]),n=s.map((e=>new nt(e,t,!0))),this},unmount(){n.forEach((e=>e.teardown()))}}},it=document.currentScript;return it&&it.hasAttribute("init")&&rt().mount(),e.createApp=rt,e.nextTick=he,e.reactive=oe,Object.defineProperty(e,"__esModule",{value:!0}),e[Symbol.toStringTag]="Module",e}({});;
  33205. var Medici=function(t){"use strict";var e=function(){return e=Object.assign||function(t){for(var e,r=1,s=arguments.length;r<s;r++)for(var i in e=arguments[r])Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t},e.apply(this,arguments)};const r=(t,e,r)=>{const s=t[e];return(...e)=>(r.apply(null,e),s.apply(t,e))},s={};function i(){return"undefined"!=typeof window?window:"undefined"!=typeof self?self:s}const n=t=>{if(null===t)return t;if(t instanceof Date)return new Date(t.getTime());if(t instanceof Array){const e=[];return t.forEach((t=>{e.push(t)})),e.map((t=>n(t)))}if("object"==typeof t&&t!=={}){const e=Object.assign({},t);return Object.keys(e).forEach((t=>{e[t]=n(e[t])})),e}return t},a=(t,e,r)=>{return s={url:t,data:{type:e,payload:r}},new Promise(((t,e)=>{const r=new XMLHttpRequest;r.open("POST",s.url,!0),r.setRequestHeader("Content-Type","application/json"),r.onerror=e,r.onreadystatechange=()=>{4===r.readyState&&t(r.response)},r.send(JSON.stringify(s.data))}));var s};class o{constructor(t){this._config=Object.assign({user:"",version:""},t.config),this._platform=t.platform,this._appId=t.appId,this._endPoint=t.endPoint}get _stopTrack(){return o._stopTrack}get trackUrl(){return this._endPoint+"/tracking/log/save"}get trackPageViewUrl(){return this._endPoint+"/tracking/log/save"}toTrackEntity(t){const e={appId:this._appId,module:t.module,type:t.type,url:t.url||this._history.playload.url,eventType:t.eventType,referrer:t.referrer||this._history.currentRef,requestData:t.requestData};return t.language&&(e.language=t.language),t.networkType&&(e.networkType=t.networkType),t.userId&&(e.userId=t.userId),e}trackView(t,e,r){if(!this._stopTrack){this._history.playload.url=t;const e={module:"pageview",url:t,type:"pageview",eventType:"pageview",language:n(this._history.playload).language,userId:this._config.user};return a(this.trackPageViewUrl,"pageview",this.toTrackEntity(e))}}trackEvent(t,e,r,s){if(!this._stopTrack){this._history.playload.url=r;const s={module:t,url:r,type:"event",eventType:e,language:n(this._history.playload).language,userId:this._config.user};return a(this.trackPageViewUrl,"event",this.toTrackEntity(s))}}track(t,e){if(!this._stopTrack){const r=n(this._history.playload),s=n(e);delete s.eventType,delete s.maxWaitTime;const i={module:t,type:"track",eventType:e.eventType,requestData:Object.assign({screen:r.screen},s,this._config),language:r.language,networkType:e.networkType,userId:this._config.user};return a(this.trackUrl,"track",this.toTrackEntity(i))}}startTrack(t,e){if(!this._stopTrack){const r=n(this._history.playload),s=n(e);delete s.eventType,delete s.maxWaitTime;const i={module:t,type:"start_track",eventType:e.eventType,requestData:Object.assign({},s,this._config),language:r.language,networkType:e.networkType,userId:this._config.user};return e.maxWaitTime&&(this._timeOut=setTimeout((()=>{this.endTrack(t,e)}),e.maxWaitTime)),a(this.trackUrl,"period_track",this.toTrackEntity(i))}}endTrack(t,e){if(this._timeOut&&clearTimeout(this._timeOut),!this._stopTrack){const r=n(this._history.playload),s=n(e);delete s.eventType,delete s.maxWaitTime;const i={module:t,type:"end_track",eventType:e.eventType,requestData:Object.assign({},s,this._config),language:r.language,networkType:e.networkType,userId:this._config.user};return a(this.trackUrl,"period_track",this.toTrackEntity(i))}}}o._stopTrack=!1;const c=i();class h{constructor(t,e){this._sdk=t,this._appId=e,this.init(),this._playload.website=e}get playload(){return this._playload}get currentUrl(){return this._currentUrl}get currentRef(){return this._currentRef}init(){window.mediciRegisterIds||(window.mediciRegisterIds=[]);const t=window.mediciRegisterIds;!Array.from(t).includes(this._appId)&&this._appId&&(c.document.addEventListener("readystatechange",this.handleReadystatechange.bind(this),!0),c.history.pushState=r(c.history,"pushState",this.handlePushState.bind(this)),c.history.replaceState=r(c.history,"replaceState",this.handlePushState.bind(this)),window.mediciRegisterIds.push(this._appId)),this.initPlayload()}initPlayload(){const{screen:{width:t,height:e},navigator:{language:r},location:{hostname:s,pathname:i,search:n}}=c,a=`${t}x${e}`;this._currentUrl=`${i}${n}`,this._currentRef=c.document.referrer,this._playload={website:"",hostname:s,screen:a,language:r,url:this._currentUrl,referrer:this._currentRef}}handleReadystatechange(){"complete"===c.document.readyState&&(this.observeDocument(),this._sdk.eventer.initElementCssEvents(c.document.body),this._sdk.trackView(this._currentUrl,this._currentRef,this._playload.website))}handlePushState(t,e,r){try{if(!r)return;const{hash:t}=c.location;this._currentRef=this._currentUrl;const e=r.toString();"http"===e.substring(0,4)?this._currentUrl="/"+e.split("/").splice(3).join("/"):this._currentUrl=e,t&&(this._currentUrl="/"+e.replace(t,"")),this._currentUrl!==this._currentRef&&this._sdk.trackView(this._currentUrl,this._currentRef,this._playload.website)}catch(t){}}handleBackState(t,e,r){}observeDocument(){new MutationObserver((t=>{const e=[];t.forEach((t=>{e.push(Array.from(t.addedNodes))})),Array.from(e.flat()).forEach((t=>{if("getAttribute"in t&&(this._sdk.eventer.addCssEvent(t),t.hasChildNodes)){t.querySelectorAll(this._sdk.eventer.eventSelect).forEach((t=>{"getAttribute"in t&&this._sdk.eventer.addCssEvent(t)}))}}))})).observe(c.document,{childList:!0,subtree:!0})}}class l{constructor(t){this.listeners={},this._sdk=t,this._identifier="mdc",this._eventSelect=`[class*='${this._identifier}--']`,this.eventClassValidate=/^mdc--([a-z]+)--([\w]+[\w-]*)$/}updateIdentifier(t){this._identifier=t,this.eventClassValidate=new RegExp("^"+t+"--([a-z]+)--([w]+[w-]*)$")}get eventSelect(){return this._eventSelect}initElementCssEvents(t){const e=t.querySelectorAll(this.eventSelect);Array.prototype.forEach.call(e,this.addCssEvent.bind(this))}addCssEvent(t){(t.getAttribute("class")||"").split(" ").forEach((e=>{if(!this.eventClassValidate.test(e))return;const[,r,s]=e.split("--"),i=this.listeners[e]?this.listeners[e]:this.listeners[e]=()=>{t.tagName,this._sdk.trackEvent(s,r)};t.addEventListener(r,i,!0)}))}}class u extends o{constructor(t){super(t),this.eventer=new l(this),this._history=new h(this,t.appId),super._history=this._history,"stopTrack"in t&&(o._stopTrack=t.stopTrack),this.setConfig(t.config)}setConfig(t){this._config=Object.assign({user:"",version:""},t),super._config=this._config}stop(){o._stopTrack=!0}resume(){o._stopTrack=!1}}var d=function(t){var r=e(e({},t),{platform:"web"});return new u(r)},p=i().document.currentScript;if(p){var y=p.getAttribute.bind(p),g=y("data-app-id"),_=y("data-url");g&&_&&(window.medici=d({platform:"web",appId:g,endPoint:_}))}return t.init=d,Object.defineProperty(t,"__esModule",{value:!0}),t}({});;
  33206. typeof window !== "undefined" &&
  33207. (function webpackUniversalModuleDefinition(root, factory) {
  33208. if(typeof exports === 'object' && typeof module === 'object')
  33209. module.exports = factory();
  33210. else if(typeof define === 'function' && define.amd)
  33211. define([], factory);
  33212. else if(typeof exports === 'object')
  33213. exports["Hls"] = factory();
  33214. else
  33215. root["Hls"] = factory();
  33216. })(this, () => {
  33217. return /******/ (() => { // webpackBootstrap
  33218. /******/ var __webpack_modules__ = ({
  33219. /***/ "./src/config.ts":
  33220. /*!***********************!*\
  33221. !*** ./src/config.ts ***!
  33222. \***********************/
  33223. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  33224. "use strict";
  33225. __webpack_require__.r(__webpack_exports__);
  33226. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  33227. /* harmony export */ "enableStreamingMode": () => (/* binding */ enableStreamingMode),
  33228. /* harmony export */ "hlsDefaultConfig": () => (/* binding */ hlsDefaultConfig),
  33229. /* harmony export */ "mergeConfig": () => (/* binding */ mergeConfig)
  33230. /* harmony export */ });
  33231. /* harmony import */ var _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./controller/abr-controller */ "./src/controller/abr-controller.ts");
  33232. /* harmony import */ var _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controller/audio-stream-controller */ "./src/controller/audio-stream-controller.ts");
  33233. /* harmony import */ var _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controller/audio-track-controller */ "./src/controller/audio-track-controller.ts");
  33234. /* harmony import */ var _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controller/subtitle-stream-controller */ "./src/controller/subtitle-stream-controller.ts");
  33235. /* harmony import */ var _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controller/subtitle-track-controller */ "./src/controller/subtitle-track-controller.ts");
  33236. /* harmony import */ var _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controller/buffer-controller */ "./src/controller/buffer-controller.ts");
  33237. /* harmony import */ var _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./controller/timeline-controller */ "./src/controller/timeline-controller.ts");
  33238. /* harmony import */ var _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controller/cap-level-controller */ "./src/controller/cap-level-controller.ts");
  33239. /* harmony import */ var _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./controller/fps-controller */ "./src/controller/fps-controller.ts");
  33240. /* harmony import */ var _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./controller/eme-controller */ "./src/controller/eme-controller.ts");
  33241. /* harmony import */ var _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./controller/cmcd-controller */ "./src/controller/cmcd-controller.ts");
  33242. /* harmony import */ var _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./utils/xhr-loader */ "./src/utils/xhr-loader.ts");
  33243. /* harmony import */ var _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./utils/fetch-loader */ "./src/utils/fetch-loader.ts");
  33244. /* harmony import */ var _utils_cues__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./utils/cues */ "./src/utils/cues.ts");
  33245. /* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts");
  33246. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./utils/logger */ "./src/utils/logger.ts");
  33247. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  33248. function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
  33249. function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
  33250. function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  33251. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  33252. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  33253. // If possible, keep hlsDefaultConfig shallow
  33254. // It is cloned whenever a new Hls instance is created, by keeping the config
  33255. // shallow the properties are cloned, and we don't end up manipulating the default
  33256. var hlsDefaultConfig = _objectSpread(_objectSpread({
  33257. autoStartLoad: true,
  33258. // used by stream-controller
  33259. startPosition: -1,
  33260. // used by stream-controller
  33261. defaultAudioCodec: undefined,
  33262. // used by stream-controller
  33263. debug: false,
  33264. // used by logger
  33265. capLevelOnFPSDrop: false,
  33266. // used by fps-controller
  33267. capLevelToPlayerSize: false,
  33268. // used by cap-level-controller
  33269. ignoreDevicePixelRatio: false,
  33270. // used by cap-level-controller
  33271. initialLiveManifestSize: 1,
  33272. // used by stream-controller
  33273. maxBufferLength: 30,
  33274. // used by stream-controller
  33275. backBufferLength: Infinity,
  33276. // used by buffer-controller
  33277. maxBufferSize: 60 * 1000 * 1000,
  33278. // used by stream-controller
  33279. maxBufferHole: 0.1,
  33280. // used by stream-controller
  33281. highBufferWatchdogPeriod: 2,
  33282. // used by stream-controller
  33283. nudgeOffset: 0.1,
  33284. // used by stream-controller
  33285. nudgeMaxRetry: 3,
  33286. // used by stream-controller
  33287. maxFragLookUpTolerance: 0.25,
  33288. // used by stream-controller
  33289. liveSyncDurationCount: 3,
  33290. // used by latency-controller
  33291. liveMaxLatencyDurationCount: Infinity,
  33292. // used by latency-controller
  33293. liveSyncDuration: undefined,
  33294. // used by latency-controller
  33295. liveMaxLatencyDuration: undefined,
  33296. // used by latency-controller
  33297. maxLiveSyncPlaybackRate: 1,
  33298. // used by latency-controller
  33299. liveDurationInfinity: false,
  33300. // used by buffer-controller
  33301. liveBackBufferLength: null,
  33302. // used by buffer-controller
  33303. maxMaxBufferLength: 600,
  33304. // used by stream-controller
  33305. enableWorker: true,
  33306. // used by demuxer
  33307. enableSoftwareAES: true,
  33308. // used by decrypter
  33309. manifestLoadingTimeOut: 10000,
  33310. // used by playlist-loader
  33311. manifestLoadingMaxRetry: 1,
  33312. // used by playlist-loader
  33313. manifestLoadingRetryDelay: 1000,
  33314. // used by playlist-loader
  33315. manifestLoadingMaxRetryTimeout: 64000,
  33316. // used by playlist-loader
  33317. startLevel: undefined,
  33318. // used by level-controller
  33319. levelLoadingTimeOut: 10000,
  33320. // used by playlist-loader
  33321. levelLoadingMaxRetry: 4,
  33322. // used by playlist-loader
  33323. levelLoadingRetryDelay: 1000,
  33324. // used by playlist-loader
  33325. levelLoadingMaxRetryTimeout: 64000,
  33326. // used by playlist-loader
  33327. fragLoadingTimeOut: 20000,
  33328. // used by fragment-loader
  33329. fragLoadingMaxRetry: 6,
  33330. // used by fragment-loader
  33331. fragLoadingRetryDelay: 1000,
  33332. // used by fragment-loader
  33333. fragLoadingMaxRetryTimeout: 64000,
  33334. // used by fragment-loader
  33335. startFragPrefetch: false,
  33336. // used by stream-controller
  33337. fpsDroppedMonitoringPeriod: 5000,
  33338. // used by fps-controller
  33339. fpsDroppedMonitoringThreshold: 0.2,
  33340. // used by fps-controller
  33341. appendErrorMaxRetry: 3,
  33342. // used by buffer-controller
  33343. loader: _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"],
  33344. // loader: FetchLoader,
  33345. fLoader: undefined,
  33346. // used by fragment-loader
  33347. pLoader: undefined,
  33348. // used by playlist-loader
  33349. xhrSetup: undefined,
  33350. // used by xhr-loader
  33351. licenseXhrSetup: undefined,
  33352. // used by eme-controller
  33353. licenseResponseCallback: undefined,
  33354. // used by eme-controller
  33355. abrController: _controller_abr_controller__WEBPACK_IMPORTED_MODULE_0__["default"],
  33356. bufferController: _controller_buffer_controller__WEBPACK_IMPORTED_MODULE_5__["default"],
  33357. capLevelController: _controller_cap_level_controller__WEBPACK_IMPORTED_MODULE_7__["default"],
  33358. fpsController: _controller_fps_controller__WEBPACK_IMPORTED_MODULE_8__["default"],
  33359. stretchShortVideoTrack: false,
  33360. // used by mp4-remuxer
  33361. maxAudioFramesDrift: 1,
  33362. // used by mp4-remuxer
  33363. forceKeyFrameOnDiscontinuity: true,
  33364. // used by ts-demuxer
  33365. abrEwmaFastLive: 3,
  33366. // used by abr-controller
  33367. abrEwmaSlowLive: 9,
  33368. // used by abr-controller
  33369. abrEwmaFastVoD: 3,
  33370. // used by abr-controller
  33371. abrEwmaSlowVoD: 9,
  33372. // used by abr-controller
  33373. abrEwmaDefaultEstimate: 5e5,
  33374. // 500 kbps // used by abr-controller
  33375. abrBandWidthFactor: 0.95,
  33376. // used by abr-controller
  33377. abrBandWidthUpFactor: 0.7,
  33378. // used by abr-controller
  33379. abrMaxWithRealBitrate: false,
  33380. // used by abr-controller
  33381. maxStarvationDelay: 4,
  33382. // used by abr-controller
  33383. maxLoadingDelay: 4,
  33384. // used by abr-controller
  33385. minAutoBitrate: 0,
  33386. // used by hls
  33387. emeEnabled: false,
  33388. // used by eme-controller
  33389. widevineLicenseUrl: undefined,
  33390. // used by eme-controller
  33391. drmSystems: {},
  33392. // used by eme-controller
  33393. drmSystemOptions: {},
  33394. // used by eme-controller
  33395. requestMediaKeySystemAccessFunc: _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_14__.requestMediaKeySystemAccess,
  33396. // used by eme-controller
  33397. testBandwidth: true,
  33398. progressive: false,
  33399. lowLatencyMode: true,
  33400. cmcd: undefined,
  33401. enableDateRangeMetadataCues: true,
  33402. enableEmsgMetadataCues: true,
  33403. enableID3MetadataCues: true
  33404. }, timelineConfig()), {}, {
  33405. subtitleStreamController: true ? _controller_subtitle_stream_controller__WEBPACK_IMPORTED_MODULE_3__.SubtitleStreamController : 0,
  33406. subtitleTrackController: true ? _controller_subtitle_track_controller__WEBPACK_IMPORTED_MODULE_4__["default"] : 0,
  33407. timelineController: true ? _controller_timeline_controller__WEBPACK_IMPORTED_MODULE_6__.TimelineController : 0,
  33408. audioStreamController: true ? _controller_audio_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"] : 0,
  33409. audioTrackController: true ? _controller_audio_track_controller__WEBPACK_IMPORTED_MODULE_2__["default"] : 0,
  33410. emeController: true ? _controller_eme_controller__WEBPACK_IMPORTED_MODULE_9__["default"] : 0,
  33411. cmcdController: true ? _controller_cmcd_controller__WEBPACK_IMPORTED_MODULE_10__["default"] : 0
  33412. });
  33413. function timelineConfig() {
  33414. return {
  33415. cueHandler: _utils_cues__WEBPACK_IMPORTED_MODULE_13__["default"],
  33416. // used by timeline-controller
  33417. enableWebVTT: true,
  33418. // used by timeline-controller
  33419. enableIMSC1: true,
  33420. // used by timeline-controller
  33421. enableCEA708Captions: true,
  33422. // used by timeline-controller
  33423. captionsTextTrack1Label: 'English',
  33424. // used by timeline-controller
  33425. captionsTextTrack1LanguageCode: 'en',
  33426. // used by timeline-controller
  33427. captionsTextTrack2Label: 'Spanish',
  33428. // used by timeline-controller
  33429. captionsTextTrack2LanguageCode: 'es',
  33430. // used by timeline-controller
  33431. captionsTextTrack3Label: 'Unknown CC',
  33432. // used by timeline-controller
  33433. captionsTextTrack3LanguageCode: '',
  33434. // used by timeline-controller
  33435. captionsTextTrack4Label: 'Unknown CC',
  33436. // used by timeline-controller
  33437. captionsTextTrack4LanguageCode: '',
  33438. // used by timeline-controller
  33439. renderTextTracksNatively: true
  33440. };
  33441. }
  33442. function mergeConfig(defaultConfig, userConfig) {
  33443. if ((userConfig.liveSyncDurationCount || userConfig.liveMaxLatencyDurationCount) && (userConfig.liveSyncDuration || userConfig.liveMaxLatencyDuration)) {
  33444. throw new Error("Illegal hls.js config: don't mix up liveSyncDurationCount/liveMaxLatencyDurationCount and liveSyncDuration/liveMaxLatencyDuration");
  33445. }
  33446. if (userConfig.liveMaxLatencyDurationCount !== undefined && (userConfig.liveSyncDurationCount === undefined || userConfig.liveMaxLatencyDurationCount <= userConfig.liveSyncDurationCount)) {
  33447. throw new Error('Illegal hls.js config: "liveMaxLatencyDurationCount" must be greater than "liveSyncDurationCount"');
  33448. }
  33449. if (userConfig.liveMaxLatencyDuration !== undefined && (userConfig.liveSyncDuration === undefined || userConfig.liveMaxLatencyDuration <= userConfig.liveSyncDuration)) {
  33450. throw new Error('Illegal hls.js config: "liveMaxLatencyDuration" must be greater than "liveSyncDuration"');
  33451. }
  33452. return _extends({}, defaultConfig, userConfig);
  33453. }
  33454. function enableStreamingMode(config) {
  33455. var currentLoader = config.loader;
  33456. if (currentLoader !== _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"] && currentLoader !== _utils_xhr_loader__WEBPACK_IMPORTED_MODULE_11__["default"]) {
  33457. // If a developer has configured their own loader, respect that choice
  33458. _utils_logger__WEBPACK_IMPORTED_MODULE_15__.logger.log('[config]: Custom loader detected, cannot enable progressive streaming');
  33459. config.progressive = false;
  33460. } else {
  33461. var canStreamProgressively = (0,_utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__.fetchSupported)();
  33462. if (canStreamProgressively) {
  33463. config.loader = _utils_fetch_loader__WEBPACK_IMPORTED_MODULE_12__["default"];
  33464. config.progressive = true;
  33465. config.enableSoftwareAES = true;
  33466. _utils_logger__WEBPACK_IMPORTED_MODULE_15__.logger.log('[config]: Progressive streaming enabled, using FetchLoader');
  33467. }
  33468. }
  33469. }
  33470. /***/ }),
  33471. /***/ "./src/controller/abr-controller.ts":
  33472. /*!******************************************!*\
  33473. !*** ./src/controller/abr-controller.ts ***!
  33474. \******************************************/
  33475. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  33476. "use strict";
  33477. __webpack_require__.r(__webpack_exports__);
  33478. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  33479. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  33480. /* harmony export */ });
  33481. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  33482. /* harmony import */ var _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/ewma-bandwidth-estimator */ "./src/utils/ewma-bandwidth-estimator.ts");
  33483. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  33484. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  33485. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  33486. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  33487. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  33488. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  33489. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  33490. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  33491. var AbrController = /*#__PURE__*/function () {
  33492. function AbrController(hls) {
  33493. this.hls = void 0;
  33494. this.lastLoadedFragLevel = 0;
  33495. this._nextAutoLevel = -1;
  33496. this.timer = void 0;
  33497. this.onCheck = this._abandonRulesCheck.bind(this);
  33498. this.fragCurrent = null;
  33499. this.partCurrent = null;
  33500. this.bitrateTestDelay = 0;
  33501. this.bwEstimator = void 0;
  33502. this.hls = hls;
  33503. var config = hls.config;
  33504. this.bwEstimator = new _utils_ewma_bandwidth_estimator__WEBPACK_IMPORTED_MODULE_1__["default"](config.abrEwmaSlowVoD, config.abrEwmaFastVoD, config.abrEwmaDefaultEstimate);
  33505. this.registerListeners();
  33506. }
  33507. var _proto = AbrController.prototype;
  33508. _proto.registerListeners = function registerListeners() {
  33509. var hls = this.hls;
  33510. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADING, this.onFragLoading, this);
  33511. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADED, this.onFragLoaded, this);
  33512. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  33513. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  33514. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, this.onError, this);
  33515. };
  33516. _proto.unregisterListeners = function unregisterListeners() {
  33517. var hls = this.hls;
  33518. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADING, this.onFragLoading, this);
  33519. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOADED, this.onFragLoaded, this);
  33520. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  33521. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  33522. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, this.onError, this);
  33523. };
  33524. _proto.destroy = function destroy() {
  33525. this.unregisterListeners();
  33526. this.clearTimer();
  33527. // @ts-ignore
  33528. this.hls = this.onCheck = null;
  33529. this.fragCurrent = this.partCurrent = null;
  33530. };
  33531. _proto.onFragLoading = function onFragLoading(event, data) {
  33532. var frag = data.frag;
  33533. if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN) {
  33534. if (!this.timer) {
  33535. var _data$part;
  33536. this.fragCurrent = frag;
  33537. this.partCurrent = (_data$part = data.part) != null ? _data$part : null;
  33538. this.timer = self.setInterval(this.onCheck, 100);
  33539. }
  33540. }
  33541. };
  33542. _proto.onLevelLoaded = function onLevelLoaded(event, data) {
  33543. var config = this.hls.config;
  33544. if (data.details.live) {
  33545. this.bwEstimator.update(config.abrEwmaSlowLive, config.abrEwmaFastLive);
  33546. } else {
  33547. this.bwEstimator.update(config.abrEwmaSlowVoD, config.abrEwmaFastVoD);
  33548. }
  33549. }
  33550. /*
  33551. This method monitors the download rate of the current fragment, and will downswitch if that fragment will not load
  33552. quickly enough to prevent underbuffering
  33553. */;
  33554. _proto._abandonRulesCheck = function _abandonRulesCheck() {
  33555. var frag = this.fragCurrent,
  33556. part = this.partCurrent,
  33557. hls = this.hls;
  33558. var autoLevelEnabled = hls.autoLevelEnabled,
  33559. media = hls.media;
  33560. if (!frag || !media) {
  33561. return;
  33562. }
  33563. var stats = part ? part.stats : frag.stats;
  33564. var duration = part ? part.duration : frag.duration;
  33565. // If frag loading is aborted, complete, or from lowest level, stop timer and return
  33566. if (stats.aborted || stats.loaded && stats.loaded === stats.total || frag.level === 0) {
  33567. this.clearTimer();
  33568. // reset forced auto level value so that next level will be selected
  33569. this._nextAutoLevel = -1;
  33570. return;
  33571. }
  33572. // This check only runs if we're in ABR mode and actually playing
  33573. if (!autoLevelEnabled || media.paused || !media.playbackRate || !media.readyState) {
  33574. return;
  33575. }
  33576. var bufferInfo = hls.mainForwardBufferInfo;
  33577. if (bufferInfo === null) {
  33578. return;
  33579. }
  33580. var requestDelay = performance.now() - stats.loading.start;
  33581. var playbackRate = Math.abs(media.playbackRate);
  33582. // In order to work with a stable bandwidth, only begin monitoring bandwidth after half of the fragment has been loaded
  33583. if (requestDelay <= 500 * duration / playbackRate) {
  33584. return;
  33585. }
  33586. var loadedFirstByte = stats.loaded && stats.loading.first;
  33587. var bwEstimate = this.bwEstimator.getEstimate();
  33588. var levels = hls.levels,
  33589. minAutoLevel = hls.minAutoLevel;
  33590. var level = levels[frag.level];
  33591. var expectedLen = stats.total || Math.max(stats.loaded, Math.round(duration * level.maxBitrate / 8));
  33592. var loadRate = loadedFirstByte ? stats.loaded * 1000 / requestDelay : 0;
  33593. // fragLoadDelay is an estimate of the time (in seconds) it will take to buffer the remainder of the fragment
  33594. var fragLoadedDelay = loadRate ? (expectedLen - stats.loaded) / loadRate : expectedLen * 8 / bwEstimate;
  33595. // bufferStarvationDelay is an estimate of the amount time (in seconds) it will take to exhaust the buffer
  33596. var bufferStarvationDelay = bufferInfo.len / playbackRate;
  33597. // Only downswitch if the time to finish loading the current fragment is greater than the amount of buffer left
  33598. if (fragLoadedDelay <= bufferStarvationDelay) {
  33599. return;
  33600. }
  33601. var fragLevelNextLoadedDelay = Number.POSITIVE_INFINITY;
  33602. var nextLoadLevel;
  33603. // Iterate through lower level and try to find the largest one that avoids rebuffering
  33604. for (nextLoadLevel = frag.level - 1; nextLoadLevel > minAutoLevel; nextLoadLevel--) {
  33605. // compute time to load next fragment at lower level
  33606. // 0.8 : consider only 80% of current bw to be conservative
  33607. // 8 = bits per byte (bps/Bps)
  33608. var levelNextBitrate = levels[nextLoadLevel].maxBitrate;
  33609. fragLevelNextLoadedDelay = loadRate ? duration * levelNextBitrate / (8 * 0.8 * loadRate) : duration * levelNextBitrate / bwEstimate;
  33610. if (fragLevelNextLoadedDelay < bufferStarvationDelay) {
  33611. break;
  33612. }
  33613. }
  33614. // Only emergency switch down if it takes less time to load a new fragment at lowest level instead of continuing
  33615. // to load the current one
  33616. if (fragLevelNextLoadedDelay >= fragLoadedDelay) {
  33617. return;
  33618. }
  33619. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("Fragment " + frag.sn + (part ? ' part ' + part.index : '') + " of level " + frag.level + " is loading too slowly and will cause an underbuffer; aborting and switching to level " + nextLoadLevel + "\n Current BW estimate: " + ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(bwEstimate) ? (bwEstimate / 1024).toFixed(3) : 'Unknown') + " Kb/s\n Estimated load time for current fragment: " + fragLoadedDelay.toFixed(3) + " s\n Estimated load time for the next fragment: " + fragLevelNextLoadedDelay.toFixed(3) + " s\n Time to underbuffer: " + bufferStarvationDelay.toFixed(3) + " s");
  33620. hls.nextLoadLevel = nextLoadLevel;
  33621. if (loadedFirstByte) {
  33622. // If there has been loading progress, sample bandwidth
  33623. this.bwEstimator.sample(requestDelay, stats.loaded);
  33624. }
  33625. this.clearTimer();
  33626. if (frag.loader || frag.keyLoader) {
  33627. this.fragCurrent = this.partCurrent = null;
  33628. frag.abortRequests();
  33629. }
  33630. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_LOAD_EMERGENCY_ABORTED, {
  33631. frag: frag,
  33632. part: part,
  33633. stats: stats
  33634. });
  33635. };
  33636. _proto.onFragLoaded = function onFragLoaded(event, _ref) {
  33637. var frag = _ref.frag,
  33638. part = _ref.part;
  33639. if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.sn)) {
  33640. var stats = part ? part.stats : frag.stats;
  33641. var duration = part ? part.duration : frag.duration;
  33642. // stop monitoring bw once frag loaded
  33643. this.clearTimer();
  33644. // store level id after successful fragment load
  33645. this.lastLoadedFragLevel = frag.level;
  33646. // reset forced auto level value so that next level will be selected
  33647. this._nextAutoLevel = -1;
  33648. // compute level average bitrate
  33649. if (this.hls.config.abrMaxWithRealBitrate) {
  33650. var level = this.hls.levels[frag.level];
  33651. var loadedBytes = (level.loaded ? level.loaded.bytes : 0) + stats.loaded;
  33652. var loadedDuration = (level.loaded ? level.loaded.duration : 0) + duration;
  33653. level.loaded = {
  33654. bytes: loadedBytes,
  33655. duration: loadedDuration
  33656. };
  33657. level.realBitrate = Math.round(8 * loadedBytes / loadedDuration);
  33658. }
  33659. if (frag.bitrateTest) {
  33660. var fragBufferedData = {
  33661. stats: stats,
  33662. frag: frag,
  33663. part: part,
  33664. id: frag.type
  33665. };
  33666. this.onFragBuffered(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED, fragBufferedData);
  33667. }
  33668. }
  33669. };
  33670. _proto.onFragBuffered = function onFragBuffered(event, data) {
  33671. var frag = data.frag,
  33672. part = data.part;
  33673. var stats = part ? part.stats : frag.stats;
  33674. if (stats.aborted) {
  33675. return;
  33676. }
  33677. // Only count non-alt-audio frags which were actually buffered in our BW calculations
  33678. if (frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN || frag.sn === 'initSegment') {
  33679. return;
  33680. }
  33681. // Use the difference between parsing and request instead of buffering and request to compute fragLoadingProcessing;
  33682. // rationale is that buffer appending only happens once media is attached. This can happen when config.startFragPrefetch
  33683. // is used. If we used buffering in that case, our BW estimate sample will be very large.
  33684. var processingMs = stats.parsing.end - stats.loading.start;
  33685. this.bwEstimator.sample(processingMs, stats.loaded);
  33686. stats.bwEstimate = this.bwEstimator.getEstimate();
  33687. if (frag.bitrateTest) {
  33688. this.bitrateTestDelay = processingMs / 1000;
  33689. } else {
  33690. this.bitrateTestDelay = 0;
  33691. }
  33692. };
  33693. _proto.onError = function onError(event, data) {
  33694. var _data$frag;
  33695. // stop timer in case of frag loading error
  33696. if (((_data$frag = data.frag) === null || _data$frag === void 0 ? void 0 : _data$frag.type) === _types_loader__WEBPACK_IMPORTED_MODULE_4__.PlaylistLevelType.MAIN) {
  33697. if (data.type === _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.KEY_SYSTEM_ERROR) {
  33698. this.clearTimer();
  33699. return;
  33700. }
  33701. switch (data.details) {
  33702. case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.FRAG_LOAD_ERROR:
  33703. case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.FRAG_LOAD_TIMEOUT:
  33704. case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.KEY_LOAD_ERROR:
  33705. case _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.KEY_LOAD_TIMEOUT:
  33706. this.clearTimer();
  33707. break;
  33708. default:
  33709. break;
  33710. }
  33711. }
  33712. };
  33713. _proto.clearTimer = function clearTimer() {
  33714. self.clearInterval(this.timer);
  33715. this.timer = undefined;
  33716. }
  33717. // return next auto level
  33718. ;
  33719. _proto.getNextABRAutoLevel = function getNextABRAutoLevel() {
  33720. var fragCurrent = this.fragCurrent,
  33721. partCurrent = this.partCurrent,
  33722. hls = this.hls;
  33723. var maxAutoLevel = hls.maxAutoLevel,
  33724. config = hls.config,
  33725. minAutoLevel = hls.minAutoLevel,
  33726. media = hls.media;
  33727. var currentFragDuration = partCurrent ? partCurrent.duration : fragCurrent ? fragCurrent.duration : 0;
  33728. // playbackRate is the absolute value of the playback rate; if media.playbackRate is 0, we use 1 to load as
  33729. // if we're playing back at the normal rate.
  33730. var playbackRate = media && media.playbackRate !== 0 ? Math.abs(media.playbackRate) : 1.0;
  33731. var avgbw = this.bwEstimator ? this.bwEstimator.getEstimate() : config.abrEwmaDefaultEstimate;
  33732. // bufferStarvationDelay is the wall-clock time left until the playback buffer is exhausted.
  33733. var bufferInfo = hls.mainForwardBufferInfo;
  33734. var bufferStarvationDelay = (bufferInfo ? bufferInfo.len : 0) / playbackRate;
  33735. // First, look to see if we can find a level matching with our avg bandwidth AND that could also guarantee no rebuffering at all
  33736. var bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay, config.abrBandWidthFactor, config.abrBandWidthUpFactor);
  33737. if (bestLevel >= 0) {
  33738. return bestLevel;
  33739. }
  33740. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace((bufferStarvationDelay ? 'rebuffering expected' : 'buffer is empty') + ", finding optimal quality level");
  33741. // not possible to get rid of rebuffering ... let's try to find level that will guarantee less than maxStarvationDelay of rebuffering
  33742. // if no matching level found, logic will return 0
  33743. var maxStarvationDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxStarvationDelay) : config.maxStarvationDelay;
  33744. var bwFactor = config.abrBandWidthFactor;
  33745. var bwUpFactor = config.abrBandWidthUpFactor;
  33746. if (!bufferStarvationDelay) {
  33747. // in case buffer is empty, let's check if previous fragment was loaded to perform a bitrate test
  33748. var bitrateTestDelay = this.bitrateTestDelay;
  33749. if (bitrateTestDelay) {
  33750. // if it is the case, then we need to adjust our max starvation delay using maxLoadingDelay config value
  33751. // max video loading delay used in automatic start level selection :
  33752. // in that mode ABR controller will ensure that video loading time (ie the time to fetch the first fragment at lowest quality level +
  33753. // the time to fetch the fragment at the appropriate quality level is less than ```maxLoadingDelay``` )
  33754. // cap maxLoadingDelay and ensure it is not bigger 'than bitrate test' frag duration
  33755. var maxLoadingDelay = currentFragDuration ? Math.min(currentFragDuration, config.maxLoadingDelay) : config.maxLoadingDelay;
  33756. maxStarvationDelay = maxLoadingDelay - bitrateTestDelay;
  33757. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace("bitrate test took " + Math.round(1000 * bitrateTestDelay) + "ms, set first fragment max fetchDuration to " + Math.round(1000 * maxStarvationDelay) + " ms");
  33758. // don't use conservative factor on bitrate test
  33759. bwFactor = bwUpFactor = 1;
  33760. }
  33761. }
  33762. bestLevel = this.findBestLevel(avgbw, minAutoLevel, maxAutoLevel, bufferStarvationDelay + maxStarvationDelay, bwFactor, bwUpFactor);
  33763. return Math.max(bestLevel, 0);
  33764. };
  33765. _proto.findBestLevel = function findBestLevel(currentBw, minAutoLevel, maxAutoLevel, maxFetchDuration, bwFactor, bwUpFactor) {
  33766. var _level$details;
  33767. var fragCurrent = this.fragCurrent,
  33768. partCurrent = this.partCurrent,
  33769. currentLevel = this.lastLoadedFragLevel;
  33770. var levels = this.hls.levels;
  33771. var level = levels[currentLevel];
  33772. var live = !!(level !== null && level !== void 0 && (_level$details = level.details) !== null && _level$details !== void 0 && _level$details.live);
  33773. var currentCodecSet = level === null || level === void 0 ? void 0 : level.codecSet;
  33774. var currentFragDuration = partCurrent ? partCurrent.duration : fragCurrent ? fragCurrent.duration : 0;
  33775. for (var i = maxAutoLevel; i >= minAutoLevel; i--) {
  33776. var levelInfo = levels[i];
  33777. if (!levelInfo || currentCodecSet && levelInfo.codecSet !== currentCodecSet) {
  33778. continue;
  33779. }
  33780. var levelDetails = levelInfo.details;
  33781. var avgDuration = (partCurrent ? levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.partTarget : levelDetails === null || levelDetails === void 0 ? void 0 : levelDetails.averagetargetduration) || currentFragDuration;
  33782. var adjustedbw = void 0;
  33783. // follow algorithm captured from stagefright :
  33784. // https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/httplive/LiveSession.cpp
  33785. // Pick the highest bandwidth stream below or equal to estimated bandwidth.
  33786. // consider only 80% of the available bandwidth, but if we are switching up,
  33787. // be even more conservative (70%) to avoid overestimating and immediately
  33788. // switching back.
  33789. if (i <= currentLevel) {
  33790. adjustedbw = bwFactor * currentBw;
  33791. } else {
  33792. adjustedbw = bwUpFactor * currentBw;
  33793. }
  33794. var bitrate = levels[i].maxBitrate;
  33795. var fetchDuration = bitrate * avgDuration / adjustedbw;
  33796. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace("level/adjustedbw/bitrate/avgDuration/maxFetchDuration/fetchDuration: " + i + "/" + Math.round(adjustedbw) + "/" + bitrate + "/" + avgDuration + "/" + maxFetchDuration + "/" + fetchDuration);
  33797. // if adjusted bw is greater than level bitrate AND
  33798. if (adjustedbw > bitrate && (
  33799. // fragment fetchDuration unknown OR live stream OR fragment fetchDuration less than max allowed fetch duration, then this level matches
  33800. // we don't account for max Fetch Duration for live streams, this is to avoid switching down when near the edge of live sliding window ...
  33801. // special case to support startLevel = -1 (bitrateTest) on live streams : in that case we should not exit loop so that findBestLevel will return -1
  33802. fetchDuration === 0 || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(fetchDuration) || live && !this.bitrateTestDelay || fetchDuration < maxFetchDuration)) {
  33803. // as we are looping from highest to lowest, this will return the best achievable quality level
  33804. return i;
  33805. }
  33806. }
  33807. // not enough time budget even with quality level 0 ... rebuffering might happen
  33808. return -1;
  33809. };
  33810. _createClass(AbrController, [{
  33811. key: "nextAutoLevel",
  33812. get: function get() {
  33813. var forcedAutoLevel = this._nextAutoLevel;
  33814. var bwEstimator = this.bwEstimator;
  33815. // in case next auto level has been forced, and bw not available or not reliable, return forced value
  33816. if (forcedAutoLevel !== -1 && !bwEstimator.canEstimate()) {
  33817. return forcedAutoLevel;
  33818. }
  33819. // compute next level using ABR logic
  33820. var nextABRAutoLevel = this.getNextABRAutoLevel();
  33821. // use forced auto level when ABR selected level has errored
  33822. if (forcedAutoLevel !== -1 && this.hls.levels[nextABRAutoLevel].loadError) {
  33823. return forcedAutoLevel;
  33824. }
  33825. // if forced auto level has been defined, use it to cap ABR computed quality level
  33826. if (forcedAutoLevel !== -1) {
  33827. nextABRAutoLevel = Math.min(forcedAutoLevel, nextABRAutoLevel);
  33828. }
  33829. return nextABRAutoLevel;
  33830. },
  33831. set: function set(nextLevel) {
  33832. this._nextAutoLevel = nextLevel;
  33833. }
  33834. }]);
  33835. return AbrController;
  33836. }();
  33837. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AbrController);
  33838. /***/ }),
  33839. /***/ "./src/controller/audio-stream-controller.ts":
  33840. /*!***************************************************!*\
  33841. !*** ./src/controller/audio-stream-controller.ts ***!
  33842. \***************************************************/
  33843. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  33844. "use strict";
  33845. __webpack_require__.r(__webpack_exports__);
  33846. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  33847. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  33848. /* harmony export */ });
  33849. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  33850. /* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts");
  33851. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  33852. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  33853. /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts");
  33854. /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts");
  33855. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  33856. /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts");
  33857. /* harmony import */ var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../demux/chunk-cache */ "./src/demux/chunk-cache.ts");
  33858. /* harmony import */ var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../demux/transmuxer-interface */ "./src/demux/transmuxer-interface.ts");
  33859. /* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts");
  33860. /* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts");
  33861. /* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts");
  33862. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  33863. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  33864. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  33865. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  33866. var TICK_INTERVAL = 100; // how often to tick in ms
  33867. var AudioStreamController = /*#__PURE__*/function (_BaseStreamController) {
  33868. _inheritsLoose(AudioStreamController, _BaseStreamController);
  33869. function AudioStreamController(hls, fragmentTracker, keyLoader) {
  33870. var _this;
  33871. _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[audio-stream-controller]') || this;
  33872. _this.videoBuffer = null;
  33873. _this.videoTrackCC = -1;
  33874. _this.waitingVideoCC = -1;
  33875. _this.audioSwitch = false;
  33876. _this.trackId = -1;
  33877. _this.waitingData = null;
  33878. _this.mainDetails = null;
  33879. _this.bufferFlushed = false;
  33880. _this.cachedTrackLoadedData = null;
  33881. _this._registerListeners();
  33882. return _this;
  33883. }
  33884. var _proto = AudioStreamController.prototype;
  33885. _proto.onHandlerDestroying = function onHandlerDestroying() {
  33886. this._unregisterListeners();
  33887. this.mainDetails = null;
  33888. };
  33889. _proto._registerListeners = function _registerListeners() {
  33890. var hls = this.hls;
  33891. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  33892. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  33893. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  33894. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  33895. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
  33896. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
  33897. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
  33898. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, this.onError, this);
  33899. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_RESET, this.onBufferReset, this);
  33900. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_CREATED, this.onBufferCreated, this);
  33901. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_FLUSHED, this.onBufferFlushed, this);
  33902. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
  33903. hls.on(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  33904. };
  33905. _proto._unregisterListeners = function _unregisterListeners() {
  33906. var hls = this.hls;
  33907. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  33908. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  33909. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  33910. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  33911. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACKS_UPDATED, this.onAudioTracksUpdated, this);
  33912. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
  33913. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
  33914. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, this.onError, this);
  33915. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_RESET, this.onBufferReset, this);
  33916. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_CREATED, this.onBufferCreated, this);
  33917. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_FLUSHED, this.onBufferFlushed, this);
  33918. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
  33919. hls.off(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  33920. }
  33921. // INIT_PTS_FOUND is triggered when the video track parsed in the stream-controller has a new PTS value
  33922. ;
  33923. _proto.onInitPtsFound = function onInitPtsFound(event, _ref) {
  33924. var frag = _ref.frag,
  33925. id = _ref.id,
  33926. initPTS = _ref.initPTS;
  33927. // Always update the new INIT PTS
  33928. // Can change due level switch
  33929. if (id === 'main') {
  33930. var cc = frag.cc;
  33931. this.initPTS[frag.cc] = initPTS;
  33932. this.log("InitPTS for cc: " + cc + " found from main: " + initPTS);
  33933. this.videoTrackCC = cc;
  33934. // If we are waiting, tick immediately to unblock audio fragment transmuxing
  33935. if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS) {
  33936. this.tick();
  33937. }
  33938. }
  33939. };
  33940. _proto.startLoad = function startLoad(startPosition) {
  33941. if (!this.levels) {
  33942. this.startPosition = startPosition;
  33943. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED;
  33944. return;
  33945. }
  33946. var lastCurrentTime = this.lastCurrentTime;
  33947. this.stopLoad();
  33948. this.setInterval(TICK_INTERVAL);
  33949. this.fragLoadError = 0;
  33950. if (lastCurrentTime > 0 && startPosition === -1) {
  33951. this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3));
  33952. startPosition = lastCurrentTime;
  33953. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  33954. } else {
  33955. this.loadedmetadata = false;
  33956. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK;
  33957. }
  33958. this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition;
  33959. this.tick();
  33960. };
  33961. _proto.doTick = function doTick() {
  33962. switch (this.state) {
  33963. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE:
  33964. this.doTickIdle();
  33965. break;
  33966. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK:
  33967. {
  33968. var _levels$trackId;
  33969. var levels = this.levels,
  33970. trackId = this.trackId;
  33971. var details = levels === null || levels === void 0 ? void 0 : (_levels$trackId = levels[trackId]) === null || _levels$trackId === void 0 ? void 0 : _levels$trackId.details;
  33972. if (details) {
  33973. if (this.waitForCdnTuneIn(details)) {
  33974. break;
  33975. }
  33976. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS;
  33977. }
  33978. break;
  33979. }
  33980. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY:
  33981. {
  33982. var _this$media;
  33983. var now = performance.now();
  33984. var retryDate = this.retryDate;
  33985. // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
  33986. if (!retryDate || now >= retryDate || (_this$media = this.media) !== null && _this$media !== void 0 && _this$media.seeking) {
  33987. this.log('RetryDate reached, switch back to IDLE state');
  33988. this.resetStartWhenNotLoaded(this.trackId);
  33989. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  33990. }
  33991. break;
  33992. }
  33993. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS:
  33994. {
  33995. // Ensure we don't get stuck in the WAITING_INIT_PTS state if the waiting frag CC doesn't match any initPTS
  33996. var waitingData = this.waitingData;
  33997. if (waitingData) {
  33998. var frag = waitingData.frag,
  33999. part = waitingData.part,
  34000. cache = waitingData.cache,
  34001. complete = waitingData.complete;
  34002. if (this.initPTS[frag.cc] !== undefined) {
  34003. this.waitingData = null;
  34004. this.waitingVideoCC = -1;
  34005. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING;
  34006. var payload = cache.flush();
  34007. var data = {
  34008. frag: frag,
  34009. part: part,
  34010. payload: payload,
  34011. networkDetails: null
  34012. };
  34013. this._handleFragmentLoadProgress(data);
  34014. if (complete) {
  34015. _BaseStreamController.prototype._handleFragmentLoadComplete.call(this, data);
  34016. }
  34017. } else if (this.videoTrackCC !== this.waitingVideoCC) {
  34018. // Drop waiting fragment if videoTrackCC has changed since waitingFragment was set and initPTS was not found
  34019. this.log("Waiting fragment cc (" + frag.cc + ") cancelled because video is at cc " + this.videoTrackCC);
  34020. this.clearWaitingFragment();
  34021. } else {
  34022. // Drop waiting fragment if an earlier fragment is needed
  34023. var pos = this.getLoadPosition();
  34024. var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(this.mediaBuffer, pos, this.config.maxBufferHole);
  34025. var waitingFragmentAtPosition = (0,_fragment_finders__WEBPACK_IMPORTED_MODULE_11__.fragmentWithinToleranceTest)(bufferInfo.end, this.config.maxFragLookUpTolerance, frag);
  34026. if (waitingFragmentAtPosition < 0) {
  34027. this.log("Waiting fragment cc (" + frag.cc + ") @ " + frag.start + " cancelled because another fragment at " + bufferInfo.end + " is needed");
  34028. this.clearWaitingFragment();
  34029. }
  34030. }
  34031. } else {
  34032. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  34033. }
  34034. }
  34035. }
  34036. this.onTickEnd();
  34037. };
  34038. _proto.clearWaitingFragment = function clearWaitingFragment() {
  34039. var waitingData = this.waitingData;
  34040. if (waitingData) {
  34041. this.fragmentTracker.removeFragment(waitingData.frag);
  34042. this.waitingData = null;
  34043. this.waitingVideoCC = -1;
  34044. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  34045. }
  34046. };
  34047. _proto.resetLoadingState = function resetLoadingState() {
  34048. this.clearWaitingFragment();
  34049. _BaseStreamController.prototype.resetLoadingState.call(this);
  34050. };
  34051. _proto.onTickEnd = function onTickEnd() {
  34052. var media = this.media;
  34053. if (!media || !media.readyState) {
  34054. // Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0)
  34055. return;
  34056. }
  34057. this.lastCurrentTime = media.currentTime;
  34058. };
  34059. _proto.doTickIdle = function doTickIdle() {
  34060. var hls = this.hls,
  34061. levels = this.levels,
  34062. media = this.media,
  34063. trackId = this.trackId;
  34064. var config = hls.config;
  34065. if (!levels || !levels[trackId]) {
  34066. return;
  34067. }
  34068. // if video not attached AND
  34069. // start fragment already requested OR start frag prefetch not enabled
  34070. // exit loop
  34071. // => if media not attached but start frag prefetch is enabled and start frag not requested yet, we will not exit loop
  34072. if (!media && (this.startFragRequested || !config.startFragPrefetch)) {
  34073. return;
  34074. }
  34075. var levelInfo = levels[trackId];
  34076. var trackDetails = levelInfo.details;
  34077. if (!trackDetails || trackDetails.live && this.levelLastLoaded !== trackId || this.waitForCdnTuneIn(trackDetails)) {
  34078. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK;
  34079. return;
  34080. }
  34081. var bufferable = this.mediaBuffer ? this.mediaBuffer : this.media;
  34082. if (this.bufferFlushed && bufferable) {
  34083. this.bufferFlushed = false;
  34084. this.afterBufferFlushed(bufferable, _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO);
  34085. }
  34086. var bufferInfo = this.getFwdBufferInfo(bufferable, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO);
  34087. if (bufferInfo === null) {
  34088. return;
  34089. }
  34090. var audioSwitch = this.audioSwitch;
  34091. if (!audioSwitch && this._streamEnded(bufferInfo, trackDetails)) {
  34092. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_EOS, {
  34093. type: 'audio'
  34094. });
  34095. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ENDED;
  34096. return;
  34097. }
  34098. var mainBufferInfo = this.getFwdBufferInfo(this.videoBuffer ? this.videoBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  34099. var bufferLen = bufferInfo.len;
  34100. var maxBufLen = this.getMaxBufferLength(mainBufferInfo === null || mainBufferInfo === void 0 ? void 0 : mainBufferInfo.len);
  34101. // if buffer length is less than maxBufLen try to load a new fragment
  34102. if (bufferLen >= maxBufLen && !audioSwitch) {
  34103. return;
  34104. }
  34105. var fragments = trackDetails.fragments;
  34106. var start = fragments[0].start;
  34107. var targetBufferTime = bufferInfo.end;
  34108. if (audioSwitch && media) {
  34109. var pos = this.getLoadPosition();
  34110. targetBufferTime = pos;
  34111. // if currentTime (pos) is less than alt audio playlist start time, it means that alt audio is ahead of currentTime
  34112. if (trackDetails.PTSKnown && pos < start) {
  34113. // if everything is buffered from pos to start or if audio buffer upfront, let's seek to start
  34114. if (bufferInfo.end > start || bufferInfo.nextStart) {
  34115. this.log('Alt audio track ahead of main track, seek to start of alt audio track');
  34116. media.currentTime = start + 0.05;
  34117. }
  34118. }
  34119. }
  34120. // buffer audio up to one target duration ahead of main buffer
  34121. if (mainBufferInfo && targetBufferTime > mainBufferInfo.end + trackDetails.targetduration) {
  34122. return;
  34123. }
  34124. // wait for main buffer after buffing some audio
  34125. if ((!mainBufferInfo || !mainBufferInfo.len) && bufferInfo.len) {
  34126. return;
  34127. }
  34128. var frag = this.getNextFragment(targetBufferTime, trackDetails);
  34129. if (!frag) {
  34130. this.bufferFlushed = true;
  34131. return;
  34132. }
  34133. this.loadFragment(frag, trackDetails, targetBufferTime);
  34134. };
  34135. _proto.getMaxBufferLength = function getMaxBufferLength(mainBufferLength) {
  34136. var maxConfigBuffer = _BaseStreamController.prototype.getMaxBufferLength.call(this);
  34137. if (!mainBufferLength) {
  34138. return maxConfigBuffer;
  34139. }
  34140. return Math.max(maxConfigBuffer, mainBufferLength);
  34141. };
  34142. _proto.onMediaDetaching = function onMediaDetaching() {
  34143. this.videoBuffer = null;
  34144. _BaseStreamController.prototype.onMediaDetaching.call(this);
  34145. };
  34146. _proto.onAudioTracksUpdated = function onAudioTracksUpdated(event, _ref2) {
  34147. var audioTracks = _ref2.audioTracks;
  34148. this.resetTransmuxer();
  34149. this.levels = audioTracks.map(function (mediaPlaylist) {
  34150. return new _types_level__WEBPACK_IMPORTED_MODULE_5__.Level(mediaPlaylist);
  34151. });
  34152. };
  34153. _proto.onAudioTrackSwitching = function onAudioTrackSwitching(event, data) {
  34154. // if any URL found on new audio track, it is an alternate audio track
  34155. var altAudio = !!data.url;
  34156. this.trackId = data.id;
  34157. var fragCurrent = this.fragCurrent;
  34158. if (fragCurrent) {
  34159. fragCurrent.abortRequests();
  34160. }
  34161. this.fragCurrent = null;
  34162. this.clearWaitingFragment();
  34163. // destroy useless transmuxer when switching audio to main
  34164. if (!altAudio) {
  34165. this.resetTransmuxer();
  34166. } else {
  34167. // switching to audio track, start timer if not already started
  34168. this.setInterval(TICK_INTERVAL);
  34169. }
  34170. // should we switch tracks ?
  34171. if (altAudio) {
  34172. this.audioSwitch = true;
  34173. // main audio track are handled by stream-controller, just do something if switching to alt audio track
  34174. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  34175. } else {
  34176. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED;
  34177. }
  34178. this.tick();
  34179. };
  34180. _proto.onManifestLoading = function onManifestLoading() {
  34181. this.mainDetails = null;
  34182. this.fragmentTracker.removeAllFragments();
  34183. this.startPosition = this.lastCurrentTime = 0;
  34184. this.bufferFlushed = false;
  34185. };
  34186. _proto.onLevelLoaded = function onLevelLoaded(event, data) {
  34187. this.mainDetails = data.details;
  34188. if (this.cachedTrackLoadedData !== null) {
  34189. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_LOADED, this.cachedTrackLoadedData);
  34190. this.cachedTrackLoadedData = null;
  34191. }
  34192. };
  34193. _proto.onAudioTrackLoaded = function onAudioTrackLoaded(event, data) {
  34194. var _track$details;
  34195. if (this.mainDetails == null) {
  34196. this.cachedTrackLoadedData = data;
  34197. return;
  34198. }
  34199. var levels = this.levels;
  34200. var newDetails = data.details,
  34201. trackId = data.id;
  34202. if (!levels) {
  34203. this.warn("Audio tracks were reset while loading level " + trackId);
  34204. return;
  34205. }
  34206. this.log("Track " + trackId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "],duration:" + newDetails.totalduration);
  34207. var track = levels[trackId];
  34208. var sliding = 0;
  34209. if (newDetails.live || (_track$details = track.details) !== null && _track$details !== void 0 && _track$details.live) {
  34210. var mainDetails = this.mainDetails;
  34211. if (!newDetails.fragments[0]) {
  34212. newDetails.deltaUpdateFailed = true;
  34213. }
  34214. if (newDetails.deltaUpdateFailed || !mainDetails) {
  34215. return;
  34216. }
  34217. if (!track.details && newDetails.hasProgramDateTime && mainDetails.hasProgramDateTime) {
  34218. // Make sure our audio rendition is aligned with the "main" rendition, using
  34219. // pdt as our reference times.
  34220. (0,_utils_discontinuities__WEBPACK_IMPORTED_MODULE_12__.alignMediaPlaylistByPDT)(newDetails, mainDetails);
  34221. sliding = newDetails.fragments[0].start;
  34222. } else {
  34223. sliding = this.alignPlaylists(newDetails, track.details);
  34224. }
  34225. }
  34226. track.details = newDetails;
  34227. this.levelLastLoaded = trackId;
  34228. // compute start position if we are aligned with the main playlist
  34229. if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) {
  34230. this.setStartPosition(track.details, sliding);
  34231. }
  34232. // only switch back to IDLE state if we were waiting for track to start downloading a new fragment
  34233. if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_TRACK && !this.waitForCdnTuneIn(newDetails)) {
  34234. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  34235. }
  34236. // trigger handler right now
  34237. this.tick();
  34238. };
  34239. _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(data) {
  34240. var _frag$initSegment;
  34241. var frag = data.frag,
  34242. part = data.part,
  34243. payload = data.payload;
  34244. var config = this.config,
  34245. trackId = this.trackId,
  34246. levels = this.levels;
  34247. if (!levels) {
  34248. this.warn("Audio tracks were reset while fragment load was in progress. Fragment " + frag.sn + " of level " + frag.level + " will not be buffered");
  34249. return;
  34250. }
  34251. var track = levels[trackId];
  34252. console.assert(track, 'Audio track is defined on fragment load progress');
  34253. var details = track.details;
  34254. console.assert(details, 'Audio track details are defined on fragment load progress');
  34255. var audioCodec = config.defaultAudioCodec || track.audioCodec || 'mp4a.40.2';
  34256. var transmuxer = this.transmuxer;
  34257. if (!transmuxer) {
  34258. transmuxer = this.transmuxer = new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_9__["default"](this.hls, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this));
  34259. }
  34260. // Check if we have video initPTS
  34261. // If not we need to wait for it
  34262. var initPTS = this.initPTS[frag.cc];
  34263. var initSegmentData = (_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.data;
  34264. if (initPTS !== undefined) {
  34265. // this.log(`Transmuxing ${sn} of [${details.startSN} ,${details.endSN}],track ${trackId}`);
  34266. // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live)
  34267. var accurateTimeOffset = false; // details.PTSKnown || !details.live;
  34268. var partIndex = part ? part.index : -1;
  34269. var partial = partIndex !== -1;
  34270. var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_10__.ChunkMetadata(frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial);
  34271. transmuxer.push(payload, initSegmentData, audioCodec, '', frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS);
  34272. } else {
  34273. this.log("Unknown video PTS for cc " + frag.cc + ", waiting for video PTS before demuxing audio frag " + frag.sn + " of [" + details.startSN + " ," + details.endSN + "],track " + trackId);
  34274. var _this$waitingData = this.waitingData = this.waitingData || {
  34275. frag: frag,
  34276. part: part,
  34277. cache: new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_8__["default"](),
  34278. complete: false
  34279. },
  34280. cache = _this$waitingData.cache;
  34281. cache.push(new Uint8Array(payload));
  34282. this.waitingVideoCC = this.videoTrackCC;
  34283. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS;
  34284. }
  34285. };
  34286. _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedData) {
  34287. if (this.waitingData) {
  34288. this.waitingData.complete = true;
  34289. return;
  34290. }
  34291. _BaseStreamController.prototype._handleFragmentLoadComplete.call(this, fragLoadedData);
  34292. };
  34293. _proto.onBufferReset = function onBufferReset( /* event: Events.BUFFER_RESET */
  34294. ) {
  34295. // reset reference to sourcebuffers
  34296. this.mediaBuffer = this.videoBuffer = null;
  34297. this.loadedmetadata = false;
  34298. };
  34299. _proto.onBufferCreated = function onBufferCreated(event, data) {
  34300. var audioTrack = data.tracks.audio;
  34301. if (audioTrack) {
  34302. this.mediaBuffer = audioTrack.buffer || null;
  34303. }
  34304. if (data.tracks.video) {
  34305. this.videoBuffer = data.tracks.video.buffer || null;
  34306. }
  34307. };
  34308. _proto.onFragBuffered = function onFragBuffered(event, data) {
  34309. var frag = data.frag,
  34310. part = data.part;
  34311. if (frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO) {
  34312. if (!this.loadedmetadata && frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN) {
  34313. var _ref3;
  34314. if ((_ref3 = this.videoBuffer || this.media) !== null && _ref3 !== void 0 && _ref3.buffered.length) {
  34315. this.loadedmetadata = true;
  34316. }
  34317. }
  34318. return;
  34319. }
  34320. if (this.fragContextChanged(frag)) {
  34321. // If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion
  34322. // Avoid setting state back to IDLE or concluding the audio switch; otherwise, the switched-to track will not buffer
  34323. this.warn("Fragment " + frag.sn + (part ? ' p: ' + part.index : '') + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state + ", audioSwitch: " + this.audioSwitch);
  34324. return;
  34325. }
  34326. if (frag.sn !== 'initSegment') {
  34327. this.fragPrevious = frag;
  34328. if (this.audioSwitch) {
  34329. this.audioSwitch = false;
  34330. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHED, {
  34331. id: this.trackId
  34332. });
  34333. }
  34334. }
  34335. this.fragBufferedComplete(frag, part);
  34336. };
  34337. _proto.onError = function onError(event, data) {
  34338. if (data.type === _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorTypes.KEY_SYSTEM_ERROR) {
  34339. this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO, data);
  34340. return;
  34341. }
  34342. switch (data.details) {
  34343. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.FRAG_LOAD_ERROR:
  34344. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.FRAG_LOAD_TIMEOUT:
  34345. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.FRAG_PARSING_ERROR:
  34346. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.KEY_LOAD_ERROR:
  34347. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.KEY_LOAD_TIMEOUT:
  34348. // TODO: Skip fragments that do not belong to this.fragCurrent audio-group id
  34349. this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO, data);
  34350. break;
  34351. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.AUDIO_TRACK_LOAD_ERROR:
  34352. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT:
  34353. // when in ERROR state, don't switch back to IDLE state in case a non-fatal error is received
  34354. if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR && this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED) {
  34355. // if fatal error, stop processing, otherwise move to IDLE to retry loading
  34356. this.state = data.fatal ? _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR : _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  34357. this.warn(data.details + " while loading frag, switching to " + this.state + " state");
  34358. }
  34359. break;
  34360. case _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.BUFFER_FULL_ERROR:
  34361. // if in appending state
  34362. if (data.parent === 'audio' && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED)) {
  34363. var flushBuffer = true;
  34364. var bufferedInfo = this.getFwdBufferInfo(this.mediaBuffer, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO);
  34365. // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
  34366. // reduce max buf len if current position is buffered
  34367. if (bufferedInfo && bufferedInfo.len > 0.5) {
  34368. flushBuffer = !this.reduceMaxBufferLength(bufferedInfo.len);
  34369. }
  34370. if (flushBuffer) {
  34371. // current position is not buffered, but browser is still complaining about buffer full error
  34372. // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
  34373. // in that case flush the whole audio buffer to recover
  34374. this.warn('Buffer full error also media.currentTime is not buffered, flush audio buffer');
  34375. this.fragCurrent = null;
  34376. _BaseStreamController.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, 'audio');
  34377. }
  34378. this.resetLoadingState();
  34379. }
  34380. break;
  34381. default:
  34382. break;
  34383. }
  34384. };
  34385. _proto.onBufferFlushed = function onBufferFlushed(event, _ref4) {
  34386. var type = _ref4.type;
  34387. if (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO) {
  34388. this.bufferFlushed = true;
  34389. if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ENDED) {
  34390. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  34391. }
  34392. }
  34393. };
  34394. _proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) {
  34395. var _id3$samples;
  34396. var id = 'audio';
  34397. var hls = this.hls;
  34398. var remuxResult = transmuxResult.remuxResult,
  34399. chunkMeta = transmuxResult.chunkMeta;
  34400. var context = this.getCurrentContext(chunkMeta);
  34401. if (!context) {
  34402. this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered.");
  34403. this.resetStartWhenNotLoaded(chunkMeta.level);
  34404. return;
  34405. }
  34406. var frag = context.frag,
  34407. part = context.part,
  34408. details = context.level.details;
  34409. var audio = remuxResult.audio,
  34410. text = remuxResult.text,
  34411. id3 = remuxResult.id3,
  34412. initSegment = remuxResult.initSegment;
  34413. // Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level.
  34414. // If we are, subsequently check if the currently loading fragment (fragCurrent) has changed.
  34415. if (this.fragContextChanged(frag) || !details) {
  34416. return;
  34417. }
  34418. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING;
  34419. if (this.audioSwitch && audio) {
  34420. this.completeAudioSwitch();
  34421. }
  34422. if (initSegment !== null && initSegment !== void 0 && initSegment.tracks) {
  34423. this._bufferInitSegment(initSegment.tracks, frag, chunkMeta);
  34424. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_PARSING_INIT_SEGMENT, {
  34425. frag: frag,
  34426. id: id,
  34427. tracks: initSegment.tracks
  34428. });
  34429. // Only flush audio from old audio tracks when PTS is known on new audio track
  34430. }
  34431. if (audio) {
  34432. var startPTS = audio.startPTS,
  34433. endPTS = audio.endPTS,
  34434. startDTS = audio.startDTS,
  34435. endDTS = audio.endDTS;
  34436. if (part) {
  34437. part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO] = {
  34438. startPTS: startPTS,
  34439. endPTS: endPTS,
  34440. startDTS: startDTS,
  34441. endDTS: endDTS
  34442. };
  34443. }
  34444. frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO, startPTS, endPTS, startDTS, endDTS);
  34445. this.bufferFragmentData(audio, frag, part, chunkMeta);
  34446. }
  34447. if (id3 !== null && id3 !== void 0 && (_id3$samples = id3.samples) !== null && _id3$samples !== void 0 && _id3$samples.length) {
  34448. var emittedID3 = _extends({
  34449. id: id,
  34450. frag: frag,
  34451. details: details
  34452. }, id3);
  34453. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_PARSING_METADATA, emittedID3);
  34454. }
  34455. if (text) {
  34456. var emittedText = _extends({
  34457. id: id,
  34458. frag: frag,
  34459. details: details
  34460. }, text);
  34461. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.FRAG_PARSING_USERDATA, emittedText);
  34462. }
  34463. };
  34464. _proto._bufferInitSegment = function _bufferInitSegment(tracks, frag, chunkMeta) {
  34465. if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING) {
  34466. return;
  34467. }
  34468. // delete any video track found on audio transmuxer
  34469. if (tracks.video) {
  34470. delete tracks.video;
  34471. }
  34472. // include levelCodec in audio and video tracks
  34473. var track = tracks.audio;
  34474. if (!track) {
  34475. return;
  34476. }
  34477. track.levelCodec = track.codec;
  34478. track.id = 'audio';
  34479. this.log("Init audio buffer, container:" + track.container + ", codecs[parsed]=[" + track.codec + "]");
  34480. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_CODECS, tracks);
  34481. var initSegment = track.initSegment;
  34482. if (initSegment !== null && initSegment !== void 0 && initSegment.byteLength) {
  34483. var segment = {
  34484. type: 'audio',
  34485. frag: frag,
  34486. part: null,
  34487. chunkMeta: chunkMeta,
  34488. parent: frag.type,
  34489. data: initSegment
  34490. };
  34491. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.BUFFER_APPENDING, segment);
  34492. }
  34493. // trigger handler right now
  34494. this.tick();
  34495. };
  34496. _proto.loadFragment = function loadFragment(frag, trackDetails, targetBufferTime) {
  34497. // only load if fragment is not loaded or if in audio switch
  34498. var fragState = this.fragmentTracker.getState(frag);
  34499. this.fragCurrent = frag;
  34500. // we force a frag loading in audio switch as fragment tracker might not have evicted previous frags in case of quick audio switch
  34501. if (this.audioSwitch || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__.FragmentState.NOT_LOADED || fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_4__.FragmentState.PARTIAL) {
  34502. if (frag.sn === 'initSegment') {
  34503. this._loadInitSegment(frag, trackDetails);
  34504. } else if (trackDetails.live && !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.initPTS[frag.cc])) {
  34505. this.log("Waiting for video PTS in continuity counter " + frag.cc + " of live stream before loading audio fragment " + frag.sn + " of level " + this.trackId);
  34506. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_INIT_PTS;
  34507. } else {
  34508. this.startFragRequested = true;
  34509. _BaseStreamController.prototype.loadFragment.call(this, frag, trackDetails, targetBufferTime);
  34510. }
  34511. }
  34512. };
  34513. _proto.completeAudioSwitch = function completeAudioSwitch() {
  34514. var hls = this.hls,
  34515. media = this.media,
  34516. trackId = this.trackId;
  34517. if (media) {
  34518. this.log('Switching audio track : flushing all audio');
  34519. _BaseStreamController.prototype.flushMainBuffer.call(this, 0, Number.POSITIVE_INFINITY, 'audio');
  34520. }
  34521. this.audioSwitch = false;
  34522. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.AUDIO_TRACK_SWITCHED, {
  34523. id: trackId
  34524. });
  34525. };
  34526. return AudioStreamController;
  34527. }(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]);
  34528. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AudioStreamController);
  34529. /***/ }),
  34530. /***/ "./src/controller/audio-track-controller.ts":
  34531. /*!**************************************************!*\
  34532. !*** ./src/controller/audio-track-controller.ts ***!
  34533. \**************************************************/
  34534. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  34535. "use strict";
  34536. __webpack_require__.r(__webpack_exports__);
  34537. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  34538. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  34539. /* harmony export */ });
  34540. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  34541. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  34542. /* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts");
  34543. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  34544. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  34545. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  34546. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  34547. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  34548. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  34549. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  34550. var AudioTrackController = /*#__PURE__*/function (_BasePlaylistControll) {
  34551. _inheritsLoose(AudioTrackController, _BasePlaylistControll);
  34552. function AudioTrackController(hls) {
  34553. var _this;
  34554. _this = _BasePlaylistControll.call(this, hls, '[audio-track-controller]') || this;
  34555. _this.tracks = [];
  34556. _this.groupId = null;
  34557. _this.tracksInGroup = [];
  34558. _this.trackId = -1;
  34559. _this.trackName = '';
  34560. _this.selectDefaultTrack = true;
  34561. _this.registerListeners();
  34562. return _this;
  34563. }
  34564. var _proto = AudioTrackController.prototype;
  34565. _proto.registerListeners = function registerListeners() {
  34566. var hls = this.hls;
  34567. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  34568. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  34569. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  34570. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING, this.onLevelSwitching, this);
  34571. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
  34572. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, this.onError, this);
  34573. };
  34574. _proto.unregisterListeners = function unregisterListeners() {
  34575. var hls = this.hls;
  34576. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  34577. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  34578. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  34579. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING, this.onLevelSwitching, this);
  34580. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_LOADED, this.onAudioTrackLoaded, this);
  34581. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, this.onError, this);
  34582. };
  34583. _proto.destroy = function destroy() {
  34584. this.unregisterListeners();
  34585. this.tracks.length = 0;
  34586. this.tracksInGroup.length = 0;
  34587. _BasePlaylistControll.prototype.destroy.call(this);
  34588. };
  34589. _proto.onManifestLoading = function onManifestLoading() {
  34590. this.tracks = [];
  34591. this.groupId = null;
  34592. this.tracksInGroup = [];
  34593. this.trackId = -1;
  34594. this.trackName = '';
  34595. this.selectDefaultTrack = true;
  34596. };
  34597. _proto.onManifestParsed = function onManifestParsed(event, data) {
  34598. this.tracks = data.audioTracks || [];
  34599. };
  34600. _proto.onAudioTrackLoaded = function onAudioTrackLoaded(event, data) {
  34601. var id = data.id,
  34602. details = data.details;
  34603. var currentTrack = this.tracksInGroup[id];
  34604. if (!currentTrack) {
  34605. this.warn("Invalid audio track id " + id);
  34606. return;
  34607. }
  34608. var curDetails = currentTrack.details;
  34609. currentTrack.details = data.details;
  34610. this.log("audioTrack " + id + " loaded [" + details.startSN + "-" + details.endSN + "]");
  34611. if (id === this.trackId) {
  34612. this.retryCount = 0;
  34613. this.playlistLoaded(id, data, curDetails);
  34614. }
  34615. };
  34616. _proto.onLevelLoading = function onLevelLoading(event, data) {
  34617. this.switchLevel(data.level);
  34618. };
  34619. _proto.onLevelSwitching = function onLevelSwitching(event, data) {
  34620. this.switchLevel(data.level);
  34621. };
  34622. _proto.switchLevel = function switchLevel(levelIndex) {
  34623. var levelInfo = this.hls.levels[levelIndex];
  34624. if (!(levelInfo !== null && levelInfo !== void 0 && levelInfo.audioGroupIds)) {
  34625. return;
  34626. }
  34627. var audioGroupId = levelInfo.audioGroupIds[levelInfo.urlId];
  34628. if (this.groupId !== audioGroupId) {
  34629. this.groupId = audioGroupId;
  34630. var audioTracks = this.tracks.filter(function (track) {
  34631. return !audioGroupId || track.groupId === audioGroupId;
  34632. });
  34633. // Disable selectDefaultTrack if there are no default tracks
  34634. if (this.selectDefaultTrack && !audioTracks.some(function (track) {
  34635. return track.default;
  34636. })) {
  34637. this.selectDefaultTrack = false;
  34638. }
  34639. this.tracksInGroup = audioTracks;
  34640. var audioTracksUpdated = {
  34641. audioTracks: audioTracks
  34642. };
  34643. this.log("Updating audio tracks, " + audioTracks.length + " track(s) found in \"" + audioGroupId + "\" group-id");
  34644. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACKS_UPDATED, audioTracksUpdated);
  34645. this.selectInitialTrack();
  34646. }
  34647. };
  34648. _proto.onError = function onError(event, data) {
  34649. _BasePlaylistControll.prototype.onError.call(this, event, data);
  34650. if (data.fatal || !data.context) {
  34651. return;
  34652. }
  34653. if (data.context.type === _types_loader__WEBPACK_IMPORTED_MODULE_3__.PlaylistContextType.AUDIO_TRACK && data.context.id === this.trackId && data.context.groupId === this.groupId) {
  34654. this.retryLoadingOrFail(data);
  34655. }
  34656. };
  34657. _proto.setAudioTrack = function setAudioTrack(newId) {
  34658. var tracks = this.tracksInGroup;
  34659. // check if level idx is valid
  34660. if (newId < 0 || newId >= tracks.length) {
  34661. this.warn('Invalid id passed to audio-track controller');
  34662. return;
  34663. }
  34664. // stopping live reloading timer if any
  34665. this.clearTimer();
  34666. var lastTrack = tracks[this.trackId];
  34667. this.log("Now switching to audio-track index " + newId);
  34668. var track = tracks[newId];
  34669. var id = track.id,
  34670. _track$groupId = track.groupId,
  34671. groupId = _track$groupId === void 0 ? '' : _track$groupId,
  34672. name = track.name,
  34673. type = track.type,
  34674. url = track.url;
  34675. this.trackId = newId;
  34676. this.trackName = name;
  34677. this.selectDefaultTrack = false;
  34678. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_SWITCHING, {
  34679. id: id,
  34680. groupId: groupId,
  34681. name: name,
  34682. type: type,
  34683. url: url
  34684. });
  34685. // Do not reload track unless live
  34686. if (track.details && !track.details.live) {
  34687. return;
  34688. }
  34689. var hlsUrlParameters = this.switchParams(track.url, lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.details);
  34690. this.loadPlaylist(hlsUrlParameters);
  34691. };
  34692. _proto.selectInitialTrack = function selectInitialTrack() {
  34693. var audioTracks = this.tracksInGroup;
  34694. console.assert(audioTracks.length, 'Initial audio track should be selected when tracks are known');
  34695. var currentAudioTrackName = this.trackName;
  34696. var trackId = this.findTrackId(currentAudioTrackName) || this.findTrackId();
  34697. if (trackId !== -1) {
  34698. this.setAudioTrack(trackId);
  34699. } else {
  34700. this.warn("No track found for running audio group-ID: " + this.groupId);
  34701. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, {
  34702. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  34703. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.AUDIO_TRACK_LOAD_ERROR,
  34704. fatal: true
  34705. });
  34706. }
  34707. };
  34708. _proto.findTrackId = function findTrackId(name) {
  34709. var audioTracks = this.tracksInGroup;
  34710. for (var i = 0; i < audioTracks.length; i++) {
  34711. var track = audioTracks[i];
  34712. if (!this.selectDefaultTrack || track.default) {
  34713. if (!name || name === track.name) {
  34714. return track.id;
  34715. }
  34716. }
  34717. }
  34718. return -1;
  34719. };
  34720. _proto.loadPlaylist = function loadPlaylist(hlsUrlParameters) {
  34721. _BasePlaylistControll.prototype.loadPlaylist.call(this);
  34722. var audioTrack = this.tracksInGroup[this.trackId];
  34723. if (this.shouldLoadTrack(audioTrack)) {
  34724. var id = audioTrack.id;
  34725. var groupId = audioTrack.groupId;
  34726. var url = audioTrack.url;
  34727. if (hlsUrlParameters) {
  34728. try {
  34729. url = hlsUrlParameters.addDirectives(url);
  34730. } catch (error) {
  34731. this.warn("Could not construct new URL with HLS Delivery Directives: " + error);
  34732. }
  34733. }
  34734. // track not retrieved yet, or live playlist we need to (re)load it
  34735. this.log("loading audio-track playlist for id: " + id);
  34736. this.clearTimer();
  34737. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.AUDIO_TRACK_LOADING, {
  34738. url: url,
  34739. id: id,
  34740. groupId: groupId,
  34741. deliveryDirectives: hlsUrlParameters || null
  34742. });
  34743. }
  34744. };
  34745. _createClass(AudioTrackController, [{
  34746. key: "audioTracks",
  34747. get: function get() {
  34748. return this.tracksInGroup;
  34749. }
  34750. }, {
  34751. key: "audioTrack",
  34752. get: function get() {
  34753. return this.trackId;
  34754. },
  34755. set: function set(newId) {
  34756. // If audio track is selected from API then don't choose from the manifest default track
  34757. this.selectDefaultTrack = false;
  34758. this.setAudioTrack(newId);
  34759. }
  34760. }]);
  34761. return AudioTrackController;
  34762. }(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]);
  34763. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AudioTrackController);
  34764. /***/ }),
  34765. /***/ "./src/controller/base-playlist-controller.ts":
  34766. /*!****************************************************!*\
  34767. !*** ./src/controller/base-playlist-controller.ts ***!
  34768. \****************************************************/
  34769. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  34770. "use strict";
  34771. __webpack_require__.r(__webpack_exports__);
  34772. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  34773. /* harmony export */ "default": () => (/* binding */ BasePlaylistController)
  34774. /* harmony export */ });
  34775. /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts");
  34776. /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts");
  34777. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  34778. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  34779. var BasePlaylistController = /*#__PURE__*/function () {
  34780. function BasePlaylistController(hls, logPrefix) {
  34781. this.hls = void 0;
  34782. this.timer = -1;
  34783. this.requestScheduled = -1;
  34784. this.canLoad = false;
  34785. this.retryCount = 0;
  34786. this.log = void 0;
  34787. this.warn = void 0;
  34788. this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger, logPrefix + ":");
  34789. this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger, logPrefix + ":");
  34790. this.hls = hls;
  34791. }
  34792. var _proto = BasePlaylistController.prototype;
  34793. _proto.destroy = function destroy() {
  34794. this.clearTimer();
  34795. // @ts-ignore
  34796. this.hls = this.log = this.warn = null;
  34797. };
  34798. _proto.onError = function onError(event, data) {
  34799. if (data.fatal && (data.type === _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.NETWORK_ERROR || data.type === _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.KEY_SYSTEM_ERROR)) {
  34800. this.stopLoad();
  34801. }
  34802. };
  34803. _proto.clearTimer = function clearTimer() {
  34804. clearTimeout(this.timer);
  34805. this.timer = -1;
  34806. };
  34807. _proto.startLoad = function startLoad() {
  34808. this.canLoad = true;
  34809. this.retryCount = 0;
  34810. this.requestScheduled = -1;
  34811. this.loadPlaylist();
  34812. };
  34813. _proto.stopLoad = function stopLoad() {
  34814. this.canLoad = false;
  34815. this.clearTimer();
  34816. };
  34817. _proto.switchParams = function switchParams(playlistUri, previous) {
  34818. var renditionReports = previous === null || previous === void 0 ? void 0 : previous.renditionReports;
  34819. if (renditionReports) {
  34820. for (var i = 0; i < renditionReports.length; i++) {
  34821. var attr = renditionReports[i];
  34822. var uri = void 0;
  34823. try {
  34824. uri = new self.URL(attr.URI, previous.url).href;
  34825. } catch (error) {
  34826. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("Could not construct new URL for Rendition Report: " + error);
  34827. uri = attr.URI || '';
  34828. }
  34829. if (uri === playlistUri.slice(-uri.length)) {
  34830. var msn = parseInt(attr['LAST-MSN']) || (previous === null || previous === void 0 ? void 0 : previous.lastPartSn);
  34831. var part = parseInt(attr['LAST-PART']) || (previous === null || previous === void 0 ? void 0 : previous.lastPartIndex);
  34832. if (this.hls.config.lowLatencyMode) {
  34833. var currentGoal = Math.min(previous.age - previous.partTarget, previous.targetduration);
  34834. if (part >= 0 && currentGoal > previous.partTarget) {
  34835. part += 1;
  34836. }
  34837. }
  34838. return new _types_level__WEBPACK_IMPORTED_MODULE_0__.HlsUrlParameters(msn, part >= 0 ? part : undefined, _types_level__WEBPACK_IMPORTED_MODULE_0__.HlsSkip.No);
  34839. }
  34840. }
  34841. }
  34842. };
  34843. _proto.loadPlaylist = function loadPlaylist(hlsUrlParameters) {
  34844. if (this.requestScheduled === -1) {
  34845. this.requestScheduled = self.performance.now();
  34846. }
  34847. };
  34848. _proto.shouldLoadTrack = function shouldLoadTrack(track) {
  34849. return this.canLoad && track && !!track.url && (!track.details || track.details.live);
  34850. };
  34851. _proto.playlistLoaded = function playlistLoaded(index, data, previousDetails) {
  34852. var _this = this;
  34853. var details = data.details,
  34854. stats = data.stats;
  34855. // Set last updated date-time
  34856. var now = self.performance.now();
  34857. var elapsed = stats.loading.first ? Math.max(0, now - stats.loading.first) : 0;
  34858. details.advancedDateTime = Date.now() - elapsed;
  34859. // if current playlist is a live playlist, arm a timer to reload it
  34860. if (details.live || previousDetails !== null && previousDetails !== void 0 && previousDetails.live) {
  34861. details.reloaded(previousDetails);
  34862. if (previousDetails) {
  34863. this.log("live playlist " + index + " " + (details.advanced ? 'REFRESHED ' + details.lastPartSn + '-' + details.lastPartIndex : 'MISSED'));
  34864. }
  34865. // Merge live playlists to adjust fragment starts and fill in delta playlist skipped segments
  34866. if (previousDetails && details.fragments.length > 0) {
  34867. (0,_level_helper__WEBPACK_IMPORTED_MODULE_1__.mergeDetails)(previousDetails, details);
  34868. }
  34869. if (!this.canLoad || !details.live) {
  34870. return;
  34871. }
  34872. var deliveryDirectives;
  34873. var msn = undefined;
  34874. var part = undefined;
  34875. if (details.canBlockReload && details.endSN && details.advanced) {
  34876. // Load level with LL-HLS delivery directives
  34877. var lowLatencyMode = this.hls.config.lowLatencyMode;
  34878. var lastPartSn = details.lastPartSn;
  34879. var endSn = details.endSN;
  34880. var lastPartIndex = details.lastPartIndex;
  34881. var hasParts = lastPartIndex !== -1;
  34882. var lastPart = lastPartSn === endSn;
  34883. // When low latency mode is disabled, we'll skip part requests once the last part index is found
  34884. var nextSnStartIndex = lowLatencyMode ? 0 : lastPartIndex;
  34885. if (hasParts) {
  34886. msn = lastPart ? endSn + 1 : lastPartSn;
  34887. part = lastPart ? nextSnStartIndex : lastPartIndex + 1;
  34888. } else {
  34889. msn = endSn + 1;
  34890. }
  34891. // Low-Latency CDN Tune-in: "age" header and time since load indicates we're behind by more than one part
  34892. // Update directives to obtain the Playlist that has the estimated additional duration of media
  34893. var lastAdvanced = details.age;
  34894. var cdnAge = lastAdvanced + details.ageHeader;
  34895. var currentGoal = Math.min(cdnAge - details.partTarget, details.targetduration * 1.5);
  34896. if (currentGoal > 0) {
  34897. if (previousDetails && currentGoal > previousDetails.tuneInGoal) {
  34898. // If we attempted to get the next or latest playlist update, but currentGoal increased,
  34899. // then we either can't catchup, or the "age" header cannot be trusted.
  34900. this.warn("CDN Tune-in goal increased from: " + previousDetails.tuneInGoal + " to: " + currentGoal + " with playlist age: " + details.age);
  34901. currentGoal = 0;
  34902. } else {
  34903. var segments = Math.floor(currentGoal / details.targetduration);
  34904. msn += segments;
  34905. if (part !== undefined) {
  34906. var parts = Math.round(currentGoal % details.targetduration / details.partTarget);
  34907. part += parts;
  34908. }
  34909. this.log("CDN Tune-in age: " + details.ageHeader + "s last advanced " + lastAdvanced.toFixed(2) + "s goal: " + currentGoal + " skip sn " + segments + " to part " + part);
  34910. }
  34911. details.tuneInGoal = currentGoal;
  34912. }
  34913. deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part);
  34914. if (lowLatencyMode || !lastPart) {
  34915. this.loadPlaylist(deliveryDirectives);
  34916. return;
  34917. }
  34918. } else {
  34919. deliveryDirectives = this.getDeliveryDirectives(details, data.deliveryDirectives, msn, part);
  34920. }
  34921. var bufferInfo = this.hls.mainForwardBufferInfo;
  34922. var position = bufferInfo ? bufferInfo.end - bufferInfo.len : 0;
  34923. var distanceToLiveEdgeMs = (details.edge - position) * 1000;
  34924. var reloadInterval = (0,_level_helper__WEBPACK_IMPORTED_MODULE_1__.computeReloadInterval)(details, distanceToLiveEdgeMs);
  34925. if (!details.updated) {
  34926. this.requestScheduled = -1;
  34927. } else if (now > this.requestScheduled + reloadInterval) {
  34928. this.requestScheduled = stats.loading.start;
  34929. }
  34930. if (msn !== undefined && details.canBlockReload) {
  34931. this.requestScheduled = stats.loading.first + reloadInterval - (details.partTarget * 1000 || 1000);
  34932. } else {
  34933. this.requestScheduled = (this.requestScheduled === -1 ? now : this.requestScheduled) + reloadInterval;
  34934. }
  34935. var estimatedTimeUntilUpdate = this.requestScheduled - now;
  34936. estimatedTimeUntilUpdate = Math.max(0, estimatedTimeUntilUpdate);
  34937. this.log("reload live playlist " + index + " in " + Math.round(estimatedTimeUntilUpdate) + " ms");
  34938. // this.log(
  34939. // `live reload ${details.updated ? 'REFRESHED' : 'MISSED'}
  34940. // reload in ${estimatedTimeUntilUpdate / 1000}
  34941. // round trip ${(stats.loading.end - stats.loading.start) / 1000}
  34942. // diff ${
  34943. // (reloadInterval -
  34944. // (estimatedTimeUntilUpdate + stats.loading.end - stats.loading.start)) /
  34945. // 1000
  34946. // }
  34947. // reload interval ${reloadInterval / 1000}
  34948. // target duration ${details.targetduration}
  34949. // distance to edge ${distanceToLiveEdgeMs / 1000}`
  34950. // );
  34951. this.timer = self.setTimeout(function () {
  34952. return _this.loadPlaylist(deliveryDirectives);
  34953. }, estimatedTimeUntilUpdate);
  34954. } else {
  34955. this.clearTimer();
  34956. }
  34957. };
  34958. _proto.getDeliveryDirectives = function getDeliveryDirectives(details, previousDeliveryDirectives, msn, part) {
  34959. var skip = (0,_types_level__WEBPACK_IMPORTED_MODULE_0__.getSkipValue)(details, msn);
  34960. if (previousDeliveryDirectives !== null && previousDeliveryDirectives !== void 0 && previousDeliveryDirectives.skip && details.deltaUpdateFailed) {
  34961. msn = previousDeliveryDirectives.msn;
  34962. part = previousDeliveryDirectives.part;
  34963. skip = _types_level__WEBPACK_IMPORTED_MODULE_0__.HlsSkip.No;
  34964. }
  34965. return new _types_level__WEBPACK_IMPORTED_MODULE_0__.HlsUrlParameters(msn, part, skip);
  34966. };
  34967. _proto.retryLoadingOrFail = function retryLoadingOrFail(errorEvent) {
  34968. var _this2 = this;
  34969. var config = this.hls.config;
  34970. var retry = this.retryCount < config.levelLoadingMaxRetry;
  34971. if (retry) {
  34972. var _errorEvent$context;
  34973. this.requestScheduled = -1;
  34974. this.retryCount++;
  34975. if (errorEvent.details.indexOf('LoadTimeOut') > -1 && (_errorEvent$context = errorEvent.context) !== null && _errorEvent$context !== void 0 && _errorEvent$context.deliveryDirectives) {
  34976. // The LL-HLS request already timed out so retry immediately
  34977. this.warn("retry playlist loading #" + this.retryCount + " after \"" + errorEvent.details + "\"");
  34978. this.loadPlaylist();
  34979. } else {
  34980. // exponential backoff capped to max retry timeout
  34981. var delay = Math.min(Math.pow(2, this.retryCount) * config.levelLoadingRetryDelay, config.levelLoadingMaxRetryTimeout);
  34982. // Schedule level/track reload
  34983. this.timer = self.setTimeout(function () {
  34984. return _this2.loadPlaylist();
  34985. }, delay);
  34986. this.warn("retry playlist loading #" + this.retryCount + " in " + delay + " ms after \"" + errorEvent.details + "\"");
  34987. }
  34988. } else {
  34989. this.warn("cannot recover from error \"" + errorEvent.details + "\"");
  34990. // stopping live reloading timer if any
  34991. this.clearTimer();
  34992. // switch error to fatal
  34993. errorEvent.fatal = true;
  34994. }
  34995. return retry;
  34996. };
  34997. return BasePlaylistController;
  34998. }();
  34999. /***/ }),
  35000. /***/ "./src/controller/base-stream-controller.ts":
  35001. /*!**************************************************!*\
  35002. !*** ./src/controller/base-stream-controller.ts ***!
  35003. \**************************************************/
  35004. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  35005. "use strict";
  35006. __webpack_require__.r(__webpack_exports__);
  35007. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  35008. /* harmony export */ "State": () => (/* binding */ State),
  35009. /* harmony export */ "default": () => (/* binding */ BaseStreamController)
  35010. /* harmony export */ });
  35011. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  35012. /* harmony import */ var _task_loop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../task-loop */ "./src/task-loop.ts");
  35013. /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts");
  35014. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  35015. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  35016. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  35017. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  35018. /* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts");
  35019. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  35020. /* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts");
  35021. /* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts");
  35022. /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts");
  35023. /* harmony import */ var _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../loader/fragment-loader */ "./src/loader/fragment-loader.ts");
  35024. /* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts");
  35025. /* harmony import */ var _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../utils/time-ranges */ "./src/utils/time-ranges.ts");
  35026. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  35027. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  35028. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  35029. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  35030. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  35031. function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
  35032. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  35033. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  35034. var State = {
  35035. STOPPED: 'STOPPED',
  35036. IDLE: 'IDLE',
  35037. KEY_LOADING: 'KEY_LOADING',
  35038. FRAG_LOADING: 'FRAG_LOADING',
  35039. FRAG_LOADING_WAITING_RETRY: 'FRAG_LOADING_WAITING_RETRY',
  35040. WAITING_TRACK: 'WAITING_TRACK',
  35041. PARSING: 'PARSING',
  35042. PARSED: 'PARSED',
  35043. ENDED: 'ENDED',
  35044. ERROR: 'ERROR',
  35045. WAITING_INIT_PTS: 'WAITING_INIT_PTS',
  35046. WAITING_LEVEL: 'WAITING_LEVEL'
  35047. };
  35048. var BaseStreamController = /*#__PURE__*/function (_TaskLoop) {
  35049. _inheritsLoose(BaseStreamController, _TaskLoop);
  35050. function BaseStreamController(hls, fragmentTracker, keyLoader, logPrefix) {
  35051. var _this;
  35052. _this = _TaskLoop.call(this) || this;
  35053. _this.hls = void 0;
  35054. _this.fragPrevious = null;
  35055. _this.fragCurrent = null;
  35056. _this.fragmentTracker = void 0;
  35057. _this.transmuxer = null;
  35058. _this._state = State.STOPPED;
  35059. _this.media = null;
  35060. _this.mediaBuffer = null;
  35061. _this.config = void 0;
  35062. _this.bitrateTest = false;
  35063. _this.lastCurrentTime = 0;
  35064. _this.nextLoadPosition = 0;
  35065. _this.startPosition = 0;
  35066. _this.loadedmetadata = false;
  35067. _this.fragLoadError = 0;
  35068. _this.retryDate = 0;
  35069. _this.levels = null;
  35070. _this.fragmentLoader = void 0;
  35071. _this.keyLoader = void 0;
  35072. _this.levelLastLoaded = null;
  35073. _this.startFragRequested = false;
  35074. _this.decrypter = void 0;
  35075. _this.initPTS = [];
  35076. _this.onvseeking = null;
  35077. _this.onvended = null;
  35078. _this.logPrefix = '';
  35079. _this.log = void 0;
  35080. _this.warn = void 0;
  35081. _this.logPrefix = logPrefix;
  35082. _this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger, logPrefix + ":");
  35083. _this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger, logPrefix + ":");
  35084. _this.hls = hls;
  35085. _this.fragmentLoader = new _loader_fragment_loader__WEBPACK_IMPORTED_MODULE_12__["default"](hls.config);
  35086. _this.keyLoader = keyLoader;
  35087. _this.fragmentTracker = fragmentTracker;
  35088. _this.config = hls.config;
  35089. _this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_13__["default"](hls.config);
  35090. hls.on(_events__WEBPACK_IMPORTED_MODULE_5__.Events.LEVEL_SWITCHING, _this.onLevelSwitching, _assertThisInitialized(_this));
  35091. return _this;
  35092. }
  35093. var _proto = BaseStreamController.prototype;
  35094. _proto.doTick = function doTick() {
  35095. this.onTickEnd();
  35096. };
  35097. _proto.onTickEnd = function onTickEnd() {}
  35098. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  35099. ;
  35100. _proto.startLoad = function startLoad(startPosition) {};
  35101. _proto.stopLoad = function stopLoad() {
  35102. this.fragmentLoader.abort();
  35103. this.keyLoader.abort();
  35104. var frag = this.fragCurrent;
  35105. if (frag) {
  35106. frag.abortRequests();
  35107. this.fragmentTracker.removeFragment(frag);
  35108. }
  35109. this.resetTransmuxer();
  35110. this.fragCurrent = null;
  35111. this.fragPrevious = null;
  35112. this.clearInterval();
  35113. this.clearNextTick();
  35114. this.state = State.STOPPED;
  35115. };
  35116. _proto._streamEnded = function _streamEnded(bufferInfo, levelDetails) {
  35117. // If playlist is live, there is another buffered range after the current range, nothing buffered, media is detached,
  35118. // of nothing loading/loaded return false
  35119. if (levelDetails.live || bufferInfo.nextStart || !bufferInfo.end || !this.media) {
  35120. return false;
  35121. }
  35122. var partList = levelDetails.partList;
  35123. // Since the last part isn't guaranteed to correspond to the last playlist segment for Low-Latency HLS,
  35124. // check instead if the last part is buffered.
  35125. if (partList !== null && partList !== void 0 && partList.length) {
  35126. var lastPart = partList[partList.length - 1];
  35127. // Checking the midpoint of the part for potential margin of error and related issues.
  35128. // NOTE: Technically I believe parts could yield content that is < the computed duration (including potential a duration of 0)
  35129. // and still be spec-compliant, so there may still be edge cases here. Likewise, there could be issues in end of stream
  35130. // part mismatches for independent audio and video playlists/segments.
  35131. var lastPartBuffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.isBuffered(this.media, lastPart.start + lastPart.duration / 2);
  35132. return lastPartBuffered;
  35133. }
  35134. var playlistType = levelDetails.fragments[levelDetails.fragments.length - 1].type;
  35135. return this.fragmentTracker.isEndListAppended(playlistType);
  35136. };
  35137. _proto.getLevelDetails = function getLevelDetails() {
  35138. if (this.levels && this.levelLastLoaded !== null) {
  35139. var _this$levels$this$lev;
  35140. return (_this$levels$this$lev = this.levels[this.levelLastLoaded]) === null || _this$levels$this$lev === void 0 ? void 0 : _this$levels$this$lev.details;
  35141. }
  35142. };
  35143. _proto.onMediaAttached = function onMediaAttached(event, data) {
  35144. var media = this.media = this.mediaBuffer = data.media;
  35145. this.onvseeking = this.onMediaSeeking.bind(this);
  35146. this.onvended = this.onMediaEnded.bind(this);
  35147. media.addEventListener('seeking', this.onvseeking);
  35148. media.addEventListener('ended', this.onvended);
  35149. var config = this.config;
  35150. if (this.levels && config.autoStartLoad && this.state === State.STOPPED) {
  35151. this.startLoad(config.startPosition);
  35152. }
  35153. };
  35154. _proto.onMediaDetaching = function onMediaDetaching() {
  35155. var media = this.media;
  35156. if (media !== null && media !== void 0 && media.ended) {
  35157. this.log('MSE detaching and video ended, reset startPosition');
  35158. this.startPosition = this.lastCurrentTime = 0;
  35159. }
  35160. // remove video listeners
  35161. if (media && this.onvseeking && this.onvended) {
  35162. media.removeEventListener('seeking', this.onvseeking);
  35163. media.removeEventListener('ended', this.onvended);
  35164. this.onvseeking = this.onvended = null;
  35165. }
  35166. if (this.keyLoader) {
  35167. this.keyLoader.detach();
  35168. }
  35169. this.media = this.mediaBuffer = null;
  35170. this.loadedmetadata = false;
  35171. this.fragmentTracker.removeAllFragments();
  35172. this.stopLoad();
  35173. };
  35174. _proto.onMediaSeeking = function onMediaSeeking() {
  35175. var config = this.config,
  35176. fragCurrent = this.fragCurrent,
  35177. media = this.media,
  35178. mediaBuffer = this.mediaBuffer,
  35179. state = this.state;
  35180. var currentTime = media ? media.currentTime : 0;
  35181. var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(mediaBuffer ? mediaBuffer : media, currentTime, config.maxBufferHole);
  35182. this.log("media seeking to " + ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(currentTime) ? currentTime.toFixed(3) : currentTime) + ", state: " + state);
  35183. if (this.state === State.ENDED) {
  35184. this.resetLoadingState();
  35185. } else if (fragCurrent) {
  35186. // Seeking while frag load is in progress
  35187. var tolerance = config.maxFragLookUpTolerance;
  35188. var fragStartOffset = fragCurrent.start - tolerance;
  35189. var fragEndOffset = fragCurrent.start + fragCurrent.duration + tolerance;
  35190. // if seeking out of buffered range or into new one
  35191. if (!bufferInfo.len || fragEndOffset < bufferInfo.start || fragStartOffset > bufferInfo.end) {
  35192. var pastFragment = currentTime > fragEndOffset;
  35193. // if the seek position is outside the current fragment range
  35194. if (currentTime < fragStartOffset || pastFragment) {
  35195. if (pastFragment && fragCurrent.loader) {
  35196. this.log('seeking outside of buffer while fragment load in progress, cancel fragment load');
  35197. fragCurrent.abortRequests();
  35198. }
  35199. this.resetLoadingState();
  35200. }
  35201. }
  35202. }
  35203. if (media) {
  35204. this.lastCurrentTime = currentTime;
  35205. }
  35206. // in case seeking occurs although no media buffered, adjust startPosition and nextLoadPosition to seek target
  35207. if (!this.loadedmetadata && !bufferInfo.len) {
  35208. this.nextLoadPosition = this.startPosition = currentTime;
  35209. }
  35210. // Async tick to speed up processing
  35211. this.tickImmediate();
  35212. };
  35213. _proto.onMediaEnded = function onMediaEnded() {
  35214. // reset startPosition and lastCurrentTime to restart playback @ stream beginning
  35215. this.startPosition = this.lastCurrentTime = 0;
  35216. };
  35217. _proto.onLevelSwitching = function onLevelSwitching(event, data) {
  35218. this.fragLoadError = 0;
  35219. };
  35220. _proto.onHandlerDestroying = function onHandlerDestroying() {
  35221. this.stopLoad();
  35222. _TaskLoop.prototype.onHandlerDestroying.call(this);
  35223. };
  35224. _proto.onHandlerDestroyed = function onHandlerDestroyed() {
  35225. this.state = State.STOPPED;
  35226. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_5__.Events.LEVEL_SWITCHING, this.onLevelSwitching, this);
  35227. if (this.fragmentLoader) {
  35228. this.fragmentLoader.destroy();
  35229. }
  35230. if (this.keyLoader) {
  35231. this.keyLoader.destroy();
  35232. }
  35233. if (this.decrypter) {
  35234. this.decrypter.destroy();
  35235. }
  35236. this.hls = this.log = this.warn = this.decrypter = this.keyLoader = this.fragmentLoader = this.fragmentTracker = null;
  35237. _TaskLoop.prototype.onHandlerDestroyed.call(this);
  35238. };
  35239. _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) {
  35240. this._loadFragForPlayback(frag, levelDetails, targetBufferTime);
  35241. };
  35242. _proto._loadFragForPlayback = function _loadFragForPlayback(frag, levelDetails, targetBufferTime) {
  35243. var _this2 = this;
  35244. var progressCallback = function progressCallback(data) {
  35245. if (_this2.fragContextChanged(frag)) {
  35246. _this2.warn("Fragment " + frag.sn + (data.part ? ' p: ' + data.part.index : '') + " of level " + frag.level + " was dropped during download.");
  35247. _this2.fragmentTracker.removeFragment(frag);
  35248. return;
  35249. }
  35250. frag.stats.chunkCount++;
  35251. _this2._handleFragmentLoadProgress(data);
  35252. };
  35253. this._doFragLoad(frag, levelDetails, targetBufferTime, progressCallback).then(function (data) {
  35254. if (!data) {
  35255. // if we're here we probably needed to backtrack or are waiting for more parts
  35256. return;
  35257. }
  35258. _this2.fragLoadError = 0;
  35259. var state = _this2.state;
  35260. if (_this2.fragContextChanged(frag)) {
  35261. if (state === State.FRAG_LOADING || !_this2.fragCurrent && state === State.PARSING) {
  35262. _this2.fragmentTracker.removeFragment(frag);
  35263. _this2.state = State.IDLE;
  35264. }
  35265. return;
  35266. }
  35267. if ('payload' in data) {
  35268. _this2.log("Loaded fragment " + frag.sn + " of level " + frag.level);
  35269. _this2.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADED, data);
  35270. }
  35271. // Pass through the whole payload; controllers not implementing progressive loading receive data from this callback
  35272. _this2._handleFragmentLoadComplete(data);
  35273. }).catch(function (reason) {
  35274. if (_this2.state === State.STOPPED || _this2.state === State.ERROR) {
  35275. return;
  35276. }
  35277. _this2.warn(reason);
  35278. _this2.resetFragmentLoading(frag);
  35279. });
  35280. };
  35281. _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset, type) {
  35282. if (type === void 0) {
  35283. type = null;
  35284. }
  35285. if (!(startOffset - endOffset)) {
  35286. return;
  35287. }
  35288. // When alternate audio is playing, the audio-stream-controller is responsible for the audio buffer. Otherwise,
  35289. // passing a null type flushes both buffers
  35290. var flushScope = {
  35291. startOffset: startOffset,
  35292. endOffset: endOffset,
  35293. type: type
  35294. };
  35295. // Reset load errors on flush
  35296. this.fragLoadError = 0;
  35297. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.BUFFER_FLUSHING, flushScope);
  35298. };
  35299. _proto._loadInitSegment = function _loadInitSegment(frag, details) {
  35300. var _this3 = this;
  35301. this._doFragLoad(frag, details).then(function (data) {
  35302. if (!data || _this3.fragContextChanged(frag) || !_this3.levels) {
  35303. throw new Error('init load aborted');
  35304. }
  35305. return data;
  35306. }).then(function (data) {
  35307. var hls = _this3.hls;
  35308. var payload = data.payload;
  35309. var decryptData = frag.decryptdata;
  35310. // check to see if the payload needs to be decrypted
  35311. if (payload && payload.byteLength > 0 && decryptData && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
  35312. var startTime = self.performance.now();
  35313. // decrypt the subtitles
  35314. return _this3.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).then(function (decryptedData) {
  35315. var endTime = self.performance.now();
  35316. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_DECRYPTED, {
  35317. frag: frag,
  35318. payload: decryptedData,
  35319. stats: {
  35320. tstart: startTime,
  35321. tdecrypt: endTime
  35322. }
  35323. });
  35324. data.payload = decryptedData;
  35325. return data;
  35326. });
  35327. }
  35328. return data;
  35329. }).then(function (data) {
  35330. var fragCurrent = _this3.fragCurrent,
  35331. hls = _this3.hls,
  35332. levels = _this3.levels;
  35333. if (!levels) {
  35334. throw new Error('init load aborted, missing levels');
  35335. }
  35336. var details = levels[frag.level].details;
  35337. console.assert(details, 'Level details are defined when init segment is loaded');
  35338. var stats = frag.stats;
  35339. _this3.state = State.IDLE;
  35340. _this3.fragLoadError = 0;
  35341. frag.data = new Uint8Array(data.payload);
  35342. stats.parsing.start = stats.buffering.start = self.performance.now();
  35343. stats.parsing.end = stats.buffering.end = self.performance.now();
  35344. // Silence FRAG_BUFFERED event if fragCurrent is null
  35345. if (data.frag === fragCurrent) {
  35346. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_BUFFERED, {
  35347. stats: stats,
  35348. frag: fragCurrent,
  35349. part: null,
  35350. id: frag.type
  35351. });
  35352. }
  35353. _this3.tick();
  35354. }).catch(function (reason) {
  35355. if (_this3.state === State.STOPPED || _this3.state === State.ERROR) {
  35356. return;
  35357. }
  35358. _this3.warn(reason);
  35359. _this3.resetFragmentLoading(frag);
  35360. });
  35361. };
  35362. _proto.fragContextChanged = function fragContextChanged(frag) {
  35363. var fragCurrent = this.fragCurrent;
  35364. return !frag || !fragCurrent || frag.level !== fragCurrent.level || frag.sn !== fragCurrent.sn || frag.urlId !== fragCurrent.urlId;
  35365. };
  35366. _proto.fragBufferedComplete = function fragBufferedComplete(frag, part) {
  35367. var _frag$startPTS, _frag$endPTS, _this$fragCurrent, _this$fragPrevious;
  35368. var media = this.mediaBuffer ? this.mediaBuffer : this.media;
  35369. this.log("Buffered " + frag.type + " sn: " + frag.sn + (part ? ' part: ' + part.index : '') + " of " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level + " (frag:[" + ((_frag$startPTS = frag.startPTS) != null ? _frag$startPTS : NaN).toFixed(3) + "-" + ((_frag$endPTS = frag.endPTS) != null ? _frag$endPTS : NaN).toFixed(3) + "] > buffer:" + (media ? _utils_time_ranges__WEBPACK_IMPORTED_MODULE_14__["default"].toString(_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.getBuffered(media)) : '(detached)') + ")");
  35370. this.state = State.IDLE;
  35371. if (!media) {
  35372. return;
  35373. }
  35374. if (!this.loadedmetadata && frag.type == _types_loader__WEBPACK_IMPORTED_MODULE_15__.PlaylistLevelType.MAIN && media.buffered.length && ((_this$fragCurrent = this.fragCurrent) === null || _this$fragCurrent === void 0 ? void 0 : _this$fragCurrent.sn) === ((_this$fragPrevious = this.fragPrevious) === null || _this$fragPrevious === void 0 ? void 0 : _this$fragPrevious.sn)) {
  35375. this.loadedmetadata = true;
  35376. this.seekToStartPos();
  35377. }
  35378. this.tick();
  35379. };
  35380. _proto.seekToStartPos = function seekToStartPos() {};
  35381. _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedEndData) {
  35382. var transmuxer = this.transmuxer;
  35383. if (!transmuxer) {
  35384. return;
  35385. }
  35386. var frag = fragLoadedEndData.frag,
  35387. part = fragLoadedEndData.part,
  35388. partsLoaded = fragLoadedEndData.partsLoaded;
  35389. // If we did not load parts, or loaded all parts, we have complete (not partial) fragment data
  35390. var complete = !partsLoaded || partsLoaded.length === 0 || partsLoaded.some(function (fragLoaded) {
  35391. return !fragLoaded;
  35392. });
  35393. var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_7__.ChunkMetadata(frag.level, frag.sn, frag.stats.chunkCount + 1, 0, part ? part.index : -1, !complete);
  35394. transmuxer.flush(chunkMeta);
  35395. }
  35396. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  35397. ;
  35398. _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(frag) {};
  35399. _proto._doFragLoad = function _doFragLoad(frag, details, targetBufferTime, progressCallback) {
  35400. var _frag$decryptdata,
  35401. _this4 = this;
  35402. if (targetBufferTime === void 0) {
  35403. targetBufferTime = null;
  35404. }
  35405. if (!this.levels) {
  35406. throw new Error('frag load aborted, missing levels');
  35407. }
  35408. var keyLoadingPromise = null;
  35409. if (frag.encrypted && !((_frag$decryptdata = frag.decryptdata) !== null && _frag$decryptdata !== void 0 && _frag$decryptdata.key)) {
  35410. this.log("Loading key for " + frag.sn + " of [" + details.startSN + "-" + details.endSN + "], " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + " " + frag.level);
  35411. this.state = State.KEY_LOADING;
  35412. this.fragCurrent = frag;
  35413. keyLoadingPromise = this.keyLoader.load(frag).then(function (keyLoadedData) {
  35414. if (!_this4.fragContextChanged(keyLoadedData.frag)) {
  35415. _this4.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.KEY_LOADED, keyLoadedData);
  35416. if (_this4.state === State.KEY_LOADING) {
  35417. _this4.state = State.IDLE;
  35418. }
  35419. return keyLoadedData;
  35420. }
  35421. });
  35422. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.KEY_LOADING, {
  35423. frag: frag
  35424. });
  35425. this.throwIfFragContextChanged('KEY_LOADING');
  35426. } else if (!frag.encrypted && details.encryptedFragments.length) {
  35427. this.keyLoader.loadClear(frag, details.encryptedFragments);
  35428. }
  35429. targetBufferTime = Math.max(frag.start, targetBufferTime || 0);
  35430. if (this.config.lowLatencyMode && details) {
  35431. var partList = details.partList;
  35432. if (partList && progressCallback) {
  35433. if (targetBufferTime > frag.end && details.fragmentHint) {
  35434. frag = details.fragmentHint;
  35435. }
  35436. var partIndex = this.getNextPart(partList, frag, targetBufferTime);
  35437. if (partIndex > -1) {
  35438. var part = partList[partIndex];
  35439. this.log("Loading part sn: " + frag.sn + " p: " + part.index + " cc: " + frag.cc + " of playlist [" + details.startSN + "-" + details.endSN + "] parts [0-" + partIndex + "-" + (partList.length - 1) + "] " + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
  35440. this.nextLoadPosition = part.start + part.duration;
  35441. this.state = State.FRAG_LOADING;
  35442. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADING, {
  35443. frag: frag,
  35444. part: partList[partIndex],
  35445. targetBufferTime: targetBufferTime
  35446. });
  35447. this.throwIfFragContextChanged('FRAG_LOADING parts');
  35448. if (keyLoadingPromise) {
  35449. return keyLoadingPromise.then(function (keyLoadedData) {
  35450. if (!keyLoadedData || _this4.fragContextChanged(keyLoadedData.frag)) {
  35451. return null;
  35452. }
  35453. return _this4.doFragPartsLoad(frag, partList, partIndex, progressCallback);
  35454. }).catch(function (error) {
  35455. return _this4.handleFragLoadError(error);
  35456. });
  35457. }
  35458. return this.doFragPartsLoad(frag, partList, partIndex, progressCallback).catch(function (error) {
  35459. return _this4.handleFragLoadError(error);
  35460. });
  35461. } else if (!frag.url || this.loadedEndOfParts(partList, targetBufferTime)) {
  35462. // Fragment hint has no parts
  35463. return Promise.resolve(null);
  35464. }
  35465. }
  35466. }
  35467. this.log("Loading fragment " + frag.sn + " cc: " + frag.cc + " " + (details ? 'of [' + details.startSN + '-' + details.endSN + '] ' : '') + (this.logPrefix === '[stream-controller]' ? 'level' : 'track') + ": " + frag.level + ", target: " + parseFloat(targetBufferTime.toFixed(3)));
  35468. // Don't update nextLoadPosition for fragments which are not buffered
  35469. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.sn) && !this.bitrateTest) {
  35470. this.nextLoadPosition = frag.start + frag.duration;
  35471. }
  35472. this.state = State.FRAG_LOADING;
  35473. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADING, {
  35474. frag: frag,
  35475. targetBufferTime: targetBufferTime
  35476. });
  35477. this.throwIfFragContextChanged('FRAG_LOADING');
  35478. // Load key before streaming fragment data
  35479. var dataOnProgress = this.config.progressive;
  35480. if (dataOnProgress && keyLoadingPromise) {
  35481. return keyLoadingPromise.then(function (keyLoadedData) {
  35482. if (!keyLoadedData || _this4.fragContextChanged(keyLoadedData === null || keyLoadedData === void 0 ? void 0 : keyLoadedData.frag)) {
  35483. return null;
  35484. }
  35485. return _this4.fragmentLoader.load(frag, progressCallback);
  35486. }).catch(function (error) {
  35487. return _this4.handleFragLoadError(error);
  35488. });
  35489. }
  35490. // load unencrypted fragment data with progress event,
  35491. // or handle fragment result after key and fragment are finished loading
  35492. return Promise.all([this.fragmentLoader.load(frag, dataOnProgress ? progressCallback : undefined), keyLoadingPromise]).then(function (_ref) {
  35493. var fragLoadedData = _ref[0];
  35494. if (!dataOnProgress && fragLoadedData && progressCallback) {
  35495. progressCallback(fragLoadedData);
  35496. }
  35497. return fragLoadedData;
  35498. }).catch(function (error) {
  35499. return _this4.handleFragLoadError(error);
  35500. });
  35501. };
  35502. _proto.throwIfFragContextChanged = function throwIfFragContextChanged(context) {
  35503. // exit if context changed during event loop
  35504. if (this.fragCurrent === null) {
  35505. throw new Error("frag load aborted, context changed in " + context);
  35506. }
  35507. };
  35508. _proto.doFragPartsLoad = function doFragPartsLoad(frag, partList, partIndex, progressCallback) {
  35509. var _this5 = this;
  35510. return new Promise(function (resolve, reject) {
  35511. var partsLoaded = [];
  35512. var loadPartIndex = function loadPartIndex(index) {
  35513. var part = partList[index];
  35514. _this5.fragmentLoader.loadPart(frag, part, progressCallback).then(function (partLoadedData) {
  35515. partsLoaded[part.index] = partLoadedData;
  35516. var loadedPart = partLoadedData.part;
  35517. _this5.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_LOADED, partLoadedData);
  35518. var nextPart = partList[index + 1];
  35519. if (nextPart && nextPart.fragment === frag) {
  35520. loadPartIndex(index + 1);
  35521. } else {
  35522. return resolve({
  35523. frag: frag,
  35524. part: loadedPart,
  35525. partsLoaded: partsLoaded
  35526. });
  35527. }
  35528. }).catch(reject);
  35529. };
  35530. loadPartIndex(partIndex);
  35531. });
  35532. };
  35533. _proto.handleFragLoadError = function handleFragLoadError(error) {
  35534. if ('data' in error) {
  35535. var data = error.data;
  35536. if (error.data && data.details === _errors__WEBPACK_IMPORTED_MODULE_6__.ErrorDetails.INTERNAL_ABORTED) {
  35537. this.handleFragLoadAborted(data.frag, data.part);
  35538. } else {
  35539. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.ERROR, data);
  35540. }
  35541. } else {
  35542. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.ERROR, {
  35543. type: _errors__WEBPACK_IMPORTED_MODULE_6__.ErrorTypes.OTHER_ERROR,
  35544. details: _errors__WEBPACK_IMPORTED_MODULE_6__.ErrorDetails.INTERNAL_EXCEPTION,
  35545. err: error,
  35546. fatal: true
  35547. });
  35548. }
  35549. return null;
  35550. };
  35551. _proto._handleTransmuxerFlush = function _handleTransmuxerFlush(chunkMeta) {
  35552. var context = this.getCurrentContext(chunkMeta);
  35553. if (!context || this.state !== State.PARSING) {
  35554. if (!this.fragCurrent && this.state !== State.STOPPED && this.state !== State.ERROR) {
  35555. this.state = State.IDLE;
  35556. }
  35557. return;
  35558. }
  35559. var frag = context.frag,
  35560. part = context.part,
  35561. level = context.level;
  35562. var now = self.performance.now();
  35563. frag.stats.parsing.end = now;
  35564. if (part) {
  35565. part.stats.parsing.end = now;
  35566. }
  35567. this.updateLevelTiming(frag, part, level, chunkMeta.partial);
  35568. };
  35569. _proto.getCurrentContext = function getCurrentContext(chunkMeta) {
  35570. var levels = this.levels;
  35571. var levelIndex = chunkMeta.level,
  35572. sn = chunkMeta.sn,
  35573. partIndex = chunkMeta.part;
  35574. if (!levels || !levels[levelIndex]) {
  35575. this.warn("Levels object was unset while buffering fragment " + sn + " of level " + levelIndex + ". The current chunk will not be buffered.");
  35576. return null;
  35577. }
  35578. var level = levels[levelIndex];
  35579. var part = partIndex > -1 ? (0,_level_helper__WEBPACK_IMPORTED_MODULE_11__.getPartWith)(level, sn, partIndex) : null;
  35580. var frag = part ? part.fragment : (0,_level_helper__WEBPACK_IMPORTED_MODULE_11__.getFragmentWithSN)(level, sn, this.fragCurrent);
  35581. if (!frag) {
  35582. return null;
  35583. }
  35584. return {
  35585. frag: frag,
  35586. part: part,
  35587. level: level
  35588. };
  35589. };
  35590. _proto.bufferFragmentData = function bufferFragmentData(data, frag, part, chunkMeta) {
  35591. if (!data || this.state !== State.PARSING) {
  35592. return;
  35593. }
  35594. var data1 = data.data1,
  35595. data2 = data.data2;
  35596. var buffer = data1;
  35597. if (data1 && data2) {
  35598. // Combine the moof + mdat so that we buffer with a single append
  35599. buffer = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.appendUint8Array)(data1, data2);
  35600. }
  35601. if (!buffer || !buffer.length) {
  35602. return;
  35603. }
  35604. var segment = {
  35605. type: data.type,
  35606. frag: frag,
  35607. part: part,
  35608. chunkMeta: chunkMeta,
  35609. parent: frag.type,
  35610. data: buffer
  35611. };
  35612. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.BUFFER_APPENDING, segment);
  35613. if (data.dropped && data.independent && !part) {
  35614. // Clear buffer so that we reload previous segments sequentially if required
  35615. this.flushBufferGap(frag);
  35616. }
  35617. };
  35618. _proto.flushBufferGap = function flushBufferGap(frag) {
  35619. var media = this.media;
  35620. if (!media) {
  35621. return;
  35622. }
  35623. // If currentTime is not buffered, clear the back buffer so that we can backtrack as much as needed
  35624. if (!_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.isBuffered(media, media.currentTime)) {
  35625. this.flushMainBuffer(0, frag.start);
  35626. return;
  35627. }
  35628. // Remove back-buffer without interrupting playback to allow back tracking
  35629. var currentTime = media.currentTime;
  35630. var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(media, currentTime, 0);
  35631. var fragDuration = frag.duration;
  35632. var segmentFraction = Math.min(this.config.maxFragLookUpTolerance * 2, fragDuration * 0.25);
  35633. var start = Math.max(Math.min(frag.start - segmentFraction, bufferInfo.end - segmentFraction), currentTime + segmentFraction);
  35634. if (frag.start - start > segmentFraction) {
  35635. this.flushMainBuffer(start, frag.start);
  35636. }
  35637. };
  35638. _proto.getFwdBufferInfo = function getFwdBufferInfo(bufferable, type) {
  35639. var config = this.config;
  35640. var pos = this.getLoadPosition();
  35641. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(pos)) {
  35642. return null;
  35643. }
  35644. var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(bufferable, pos, config.maxBufferHole);
  35645. // Workaround flaw in getting forward buffer when maxBufferHole is smaller than gap at current pos
  35646. if (bufferInfo.len === 0 && bufferInfo.nextStart !== undefined) {
  35647. var bufferedFragAtPos = this.fragmentTracker.getBufferedFrag(pos, type);
  35648. if (bufferedFragAtPos && bufferInfo.nextStart < bufferedFragAtPos.end) {
  35649. return _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.bufferInfo(bufferable, pos, Math.max(bufferInfo.nextStart, config.maxBufferHole));
  35650. }
  35651. }
  35652. return bufferInfo;
  35653. };
  35654. _proto.getMaxBufferLength = function getMaxBufferLength(levelBitrate) {
  35655. var config = this.config;
  35656. var maxBufLen;
  35657. if (levelBitrate) {
  35658. maxBufLen = Math.max(8 * config.maxBufferSize / levelBitrate, config.maxBufferLength);
  35659. } else {
  35660. maxBufLen = config.maxBufferLength;
  35661. }
  35662. return Math.min(maxBufLen, config.maxMaxBufferLength);
  35663. };
  35664. _proto.reduceMaxBufferLength = function reduceMaxBufferLength(threshold) {
  35665. var config = this.config;
  35666. var minLength = threshold || config.maxBufferLength;
  35667. if (config.maxMaxBufferLength >= minLength) {
  35668. // reduce max buffer length as it might be too high. we do this to avoid loop flushing ...
  35669. config.maxMaxBufferLength /= 2;
  35670. this.warn("Reduce max buffer length to " + config.maxMaxBufferLength + "s");
  35671. return true;
  35672. }
  35673. return false;
  35674. };
  35675. _proto.getNextFragment = function getNextFragment(pos, levelDetails) {
  35676. var fragments = levelDetails.fragments;
  35677. var fragLen = fragments.length;
  35678. if (!fragLen) {
  35679. return null;
  35680. }
  35681. // find fragment index, contiguous with end of buffer position
  35682. var config = this.config;
  35683. var start = fragments[0].start;
  35684. var frag;
  35685. if (levelDetails.live) {
  35686. var initialLiveManifestSize = config.initialLiveManifestSize;
  35687. if (fragLen < initialLiveManifestSize) {
  35688. this.warn("Not enough fragments to start playback (have: " + fragLen + ", need: " + initialLiveManifestSize + ")");
  35689. return null;
  35690. }
  35691. // The real fragment start times for a live stream are only known after the PTS range for that level is known.
  35692. // In order to discover the range, we load the best matching fragment for that level and demux it.
  35693. // Do not load using live logic if the starting frag is requested - we want to use getFragmentAtPosition() so that
  35694. // we get the fragment matching that start time
  35695. if (!levelDetails.PTSKnown && !this.startFragRequested && this.startPosition === -1) {
  35696. frag = this.getInitialLiveFragment(levelDetails, fragments);
  35697. this.startPosition = frag ? this.hls.liveSyncPosition || frag.start : pos;
  35698. }
  35699. } else if (pos <= start) {
  35700. // VoD playlist: if loadPosition before start of playlist, load first fragment
  35701. frag = fragments[0];
  35702. }
  35703. // If we haven't run into any special cases already, just load the fragment most closely matching the requested position
  35704. if (!frag) {
  35705. var end = config.lowLatencyMode ? levelDetails.partEnd : levelDetails.fragmentEnd;
  35706. frag = this.getFragmentAtPosition(pos, end, levelDetails);
  35707. }
  35708. return this.mapToInitFragWhenRequired(frag);
  35709. };
  35710. _proto.mapToInitFragWhenRequired = function mapToInitFragWhenRequired(frag) {
  35711. // If an initSegment is present, it must be buffered first
  35712. if (frag !== null && frag !== void 0 && frag.initSegment && !(frag !== null && frag !== void 0 && frag.initSegment.data) && !this.bitrateTest) {
  35713. return frag.initSegment;
  35714. }
  35715. return frag;
  35716. };
  35717. _proto.getNextPart = function getNextPart(partList, frag, targetBufferTime) {
  35718. var nextPart = -1;
  35719. var contiguous = false;
  35720. var independentAttrOmitted = true;
  35721. for (var i = 0, len = partList.length; i < len; i++) {
  35722. var part = partList[i];
  35723. independentAttrOmitted = independentAttrOmitted && !part.independent;
  35724. if (nextPart > -1 && targetBufferTime < part.start) {
  35725. break;
  35726. }
  35727. var loaded = part.loaded;
  35728. if (loaded) {
  35729. nextPart = -1;
  35730. } else if ((contiguous || part.independent || independentAttrOmitted) && part.fragment === frag) {
  35731. nextPart = i;
  35732. }
  35733. contiguous = loaded;
  35734. }
  35735. return nextPart;
  35736. };
  35737. _proto.loadedEndOfParts = function loadedEndOfParts(partList, targetBufferTime) {
  35738. var lastPart = partList[partList.length - 1];
  35739. return lastPart && targetBufferTime > lastPart.start && lastPart.loaded;
  35740. }
  35741. /*
  35742. This method is used find the best matching first fragment for a live playlist. This fragment is used to calculate the
  35743. "sliding" of the playlist, which is its offset from the start of playback. After sliding we can compute the real
  35744. start and end times for each fragment in the playlist (after which this method will not need to be called).
  35745. */;
  35746. _proto.getInitialLiveFragment = function getInitialLiveFragment(levelDetails, fragments) {
  35747. var fragPrevious = this.fragPrevious;
  35748. var frag = null;
  35749. if (fragPrevious) {
  35750. if (levelDetails.hasProgramDateTime) {
  35751. // Prefer using PDT, because it can be accurate enough to choose the correct fragment without knowing the level sliding
  35752. this.log("Live playlist, switching playlist, load frag with same PDT: " + fragPrevious.programDateTime);
  35753. frag = (0,_fragment_finders__WEBPACK_IMPORTED_MODULE_10__.findFragmentByPDT)(fragments, fragPrevious.endProgramDateTime, this.config.maxFragLookUpTolerance);
  35754. }
  35755. if (!frag) {
  35756. // SN does not need to be accurate between renditions, but depending on the packaging it may be so.
  35757. var targetSN = fragPrevious.sn + 1;
  35758. if (targetSN >= levelDetails.startSN && targetSN <= levelDetails.endSN) {
  35759. var fragNext = fragments[targetSN - levelDetails.startSN];
  35760. // Ensure that we're staying within the continuity range, since PTS resets upon a new range
  35761. if (fragPrevious.cc === fragNext.cc) {
  35762. frag = fragNext;
  35763. this.log("Live playlist, switching playlist, load frag with next SN: " + frag.sn);
  35764. }
  35765. }
  35766. // It's important to stay within the continuity range if available; otherwise the fragments in the playlist
  35767. // will have the wrong start times
  35768. if (!frag) {
  35769. frag = (0,_fragment_finders__WEBPACK_IMPORTED_MODULE_10__.findFragWithCC)(fragments, fragPrevious.cc);
  35770. if (frag) {
  35771. this.log("Live playlist, switching playlist, load frag with same CC: " + frag.sn);
  35772. }
  35773. }
  35774. }
  35775. } else {
  35776. // Find a new start fragment when fragPrevious is null
  35777. var liveStart = this.hls.liveSyncPosition;
  35778. if (liveStart !== null) {
  35779. frag = this.getFragmentAtPosition(liveStart, this.bitrateTest ? levelDetails.fragmentEnd : levelDetails.edge, levelDetails);
  35780. }
  35781. }
  35782. return frag;
  35783. }
  35784. /*
  35785. This method finds the best matching fragment given the provided position.
  35786. */;
  35787. _proto.getFragmentAtPosition = function getFragmentAtPosition(bufferEnd, end, levelDetails) {
  35788. var config = this.config;
  35789. var fragPrevious = this.fragPrevious;
  35790. var fragments = levelDetails.fragments,
  35791. endSN = levelDetails.endSN;
  35792. var fragmentHint = levelDetails.fragmentHint;
  35793. var tolerance = config.maxFragLookUpTolerance;
  35794. var loadingParts = !!(config.lowLatencyMode && levelDetails.partList && fragmentHint);
  35795. if (loadingParts && fragmentHint && !this.bitrateTest) {
  35796. // Include incomplete fragment with parts at end
  35797. fragments = fragments.concat(fragmentHint);
  35798. endSN = fragmentHint.sn;
  35799. }
  35800. var frag;
  35801. if (bufferEnd < end) {
  35802. var lookupTolerance = bufferEnd > end - tolerance ? 0 : tolerance;
  35803. // Remove the tolerance if it would put the bufferEnd past the actual end of stream
  35804. // Uses buffer and sequence number to calculate switch segment (required if using EXT-X-DISCONTINUITY-SEQUENCE)
  35805. frag = (0,_fragment_finders__WEBPACK_IMPORTED_MODULE_10__.findFragmentByPTS)(fragPrevious, fragments, bufferEnd, lookupTolerance);
  35806. } else {
  35807. // reach end of playlist
  35808. frag = fragments[fragments.length - 1];
  35809. }
  35810. if (frag) {
  35811. var curSNIdx = frag.sn - levelDetails.startSN;
  35812. // Move fragPrevious forward to support forcing the next fragment to load
  35813. // when the buffer catches up to a previously buffered range.
  35814. if (this.fragmentTracker.getState(frag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__.FragmentState.OK) {
  35815. fragPrevious = frag;
  35816. }
  35817. if (fragPrevious && frag.sn === fragPrevious.sn && !loadingParts) {
  35818. // Force the next fragment to load if the previous one was already selected. This can occasionally happen with
  35819. // non-uniform fragment durations
  35820. var sameLevel = fragPrevious && frag.level === fragPrevious.level;
  35821. if (sameLevel) {
  35822. var nextFrag = fragments[curSNIdx + 1];
  35823. if (frag.sn < endSN && this.fragmentTracker.getState(nextFrag) !== _fragment_tracker__WEBPACK_IMPORTED_MODULE_2__.FragmentState.OK) {
  35824. this.log("SN " + frag.sn + " just loaded, load next one: " + nextFrag.sn);
  35825. frag = nextFrag;
  35826. } else {
  35827. frag = null;
  35828. }
  35829. }
  35830. }
  35831. }
  35832. return frag;
  35833. };
  35834. _proto.synchronizeToLiveEdge = function synchronizeToLiveEdge(levelDetails) {
  35835. var config = this.config,
  35836. media = this.media;
  35837. if (!media) {
  35838. return;
  35839. }
  35840. var liveSyncPosition = this.hls.liveSyncPosition;
  35841. var currentTime = media.currentTime;
  35842. var start = levelDetails.fragments[0].start;
  35843. var end = levelDetails.edge;
  35844. var withinSlidingWindow = currentTime >= start - config.maxFragLookUpTolerance && currentTime <= end;
  35845. // Continue if we can seek forward to sync position or if current time is outside of sliding window
  35846. if (liveSyncPosition !== null && media.duration > liveSyncPosition && (currentTime < liveSyncPosition || !withinSlidingWindow)) {
  35847. // Continue if buffer is starving or if current time is behind max latency
  35848. var maxLatency = config.liveMaxLatencyDuration !== undefined ? config.liveMaxLatencyDuration : config.liveMaxLatencyDurationCount * levelDetails.targetduration;
  35849. if (!withinSlidingWindow && media.readyState < 4 || currentTime < end - maxLatency) {
  35850. if (!this.loadedmetadata) {
  35851. this.nextLoadPosition = liveSyncPosition;
  35852. }
  35853. // Only seek if ready and there is not a significant forward buffer available for playback
  35854. if (media.readyState) {
  35855. this.warn("Playback: " + currentTime.toFixed(3) + " is located too far from the end of live sliding playlist: " + end + ", reset currentTime to : " + liveSyncPosition.toFixed(3));
  35856. media.currentTime = liveSyncPosition;
  35857. }
  35858. }
  35859. }
  35860. };
  35861. _proto.alignPlaylists = function alignPlaylists(details, previousDetails) {
  35862. var levels = this.levels,
  35863. levelLastLoaded = this.levelLastLoaded,
  35864. fragPrevious = this.fragPrevious;
  35865. var lastLevel = levelLastLoaded !== null ? levels[levelLastLoaded] : null;
  35866. // FIXME: If not for `shouldAlignOnDiscontinuities` requiring fragPrevious.cc,
  35867. // this could all go in level-helper mergeDetails()
  35868. var length = details.fragments.length;
  35869. if (!length) {
  35870. this.warn("No fragments in live playlist");
  35871. return 0;
  35872. }
  35873. var slidingStart = details.fragments[0].start;
  35874. var firstLevelLoad = !previousDetails;
  35875. var aligned = details.alignedSliding && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(slidingStart);
  35876. if (firstLevelLoad || !aligned && !slidingStart) {
  35877. (0,_utils_discontinuities__WEBPACK_IMPORTED_MODULE_9__.alignStream)(fragPrevious, lastLevel, details);
  35878. var alignedSlidingStart = details.fragments[0].start;
  35879. this.log("Live playlist sliding: " + alignedSlidingStart.toFixed(2) + " start-sn: " + (previousDetails ? previousDetails.startSN : 'na') + "->" + details.startSN + " prev-sn: " + (fragPrevious ? fragPrevious.sn : 'na') + " fragments: " + length);
  35880. return alignedSlidingStart;
  35881. }
  35882. return slidingStart;
  35883. };
  35884. _proto.waitForCdnTuneIn = function waitForCdnTuneIn(details) {
  35885. // Wait for Low-Latency CDN Tune-in to get an updated playlist
  35886. var advancePartLimit = 3;
  35887. return details.live && details.canBlockReload && details.partTarget && details.tuneInGoal > Math.max(details.partHoldBack, details.partTarget * advancePartLimit);
  35888. };
  35889. _proto.setStartPosition = function setStartPosition(details, sliding) {
  35890. // compute start position if set to -1. use it straight away if value is defined
  35891. var startPosition = this.startPosition;
  35892. if (startPosition < sliding) {
  35893. startPosition = -1;
  35894. }
  35895. if (startPosition === -1 || this.lastCurrentTime === -1) {
  35896. // first, check if start time offset has been set in playlist, if yes, use this value
  35897. var startTimeOffset = details.startTimeOffset;
  35898. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(startTimeOffset)) {
  35899. startPosition = sliding + startTimeOffset;
  35900. if (startTimeOffset < 0) {
  35901. startPosition += details.totalduration;
  35902. }
  35903. startPosition = Math.min(Math.max(sliding, startPosition), sliding + details.totalduration);
  35904. this.log("Start time offset " + startTimeOffset + " found in playlist, adjust startPosition to " + startPosition);
  35905. this.startPosition = startPosition;
  35906. } else if (details.live) {
  35907. // Leave this.startPosition at -1, so that we can use `getInitialLiveFragment` logic when startPosition has
  35908. // not been specified via the config or an as an argument to startLoad (#3736).
  35909. startPosition = this.hls.liveSyncPosition || sliding;
  35910. } else {
  35911. this.startPosition = startPosition = 0;
  35912. }
  35913. this.lastCurrentTime = startPosition;
  35914. }
  35915. this.nextLoadPosition = startPosition;
  35916. };
  35917. _proto.getLoadPosition = function getLoadPosition() {
  35918. var media = this.media;
  35919. // if we have not yet loaded any fragment, start loading from start position
  35920. var pos = 0;
  35921. if (this.loadedmetadata && media) {
  35922. pos = media.currentTime;
  35923. } else if (this.nextLoadPosition) {
  35924. pos = this.nextLoadPosition;
  35925. }
  35926. return pos;
  35927. };
  35928. _proto.handleFragLoadAborted = function handleFragLoadAborted(frag, part) {
  35929. if (this.transmuxer && frag.sn !== 'initSegment' && frag.stats.aborted) {
  35930. this.warn("Fragment " + frag.sn + (part ? ' part' + part.index : '') + " of level " + frag.level + " was aborted");
  35931. this.resetFragmentLoading(frag);
  35932. }
  35933. };
  35934. _proto.resetFragmentLoading = function resetFragmentLoading(frag) {
  35935. if (!this.fragCurrent || !this.fragContextChanged(frag) && this.state !== State.FRAG_LOADING_WAITING_RETRY) {
  35936. this.state = State.IDLE;
  35937. }
  35938. };
  35939. _proto.onFragmentOrKeyLoadError = function onFragmentOrKeyLoadError(filterType, data) {
  35940. if (data.fatal) {
  35941. this.stopLoad();
  35942. this.state = State.ERROR;
  35943. return;
  35944. }
  35945. var config = this.config;
  35946. if (data.chunkMeta) {
  35947. // Parsing Error: no retries
  35948. var context = this.getCurrentContext(data.chunkMeta);
  35949. if (context) {
  35950. data.frag = context.frag;
  35951. data.levelRetry = true;
  35952. this.fragLoadError = config.fragLoadingMaxRetry;
  35953. }
  35954. }
  35955. var frag = data.frag;
  35956. // Handle frag error related to caller's filterType
  35957. if (!frag || frag.type !== filterType) {
  35958. return;
  35959. }
  35960. var fragCurrent = this.fragCurrent;
  35961. console.assert(fragCurrent && frag.sn === fragCurrent.sn && frag.level === fragCurrent.level && frag.urlId === fragCurrent.urlId, 'Frag load error must match current frag to retry');
  35962. // keep retrying until the limit will be reached
  35963. if (this.fragLoadError + 1 <= config.fragLoadingMaxRetry) {
  35964. if (!this.loadedmetadata) {
  35965. this.startFragRequested = false;
  35966. this.nextLoadPosition = this.startPosition;
  35967. }
  35968. // exponential backoff capped to config.fragLoadingMaxRetryTimeout
  35969. var delay = Math.min(Math.pow(2, this.fragLoadError) * config.fragLoadingRetryDelay, config.fragLoadingMaxRetryTimeout);
  35970. this.warn("Fragment " + frag.sn + " of " + filterType + " " + frag.level + " failed to load, retrying in " + delay + "ms");
  35971. this.retryDate = self.performance.now() + delay;
  35972. this.fragLoadError++;
  35973. this.state = State.FRAG_LOADING_WAITING_RETRY;
  35974. } else if (data.levelRetry) {
  35975. if (filterType === _types_loader__WEBPACK_IMPORTED_MODULE_15__.PlaylistLevelType.AUDIO) {
  35976. // Reset current fragment since audio track audio is essential and may not have a fail-over track
  35977. this.fragCurrent = null;
  35978. }
  35979. // Fragment errors that result in a level switch or redundant fail-over
  35980. // should reset the stream controller state to idle
  35981. this.fragLoadError = 0;
  35982. this.state = State.IDLE;
  35983. } else {
  35984. _utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.error(data.details + " reaches max retry, redispatch as fatal ...");
  35985. // switch error to fatal
  35986. data.fatal = true;
  35987. this.hls.stopLoad();
  35988. this.state = State.ERROR;
  35989. }
  35990. };
  35991. _proto.afterBufferFlushed = function afterBufferFlushed(media, bufferType, playlistType) {
  35992. if (!media) {
  35993. return;
  35994. }
  35995. // After successful buffer flushing, filter flushed fragments from bufferedFrags use mediaBuffered instead of media
  35996. // (so that we will check against video.buffered ranges in case of alt audio track)
  35997. var bufferedTimeRanges = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_3__.BufferHelper.getBuffered(media);
  35998. this.fragmentTracker.detectEvictedFragments(bufferType, bufferedTimeRanges, playlistType);
  35999. if (this.state === State.ENDED) {
  36000. this.resetLoadingState();
  36001. }
  36002. };
  36003. _proto.resetLoadingState = function resetLoadingState() {
  36004. this.log('Reset loading state');
  36005. this.fragCurrent = null;
  36006. this.fragPrevious = null;
  36007. this.state = State.IDLE;
  36008. };
  36009. _proto.resetStartWhenNotLoaded = function resetStartWhenNotLoaded(level) {
  36010. // if loadedmetadata is not set, it means that first frag request failed
  36011. // in that case, reset startFragRequested flag
  36012. if (!this.loadedmetadata) {
  36013. this.startFragRequested = false;
  36014. var details = this.levels ? this.levels[level].details : null;
  36015. if (details !== null && details !== void 0 && details.live) {
  36016. // Update the start position and return to IDLE to recover live start
  36017. this.startPosition = -1;
  36018. this.setStartPosition(details, 0);
  36019. this.resetLoadingState();
  36020. } else {
  36021. this.nextLoadPosition = this.startPosition;
  36022. }
  36023. }
  36024. };
  36025. _proto.updateLevelTiming = function updateLevelTiming(frag, part, level, partial) {
  36026. var _this6 = this;
  36027. var details = level.details;
  36028. console.assert(!!details, 'level.details must be defined');
  36029. var parsed = Object.keys(frag.elementaryStreams).reduce(function (result, type) {
  36030. var info = frag.elementaryStreams[type];
  36031. if (info) {
  36032. var parsedDuration = info.endPTS - info.startPTS;
  36033. if (parsedDuration <= 0) {
  36034. // Destroy the transmuxer after it's next time offset failed to advance because duration was <= 0.
  36035. // The new transmuxer will be configured with a time offset matching the next fragment start,
  36036. // preventing the timeline from shifting.
  36037. _this6.warn("Could not parse fragment " + frag.sn + " " + type + " duration reliably (" + parsedDuration + ")");
  36038. return result || false;
  36039. }
  36040. var drift = partial ? 0 : (0,_level_helper__WEBPACK_IMPORTED_MODULE_11__.updateFragPTSDTS)(details, frag, info.startPTS, info.endPTS, info.startDTS, info.endDTS);
  36041. _this6.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.LEVEL_PTS_UPDATED, {
  36042. details: details,
  36043. level: level,
  36044. drift: drift,
  36045. type: type,
  36046. frag: frag,
  36047. start: info.startPTS,
  36048. end: info.endPTS
  36049. });
  36050. return true;
  36051. }
  36052. return result;
  36053. }, false);
  36054. if (!parsed) {
  36055. this.warn("Found no media in fragment " + frag.sn + " of level " + level.id + " resetting transmuxer to fallback to playlist timing");
  36056. this.resetTransmuxer();
  36057. }
  36058. this.state = State.PARSED;
  36059. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_5__.Events.FRAG_PARSED, {
  36060. frag: frag,
  36061. part: part
  36062. });
  36063. };
  36064. _proto.resetTransmuxer = function resetTransmuxer() {
  36065. if (this.transmuxer) {
  36066. this.transmuxer.destroy();
  36067. this.transmuxer = null;
  36068. }
  36069. };
  36070. _createClass(BaseStreamController, [{
  36071. key: "state",
  36072. get: function get() {
  36073. return this._state;
  36074. },
  36075. set: function set(nextState) {
  36076. var previousState = this._state;
  36077. if (previousState !== nextState) {
  36078. this._state = nextState;
  36079. this.log(previousState + "->" + nextState);
  36080. }
  36081. }
  36082. }]);
  36083. return BaseStreamController;
  36084. }(_task_loop__WEBPACK_IMPORTED_MODULE_1__["default"]);
  36085. /***/ }),
  36086. /***/ "./src/controller/buffer-controller.ts":
  36087. /*!*********************************************!*\
  36088. !*** ./src/controller/buffer-controller.ts ***!
  36089. \*********************************************/
  36090. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  36091. "use strict";
  36092. __webpack_require__.r(__webpack_exports__);
  36093. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  36094. /* harmony export */ "default": () => (/* binding */ BufferController)
  36095. /* harmony export */ });
  36096. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  36097. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  36098. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  36099. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  36100. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  36101. /* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mediasource-helper */ "./src/utils/mediasource-helper.ts");
  36102. /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts");
  36103. /* harmony import */ var _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./buffer-operation-queue */ "./src/controller/buffer-operation-queue.ts");
  36104. var MediaSource = (0,_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__.getMediaSource)();
  36105. var VIDEO_CODEC_PROFILE_REPACE = /([ha]vc.)(?:\.[^.,]+)+/;
  36106. var BufferController = /*#__PURE__*/function () {
  36107. // The level details used to determine duration, target-duration and live
  36108. // cache the self generated object url to detect hijack of video tag
  36109. // A queue of buffer operations which require the SourceBuffer to not be updating upon execution
  36110. // References to event listeners for each SourceBuffer, so that they can be referenced for event removal
  36111. // The number of BUFFER_CODEC events received before any sourceBuffers are created
  36112. // The total number of BUFFER_CODEC events received
  36113. // A reference to the attached media element
  36114. // A reference to the active media source
  36115. // Last MP3 audio chunk appended
  36116. // counters
  36117. function BufferController(hls) {
  36118. var _this = this;
  36119. this.details = null;
  36120. this._objectUrl = null;
  36121. this.operationQueue = void 0;
  36122. this.listeners = void 0;
  36123. this.hls = void 0;
  36124. this.bufferCodecEventsExpected = 0;
  36125. this._bufferCodecEventsTotal = 0;
  36126. this.media = null;
  36127. this.mediaSource = null;
  36128. this.lastMpegAudioChunk = null;
  36129. this.appendError = 0;
  36130. this.tracks = {};
  36131. this.pendingTracks = {};
  36132. this.sourceBuffer = void 0;
  36133. this._onMediaSourceOpen = function () {
  36134. var media = _this.media,
  36135. mediaSource = _this.mediaSource;
  36136. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media source opened');
  36137. if (media) {
  36138. media.removeEventListener('emptied', _this._onMediaEmptied);
  36139. _this.updateMediaElementDuration();
  36140. _this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED, {
  36141. media: media
  36142. });
  36143. }
  36144. if (mediaSource) {
  36145. // once received, don't listen anymore to sourceopen event
  36146. mediaSource.removeEventListener('sourceopen', _this._onMediaSourceOpen);
  36147. }
  36148. _this.checkPendingTracks();
  36149. };
  36150. this._onMediaSourceClose = function () {
  36151. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media source closed');
  36152. };
  36153. this._onMediaSourceEnded = function () {
  36154. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media source ended');
  36155. };
  36156. this._onMediaEmptied = function () {
  36157. var media = _this.media,
  36158. _objectUrl = _this._objectUrl;
  36159. if (media && media.src !== _objectUrl) {
  36160. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("Media element src was set while attaching MediaSource (" + _objectUrl + " > " + media.src + ")");
  36161. }
  36162. };
  36163. this.hls = hls;
  36164. this._initSourceBuffer();
  36165. this.registerListeners();
  36166. }
  36167. var _proto = BufferController.prototype;
  36168. _proto.hasSourceTypes = function hasSourceTypes() {
  36169. return this.getSourceBufferTypes().length > 0 || Object.keys(this.pendingTracks).length > 0;
  36170. };
  36171. _proto.destroy = function destroy() {
  36172. this.unregisterListeners();
  36173. this.details = null;
  36174. this.lastMpegAudioChunk = null;
  36175. };
  36176. _proto.registerListeners = function registerListeners() {
  36177. var hls = this.hls;
  36178. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  36179. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  36180. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  36181. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_RESET, this.onBufferReset, this);
  36182. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_APPENDING, this.onBufferAppending, this);
  36183. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_CODECS, this.onBufferCodecs, this);
  36184. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_EOS, this.onBufferEos, this);
  36185. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  36186. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED, this.onLevelUpdated, this);
  36187. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSED, this.onFragParsed, this);
  36188. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_CHANGED, this.onFragChanged, this);
  36189. };
  36190. _proto.unregisterListeners = function unregisterListeners() {
  36191. var hls = this.hls;
  36192. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  36193. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  36194. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  36195. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_RESET, this.onBufferReset, this);
  36196. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_APPENDING, this.onBufferAppending, this);
  36197. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_CODECS, this.onBufferCodecs, this);
  36198. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_EOS, this.onBufferEos, this);
  36199. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  36200. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED, this.onLevelUpdated, this);
  36201. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSED, this.onFragParsed, this);
  36202. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_CHANGED, this.onFragChanged, this);
  36203. };
  36204. _proto._initSourceBuffer = function _initSourceBuffer() {
  36205. this.sourceBuffer = {};
  36206. this.operationQueue = new _buffer_operation_queue__WEBPACK_IMPORTED_MODULE_7__["default"](this.sourceBuffer);
  36207. this.listeners = {
  36208. audio: [],
  36209. video: [],
  36210. audiovideo: []
  36211. };
  36212. this.lastMpegAudioChunk = null;
  36213. };
  36214. _proto.onManifestParsed = function onManifestParsed(event, data) {
  36215. // in case of alt audio 2 BUFFER_CODECS events will be triggered, one per stream controller
  36216. // sourcebuffers will be created all at once when the expected nb of tracks will be reached
  36217. // in case alt audio is not used, only one BUFFER_CODEC event will be fired from main stream controller
  36218. // it will contain the expected nb of source buffers, no need to compute it
  36219. var codecEvents = 2;
  36220. if (data.audio && !data.video || !data.altAudio) {
  36221. codecEvents = 1;
  36222. }
  36223. this.bufferCodecEventsExpected = this._bufferCodecEventsTotal = codecEvents;
  36224. this.details = null;
  36225. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log(this.bufferCodecEventsExpected + " bufferCodec event(s) expected");
  36226. };
  36227. _proto.onMediaAttaching = function onMediaAttaching(event, data) {
  36228. var media = this.media = data.media;
  36229. if (media && MediaSource) {
  36230. var ms = this.mediaSource = new MediaSource();
  36231. // MediaSource listeners are arrow functions with a lexical scope, and do not need to be bound
  36232. ms.addEventListener('sourceopen', this._onMediaSourceOpen);
  36233. ms.addEventListener('sourceended', this._onMediaSourceEnded);
  36234. ms.addEventListener('sourceclose', this._onMediaSourceClose);
  36235. // link video and media Source
  36236. media.src = self.URL.createObjectURL(ms);
  36237. // cache the locally generated object url
  36238. this._objectUrl = media.src;
  36239. media.addEventListener('emptied', this._onMediaEmptied);
  36240. }
  36241. };
  36242. _proto.onMediaDetaching = function onMediaDetaching() {
  36243. var media = this.media,
  36244. mediaSource = this.mediaSource,
  36245. _objectUrl = this._objectUrl;
  36246. if (mediaSource) {
  36247. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: media source detaching');
  36248. if (mediaSource.readyState === 'open') {
  36249. try {
  36250. // endOfStream could trigger exception if any sourcebuffer is in updating state
  36251. // we don't really care about checking sourcebuffer state here,
  36252. // as we are anyway detaching the MediaSource
  36253. // let's just avoid this exception to propagate
  36254. mediaSource.endOfStream();
  36255. } catch (err) {
  36256. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: onMediaDetaching: " + err.message + " while calling endOfStream");
  36257. }
  36258. }
  36259. // Clean up the SourceBuffers by invoking onBufferReset
  36260. this.onBufferReset();
  36261. mediaSource.removeEventListener('sourceopen', this._onMediaSourceOpen);
  36262. mediaSource.removeEventListener('sourceended', this._onMediaSourceEnded);
  36263. mediaSource.removeEventListener('sourceclose', this._onMediaSourceClose);
  36264. // Detach properly the MediaSource from the HTMLMediaElement as
  36265. // suggested in https://github.com/w3c/media-source/issues/53.
  36266. if (media) {
  36267. media.removeEventListener('emptied', this._onMediaEmptied);
  36268. if (_objectUrl) {
  36269. self.URL.revokeObjectURL(_objectUrl);
  36270. }
  36271. // clean up video tag src only if it's our own url. some external libraries might
  36272. // hijack the video tag and change its 'src' without destroying the Hls instance first
  36273. if (media.src === _objectUrl) {
  36274. media.removeAttribute('src');
  36275. media.load();
  36276. } else {
  36277. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn('[buffer-controller]: media.src was changed by a third party - skip cleanup');
  36278. }
  36279. }
  36280. this.mediaSource = null;
  36281. this.media = null;
  36282. this._objectUrl = null;
  36283. this.bufferCodecEventsExpected = this._bufferCodecEventsTotal;
  36284. this.pendingTracks = {};
  36285. this.tracks = {};
  36286. }
  36287. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHED, undefined);
  36288. };
  36289. _proto.onBufferReset = function onBufferReset() {
  36290. var _this2 = this;
  36291. this.getSourceBufferTypes().forEach(function (type) {
  36292. var sb = _this2.sourceBuffer[type];
  36293. try {
  36294. if (sb) {
  36295. _this2.removeBufferListeners(type);
  36296. if (_this2.mediaSource) {
  36297. _this2.mediaSource.removeSourceBuffer(sb);
  36298. }
  36299. // Synchronously remove the SB from the map before the next call in order to prevent an async function from
  36300. // accessing it
  36301. _this2.sourceBuffer[type] = undefined;
  36302. }
  36303. } catch (err) {
  36304. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Failed to reset the " + type + " buffer", err);
  36305. }
  36306. });
  36307. this._initSourceBuffer();
  36308. };
  36309. _proto.onBufferCodecs = function onBufferCodecs(event, data) {
  36310. var _this3 = this;
  36311. var sourceBufferCount = this.getSourceBufferTypes().length;
  36312. Object.keys(data).forEach(function (trackName) {
  36313. if (sourceBufferCount) {
  36314. // check if SourceBuffer codec needs to change
  36315. var track = _this3.tracks[trackName];
  36316. if (track && typeof track.buffer.changeType === 'function') {
  36317. var _data$trackName = data[trackName],
  36318. id = _data$trackName.id,
  36319. codec = _data$trackName.codec,
  36320. levelCodec = _data$trackName.levelCodec,
  36321. container = _data$trackName.container,
  36322. metadata = _data$trackName.metadata;
  36323. var currentCodec = (track.levelCodec || track.codec).replace(VIDEO_CODEC_PROFILE_REPACE, '$1');
  36324. var nextCodec = (levelCodec || codec).replace(VIDEO_CODEC_PROFILE_REPACE, '$1');
  36325. if (currentCodec !== nextCodec) {
  36326. var mimeType = container + ";codecs=" + (levelCodec || codec);
  36327. _this3.appendChangeType(trackName, mimeType);
  36328. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: switching codec " + currentCodec + " to " + nextCodec);
  36329. _this3.tracks[trackName] = {
  36330. buffer: track.buffer,
  36331. codec: codec,
  36332. container: container,
  36333. levelCodec: levelCodec,
  36334. metadata: metadata,
  36335. id: id
  36336. };
  36337. }
  36338. }
  36339. } else {
  36340. // if source buffer(s) not created yet, appended buffer tracks in this.pendingTracks
  36341. _this3.pendingTracks[trackName] = data[trackName];
  36342. }
  36343. });
  36344. // if sourcebuffers already created, do nothing ...
  36345. if (sourceBufferCount) {
  36346. return;
  36347. }
  36348. this.bufferCodecEventsExpected = Math.max(this.bufferCodecEventsExpected - 1, 0);
  36349. if (this.mediaSource && this.mediaSource.readyState === 'open') {
  36350. this.checkPendingTracks();
  36351. }
  36352. };
  36353. _proto.appendChangeType = function appendChangeType(type, mimeType) {
  36354. var _this4 = this;
  36355. var operationQueue = this.operationQueue;
  36356. var operation = {
  36357. execute: function execute() {
  36358. var sb = _this4.sourceBuffer[type];
  36359. if (sb) {
  36360. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: changing " + type + " sourceBuffer type to " + mimeType);
  36361. sb.changeType(mimeType);
  36362. }
  36363. operationQueue.shiftAndExecuteNext(type);
  36364. },
  36365. onStart: function onStart() {},
  36366. onComplete: function onComplete() {},
  36367. onError: function onError(e) {
  36368. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Failed to change " + type + " SourceBuffer type", e);
  36369. }
  36370. };
  36371. operationQueue.append(operation, type);
  36372. };
  36373. _proto.onBufferAppending = function onBufferAppending(event, eventData) {
  36374. var _this5 = this;
  36375. var hls = this.hls,
  36376. operationQueue = this.operationQueue,
  36377. tracks = this.tracks;
  36378. var data = eventData.data,
  36379. type = eventData.type,
  36380. frag = eventData.frag,
  36381. part = eventData.part,
  36382. chunkMeta = eventData.chunkMeta;
  36383. var chunkStats = chunkMeta.buffering[type];
  36384. var bufferAppendingStart = self.performance.now();
  36385. chunkStats.start = bufferAppendingStart;
  36386. var fragBuffering = frag.stats.buffering;
  36387. var partBuffering = part ? part.stats.buffering : null;
  36388. if (fragBuffering.start === 0) {
  36389. fragBuffering.start = bufferAppendingStart;
  36390. }
  36391. if (partBuffering && partBuffering.start === 0) {
  36392. partBuffering.start = bufferAppendingStart;
  36393. }
  36394. // TODO: Only update timestampOffset when audio/mpeg fragment or part is not contiguous with previously appended
  36395. // Adjusting `SourceBuffer.timestampOffset` (desired point in the timeline where the next frames should be appended)
  36396. // in Chrome browser when we detect MPEG audio container and time delta between level PTS and `SourceBuffer.timestampOffset`
  36397. // is greater than 100ms (this is enough to handle seek for VOD or level change for LIVE videos).
  36398. // More info here: https://github.com/video-dev/hls.js/issues/332#issuecomment-257986486
  36399. var audioTrack = tracks.audio;
  36400. var checkTimestampOffset = false;
  36401. if (type === 'audio' && (audioTrack === null || audioTrack === void 0 ? void 0 : audioTrack.container) === 'audio/mpeg') {
  36402. checkTimestampOffset = !this.lastMpegAudioChunk || chunkMeta.id === 1 || this.lastMpegAudioChunk.sn !== chunkMeta.sn;
  36403. this.lastMpegAudioChunk = chunkMeta;
  36404. }
  36405. var fragStart = frag.start;
  36406. var operation = {
  36407. execute: function execute() {
  36408. chunkStats.executeStart = self.performance.now();
  36409. if (checkTimestampOffset) {
  36410. var sb = _this5.sourceBuffer[type];
  36411. if (sb) {
  36412. var delta = fragStart - sb.timestampOffset;
  36413. if (Math.abs(delta) >= 0.1) {
  36414. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Updating audio SourceBuffer timestampOffset to " + fragStart + " (delta: " + delta + ") sn: " + frag.sn + ")");
  36415. sb.timestampOffset = fragStart;
  36416. }
  36417. }
  36418. }
  36419. _this5.appendExecutor(data, type);
  36420. },
  36421. onStart: function onStart() {
  36422. // logger.debug(`[buffer-controller]: ${type} SourceBuffer updatestart`);
  36423. },
  36424. onComplete: function onComplete() {
  36425. // logger.debug(`[buffer-controller]: ${type} SourceBuffer updateend`);
  36426. var end = self.performance.now();
  36427. chunkStats.executeEnd = chunkStats.end = end;
  36428. if (fragBuffering.first === 0) {
  36429. fragBuffering.first = end;
  36430. }
  36431. if (partBuffering && partBuffering.first === 0) {
  36432. partBuffering.first = end;
  36433. }
  36434. var sourceBuffer = _this5.sourceBuffer;
  36435. var timeRanges = {};
  36436. for (var _type in sourceBuffer) {
  36437. timeRanges[_type] = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(sourceBuffer[_type]);
  36438. }
  36439. _this5.appendError = 0;
  36440. _this5.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_APPENDED, {
  36441. type: type,
  36442. frag: frag,
  36443. part: part,
  36444. chunkMeta: chunkMeta,
  36445. parent: frag.type,
  36446. timeRanges: timeRanges
  36447. });
  36448. },
  36449. onError: function onError(err) {
  36450. // in case any error occured while appending, put back segment in segments table
  36451. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: Error encountered while trying to append to the " + type + " SourceBuffer", err);
  36452. var event = {
  36453. type: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,
  36454. parent: frag.type,
  36455. details: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_APPEND_ERROR,
  36456. err: err,
  36457. fatal: false
  36458. };
  36459. if (err.code === DOMException.QUOTA_EXCEEDED_ERR) {
  36460. // QuotaExceededError: http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
  36461. // let's stop appending any segments, and report BUFFER_FULL_ERROR error
  36462. event.details = _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_FULL_ERROR;
  36463. } else {
  36464. _this5.appendError++;
  36465. event.details = _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_APPEND_ERROR;
  36466. /* with UHD content, we could get loop of quota exceeded error until
  36467. browser is able to evict some data from sourcebuffer. Retrying can help recover.
  36468. */
  36469. if (_this5.appendError > hls.config.appendErrorMaxRetry) {
  36470. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: Failed " + hls.config.appendErrorMaxRetry + " times to append segment in sourceBuffer");
  36471. event.fatal = true;
  36472. hls.stopLoad();
  36473. }
  36474. }
  36475. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, event);
  36476. }
  36477. };
  36478. operationQueue.append(operation, type);
  36479. };
  36480. _proto.onBufferFlushing = function onBufferFlushing(event, data) {
  36481. var _this6 = this;
  36482. var operationQueue = this.operationQueue;
  36483. var flushOperation = function flushOperation(type) {
  36484. return {
  36485. execute: _this6.removeExecutor.bind(_this6, type, data.startOffset, data.endOffset),
  36486. onStart: function onStart() {
  36487. // logger.debug(`[buffer-controller]: Started flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`);
  36488. },
  36489. onComplete: function onComplete() {
  36490. // logger.debug(`[buffer-controller]: Finished flushing ${data.startOffset} -> ${data.endOffset} for ${type} Source Buffer`);
  36491. _this6.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHED, {
  36492. type: type
  36493. });
  36494. },
  36495. onError: function onError(e) {
  36496. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Failed to remove from " + type + " SourceBuffer", e);
  36497. }
  36498. };
  36499. };
  36500. if (data.type) {
  36501. operationQueue.append(flushOperation(data.type), data.type);
  36502. } else {
  36503. this.getSourceBufferTypes().forEach(function (type) {
  36504. operationQueue.append(flushOperation(type), type);
  36505. });
  36506. }
  36507. };
  36508. _proto.onFragParsed = function onFragParsed(event, data) {
  36509. var _this7 = this;
  36510. var frag = data.frag,
  36511. part = data.part;
  36512. var buffersAppendedTo = [];
  36513. var elementaryStreams = part ? part.elementaryStreams : frag.elementaryStreams;
  36514. if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__.ElementaryStreamTypes.AUDIOVIDEO]) {
  36515. buffersAppendedTo.push('audiovideo');
  36516. } else {
  36517. if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__.ElementaryStreamTypes.AUDIO]) {
  36518. buffersAppendedTo.push('audio');
  36519. }
  36520. if (elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_6__.ElementaryStreamTypes.VIDEO]) {
  36521. buffersAppendedTo.push('video');
  36522. }
  36523. }
  36524. var onUnblocked = function onUnblocked() {
  36525. var now = self.performance.now();
  36526. frag.stats.buffering.end = now;
  36527. if (part) {
  36528. part.stats.buffering.end = now;
  36529. }
  36530. var stats = part ? part.stats : frag.stats;
  36531. _this7.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_BUFFERED, {
  36532. frag: frag,
  36533. part: part,
  36534. stats: stats,
  36535. id: frag.type
  36536. });
  36537. };
  36538. if (buffersAppendedTo.length === 0) {
  36539. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("Fragments must have at least one ElementaryStreamType set. type: " + frag.type + " level: " + frag.level + " sn: " + frag.sn);
  36540. }
  36541. this.blockBuffers(onUnblocked, buffersAppendedTo);
  36542. };
  36543. _proto.onFragChanged = function onFragChanged(event, data) {
  36544. this.flushBackBuffer();
  36545. }
  36546. // on BUFFER_EOS mark matching sourcebuffer(s) as ended and trigger checkEos()
  36547. // an undefined data.type will mark all buffers as EOS.
  36548. ;
  36549. _proto.onBufferEos = function onBufferEos(event, data) {
  36550. var _this8 = this;
  36551. var ended = this.getSourceBufferTypes().reduce(function (acc, type) {
  36552. var sb = _this8.sourceBuffer[type];
  36553. if (sb && (!data.type || data.type === type)) {
  36554. sb.ending = true;
  36555. if (!sb.ended) {
  36556. sb.ended = true;
  36557. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: " + type + " sourceBuffer now EOS");
  36558. }
  36559. }
  36560. return acc && !!(!sb || sb.ended);
  36561. }, true);
  36562. if (ended) {
  36563. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Queueing mediaSource.endOfStream()");
  36564. this.blockBuffers(function () {
  36565. _this8.getSourceBufferTypes().forEach(function (type) {
  36566. var sb = _this8.sourceBuffer[type];
  36567. if (sb) {
  36568. sb.ending = false;
  36569. }
  36570. });
  36571. var mediaSource = _this8.mediaSource;
  36572. if (!mediaSource || mediaSource.readyState !== 'open') {
  36573. if (mediaSource) {
  36574. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.info("[buffer-controller]: Could not call mediaSource.endOfStream(). mediaSource.readyState: " + mediaSource.readyState);
  36575. }
  36576. return;
  36577. }
  36578. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Calling mediaSource.endOfStream()");
  36579. // Allow this to throw and be caught by the enqueueing function
  36580. mediaSource.endOfStream();
  36581. });
  36582. }
  36583. };
  36584. _proto.onLevelUpdated = function onLevelUpdated(event, _ref) {
  36585. var details = _ref.details;
  36586. if (!details.fragments.length) {
  36587. return;
  36588. }
  36589. this.details = details;
  36590. if (this.getSourceBufferTypes().length) {
  36591. this.blockBuffers(this.updateMediaElementDuration.bind(this));
  36592. } else {
  36593. this.updateMediaElementDuration();
  36594. }
  36595. };
  36596. _proto.flushBackBuffer = function flushBackBuffer() {
  36597. var hls = this.hls,
  36598. details = this.details,
  36599. media = this.media,
  36600. sourceBuffer = this.sourceBuffer;
  36601. if (!media || details === null) {
  36602. return;
  36603. }
  36604. var sourceBufferTypes = this.getSourceBufferTypes();
  36605. if (!sourceBufferTypes.length) {
  36606. return;
  36607. }
  36608. // Support for deprecated liveBackBufferLength
  36609. var backBufferLength = details.live && hls.config.liveBackBufferLength !== null ? hls.config.liveBackBufferLength : hls.config.backBufferLength;
  36610. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(backBufferLength) || backBufferLength < 0) {
  36611. return;
  36612. }
  36613. var currentTime = media.currentTime;
  36614. var targetDuration = details.levelTargetDuration;
  36615. var maxBackBufferLength = Math.max(backBufferLength, targetDuration);
  36616. var targetBackBufferPosition = Math.floor(currentTime / targetDuration) * targetDuration - maxBackBufferLength;
  36617. sourceBufferTypes.forEach(function (type) {
  36618. var sb = sourceBuffer[type];
  36619. if (sb) {
  36620. var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(sb);
  36621. // when target buffer start exceeds actual buffer start
  36622. if (buffered.length > 0 && targetBackBufferPosition > buffered.start(0)) {
  36623. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BACK_BUFFER_REACHED, {
  36624. bufferEnd: targetBackBufferPosition
  36625. });
  36626. // Support for deprecated event:
  36627. if (details.live) {
  36628. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LIVE_BACK_BUFFER_REACHED, {
  36629. bufferEnd: targetBackBufferPosition
  36630. });
  36631. } else if (sb.ended && buffered.end(buffered.length - 1) - currentTime < targetDuration * 2) {
  36632. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.info("[buffer-controller]: Cannot flush " + type + " back buffer while SourceBuffer is in ended state");
  36633. return;
  36634. }
  36635. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, {
  36636. startOffset: 0,
  36637. endOffset: targetBackBufferPosition,
  36638. type: type
  36639. });
  36640. }
  36641. }
  36642. });
  36643. }
  36644. /**
  36645. * Update Media Source duration to current level duration or override to Infinity if configuration parameter
  36646. * 'liveDurationInfinity` is set to `true`
  36647. * More details: https://github.com/video-dev/hls.js/issues/355
  36648. */;
  36649. _proto.updateMediaElementDuration = function updateMediaElementDuration() {
  36650. if (!this.details || !this.media || !this.mediaSource || this.mediaSource.readyState !== 'open') {
  36651. return;
  36652. }
  36653. var details = this.details,
  36654. hls = this.hls,
  36655. media = this.media,
  36656. mediaSource = this.mediaSource;
  36657. var levelDuration = details.fragments[0].start + details.totalduration;
  36658. var mediaDuration = media.duration;
  36659. var msDuration = (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mediaSource.duration) ? mediaSource.duration : 0;
  36660. if (details.live && hls.config.liveDurationInfinity) {
  36661. // Override duration to Infinity
  36662. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Media Source duration is set to Infinity');
  36663. mediaSource.duration = Infinity;
  36664. this.updateSeekableRange(details);
  36665. } else if (levelDuration > msDuration && levelDuration > mediaDuration || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mediaDuration)) {
  36666. // levelDuration was the last value we set.
  36667. // not using mediaSource.duration as the browser may tweak this value
  36668. // only update Media Source duration if its value increase, this is to avoid
  36669. // flushing already buffered portion when switching between quality level
  36670. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Updating Media Source duration to " + levelDuration.toFixed(3));
  36671. mediaSource.duration = levelDuration;
  36672. }
  36673. };
  36674. _proto.updateSeekableRange = function updateSeekableRange(levelDetails) {
  36675. var mediaSource = this.mediaSource;
  36676. var fragments = levelDetails.fragments;
  36677. var len = fragments.length;
  36678. if (len && levelDetails.live && mediaSource !== null && mediaSource !== void 0 && mediaSource.setLiveSeekableRange) {
  36679. var start = Math.max(0, fragments[0].start);
  36680. var end = Math.max(start, start + levelDetails.totalduration);
  36681. mediaSource.setLiveSeekableRange(start, end);
  36682. }
  36683. };
  36684. _proto.checkPendingTracks = function checkPendingTracks() {
  36685. var bufferCodecEventsExpected = this.bufferCodecEventsExpected,
  36686. operationQueue = this.operationQueue,
  36687. pendingTracks = this.pendingTracks;
  36688. // Check if we've received all of the expected bufferCodec events. When none remain, create all the sourceBuffers at once.
  36689. // This is important because the MSE spec allows implementations to throw QuotaExceededErrors if creating new sourceBuffers after
  36690. // data has been appended to existing ones.
  36691. // 2 tracks is the max (one for audio, one for video). If we've reach this max go ahead and create the buffers.
  36692. var pendingTracksCount = Object.keys(pendingTracks).length;
  36693. if (pendingTracksCount && !bufferCodecEventsExpected || pendingTracksCount === 2) {
  36694. // ok, let's create them now !
  36695. this.createSourceBuffers(pendingTracks);
  36696. this.pendingTracks = {};
  36697. // append any pending segments now !
  36698. var buffers = this.getSourceBufferTypes();
  36699. if (buffers.length === 0) {
  36700. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  36701. type: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,
  36702. details: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_INCOMPATIBLE_CODECS_ERROR,
  36703. fatal: true,
  36704. reason: 'could not create source buffer for media codec(s)'
  36705. });
  36706. return;
  36707. }
  36708. buffers.forEach(function (type) {
  36709. operationQueue.executeNext(type);
  36710. });
  36711. }
  36712. };
  36713. _proto.createSourceBuffers = function createSourceBuffers(tracks) {
  36714. var sourceBuffer = this.sourceBuffer,
  36715. mediaSource = this.mediaSource;
  36716. if (!mediaSource) {
  36717. throw Error('createSourceBuffers called when mediaSource was null');
  36718. }
  36719. var tracksCreated = 0;
  36720. for (var trackName in tracks) {
  36721. if (!sourceBuffer[trackName]) {
  36722. var track = tracks[trackName];
  36723. if (!track) {
  36724. throw Error("source buffer exists for track " + trackName + ", however track does not");
  36725. }
  36726. // use levelCodec as first priority
  36727. var codec = track.levelCodec || track.codec;
  36728. var mimeType = track.container + ";codecs=" + codec;
  36729. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: creating sourceBuffer(" + mimeType + ")");
  36730. try {
  36731. var sb = sourceBuffer[trackName] = mediaSource.addSourceBuffer(mimeType);
  36732. var sbName = trackName;
  36733. this.addBufferListener(sbName, 'updatestart', this._onSBUpdateStart);
  36734. this.addBufferListener(sbName, 'updateend', this._onSBUpdateEnd);
  36735. this.addBufferListener(sbName, 'error', this._onSBUpdateError);
  36736. this.tracks[trackName] = {
  36737. buffer: sb,
  36738. codec: codec,
  36739. container: track.container,
  36740. levelCodec: track.levelCodec,
  36741. metadata: track.metadata,
  36742. id: track.id
  36743. };
  36744. tracksCreated++;
  36745. } catch (err) {
  36746. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: error while trying to add sourceBuffer: " + err.message);
  36747. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  36748. type: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,
  36749. details: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_ADD_CODEC_ERROR,
  36750. fatal: false,
  36751. error: err,
  36752. mimeType: mimeType
  36753. });
  36754. }
  36755. }
  36756. }
  36757. if (tracksCreated) {
  36758. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_CREATED, {
  36759. tracks: this.tracks
  36760. });
  36761. }
  36762. }
  36763. // Keep as arrow functions so that we can directly reference these functions directly as event listeners
  36764. ;
  36765. _proto._onSBUpdateStart = function _onSBUpdateStart(type) {
  36766. var operationQueue = this.operationQueue;
  36767. var operation = operationQueue.current(type);
  36768. operation.onStart();
  36769. };
  36770. _proto._onSBUpdateEnd = function _onSBUpdateEnd(type) {
  36771. var operationQueue = this.operationQueue;
  36772. var operation = operationQueue.current(type);
  36773. operation.onComplete();
  36774. operationQueue.shiftAndExecuteNext(type);
  36775. };
  36776. _proto._onSBUpdateError = function _onSBUpdateError(type, event) {
  36777. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error("[buffer-controller]: " + type + " SourceBuffer error", event);
  36778. // according to http://www.w3.org/TR/media-source/#sourcebuffer-append-error
  36779. // SourceBuffer errors are not necessarily fatal; if so, the HTMLMediaElement will fire an error event
  36780. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  36781. type: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorTypes.MEDIA_ERROR,
  36782. details: _errors__WEBPACK_IMPORTED_MODULE_3__.ErrorDetails.BUFFER_APPENDING_ERROR,
  36783. fatal: false
  36784. });
  36785. // updateend is always fired after error, so we'll allow that to shift the current operation off of the queue
  36786. var operation = this.operationQueue.current(type);
  36787. if (operation) {
  36788. operation.onError(event);
  36789. }
  36790. }
  36791. // This method must result in an updateend event; if remove is not called, _onSBUpdateEnd must be called manually
  36792. ;
  36793. _proto.removeExecutor = function removeExecutor(type, startOffset, endOffset) {
  36794. var media = this.media,
  36795. mediaSource = this.mediaSource,
  36796. operationQueue = this.operationQueue,
  36797. sourceBuffer = this.sourceBuffer;
  36798. var sb = sourceBuffer[type];
  36799. if (!media || !mediaSource || !sb) {
  36800. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Attempting to remove from the " + type + " SourceBuffer, but it does not exist");
  36801. operationQueue.shiftAndExecuteNext(type);
  36802. return;
  36803. }
  36804. var mediaDuration = (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(media.duration) ? media.duration : Infinity;
  36805. var msDuration = (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mediaSource.duration) ? mediaSource.duration : Infinity;
  36806. var removeStart = Math.max(0, startOffset);
  36807. var removeEnd = Math.min(endOffset, mediaDuration, msDuration);
  36808. if (removeEnd > removeStart && !sb.ending) {
  36809. sb.ended = false;
  36810. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log("[buffer-controller]: Removing [" + removeStart + "," + removeEnd + "] from the " + type + " SourceBuffer");
  36811. console.assert(!sb.updating, type + " sourceBuffer must not be updating");
  36812. sb.remove(removeStart, removeEnd);
  36813. } else {
  36814. // Cycle the queue
  36815. operationQueue.shiftAndExecuteNext(type);
  36816. }
  36817. }
  36818. // This method must result in an updateend event; if append is not called, _onSBUpdateEnd must be called manually
  36819. ;
  36820. _proto.appendExecutor = function appendExecutor(data, type) {
  36821. var operationQueue = this.operationQueue,
  36822. sourceBuffer = this.sourceBuffer;
  36823. var sb = sourceBuffer[type];
  36824. if (!sb) {
  36825. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("[buffer-controller]: Attempting to append to the " + type + " SourceBuffer, but it does not exist");
  36826. operationQueue.shiftAndExecuteNext(type);
  36827. return;
  36828. }
  36829. sb.ended = false;
  36830. console.assert(!sb.updating, type + " sourceBuffer must not be updating");
  36831. sb.appendBuffer(data);
  36832. }
  36833. // Enqueues an operation to each SourceBuffer queue which, upon execution, resolves a promise. When all promises
  36834. // resolve, the onUnblocked function is executed. Functions calling this method do not need to unblock the queue
  36835. // upon completion, since we already do it here
  36836. ;
  36837. _proto.blockBuffers = function blockBuffers(onUnblocked, buffers) {
  36838. var _this9 = this;
  36839. if (buffers === void 0) {
  36840. buffers = this.getSourceBufferTypes();
  36841. }
  36842. if (!buffers.length) {
  36843. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('[buffer-controller]: Blocking operation requested, but no SourceBuffers exist');
  36844. Promise.resolve().then(onUnblocked);
  36845. return;
  36846. }
  36847. var operationQueue = this.operationQueue;
  36848. // logger.debug(`[buffer-controller]: Blocking ${buffers} SourceBuffer`);
  36849. var blockingOperations = buffers.map(function (type) {
  36850. return operationQueue.appendBlocker(type);
  36851. });
  36852. Promise.all(blockingOperations).then(function () {
  36853. // logger.debug(`[buffer-controller]: Blocking operation resolved; unblocking ${buffers} SourceBuffer`);
  36854. onUnblocked();
  36855. buffers.forEach(function (type) {
  36856. var sb = _this9.sourceBuffer[type];
  36857. // Only cycle the queue if the SB is not updating. There's a bug in Chrome which sets the SB updating flag to
  36858. // true when changing the MediaSource duration (https://bugs.chromium.org/p/chromium/issues/detail?id=959359&can=2&q=mediasource%20duration)
  36859. // While this is a workaround, it's probably useful to have around
  36860. if (!sb || !sb.updating) {
  36861. operationQueue.shiftAndExecuteNext(type);
  36862. }
  36863. });
  36864. });
  36865. };
  36866. _proto.getSourceBufferTypes = function getSourceBufferTypes() {
  36867. return Object.keys(this.sourceBuffer);
  36868. };
  36869. _proto.addBufferListener = function addBufferListener(type, event, fn) {
  36870. var buffer = this.sourceBuffer[type];
  36871. if (!buffer) {
  36872. return;
  36873. }
  36874. var listener = fn.bind(this, type);
  36875. this.listeners[type].push({
  36876. event: event,
  36877. listener: listener
  36878. });
  36879. buffer.addEventListener(event, listener);
  36880. };
  36881. _proto.removeBufferListeners = function removeBufferListeners(type) {
  36882. var buffer = this.sourceBuffer[type];
  36883. if (!buffer) {
  36884. return;
  36885. }
  36886. this.listeners[type].forEach(function (l) {
  36887. buffer.removeEventListener(l.event, l.listener);
  36888. });
  36889. };
  36890. return BufferController;
  36891. }();
  36892. /***/ }),
  36893. /***/ "./src/controller/buffer-operation-queue.ts":
  36894. /*!**************************************************!*\
  36895. !*** ./src/controller/buffer-operation-queue.ts ***!
  36896. \**************************************************/
  36897. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  36898. "use strict";
  36899. __webpack_require__.r(__webpack_exports__);
  36900. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  36901. /* harmony export */ "default": () => (/* binding */ BufferOperationQueue)
  36902. /* harmony export */ });
  36903. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  36904. var BufferOperationQueue = /*#__PURE__*/function () {
  36905. function BufferOperationQueue(sourceBufferReference) {
  36906. this.buffers = void 0;
  36907. this.queues = {
  36908. video: [],
  36909. audio: [],
  36910. audiovideo: []
  36911. };
  36912. this.buffers = sourceBufferReference;
  36913. }
  36914. var _proto = BufferOperationQueue.prototype;
  36915. _proto.append = function append(operation, type) {
  36916. var queue = this.queues[type];
  36917. queue.push(operation);
  36918. if (queue.length === 1 && this.buffers[type]) {
  36919. this.executeNext(type);
  36920. }
  36921. };
  36922. _proto.insertAbort = function insertAbort(operation, type) {
  36923. var queue = this.queues[type];
  36924. queue.unshift(operation);
  36925. this.executeNext(type);
  36926. };
  36927. _proto.appendBlocker = function appendBlocker(type) {
  36928. var execute;
  36929. var promise = new Promise(function (resolve) {
  36930. execute = resolve;
  36931. });
  36932. var operation = {
  36933. execute: execute,
  36934. onStart: function onStart() {},
  36935. onComplete: function onComplete() {},
  36936. onError: function onError() {}
  36937. };
  36938. this.append(operation, type);
  36939. return promise;
  36940. };
  36941. _proto.executeNext = function executeNext(type) {
  36942. var buffers = this.buffers,
  36943. queues = this.queues;
  36944. var sb = buffers[type];
  36945. var queue = queues[type];
  36946. if (queue.length) {
  36947. var operation = queue[0];
  36948. try {
  36949. // Operations are expected to result in an 'updateend' event being fired. If not, the queue will lock. Operations
  36950. // which do not end with this event must call _onSBUpdateEnd manually
  36951. operation.execute();
  36952. } catch (e) {
  36953. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.warn('[buffer-operation-queue]: Unhandled exception executing the current operation');
  36954. operation.onError(e);
  36955. // Only shift the current operation off, otherwise the updateend handler will do this for us
  36956. if (!sb || !sb.updating) {
  36957. queue.shift();
  36958. this.executeNext(type);
  36959. }
  36960. }
  36961. }
  36962. };
  36963. _proto.shiftAndExecuteNext = function shiftAndExecuteNext(type) {
  36964. this.queues[type].shift();
  36965. this.executeNext(type);
  36966. };
  36967. _proto.current = function current(type) {
  36968. return this.queues[type][0];
  36969. };
  36970. return BufferOperationQueue;
  36971. }();
  36972. /***/ }),
  36973. /***/ "./src/controller/cap-level-controller.ts":
  36974. /*!************************************************!*\
  36975. !*** ./src/controller/cap-level-controller.ts ***!
  36976. \************************************************/
  36977. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  36978. "use strict";
  36979. __webpack_require__.r(__webpack_exports__);
  36980. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  36981. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  36982. /* harmony export */ });
  36983. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  36984. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  36985. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  36986. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  36987. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  36988. /*
  36989. * cap stream level to media size dimension controller
  36990. */
  36991. var CapLevelController = /*#__PURE__*/function () {
  36992. function CapLevelController(hls) {
  36993. this.autoLevelCapping = void 0;
  36994. this.firstLevel = void 0;
  36995. this.media = void 0;
  36996. this.restrictedLevels = void 0;
  36997. this.timer = void 0;
  36998. this.hls = void 0;
  36999. this.streamController = void 0;
  37000. this.clientRect = void 0;
  37001. this.hls = hls;
  37002. this.autoLevelCapping = Number.POSITIVE_INFINITY;
  37003. this.firstLevel = -1;
  37004. this.media = null;
  37005. this.restrictedLevels = [];
  37006. this.timer = undefined;
  37007. this.clientRect = null;
  37008. this.registerListeners();
  37009. }
  37010. var _proto = CapLevelController.prototype;
  37011. _proto.setStreamController = function setStreamController(streamController) {
  37012. this.streamController = streamController;
  37013. };
  37014. _proto.destroy = function destroy() {
  37015. this.unregisterListener();
  37016. if (this.hls.config.capLevelToPlayerSize) {
  37017. this.stopCapping();
  37018. }
  37019. this.media = null;
  37020. this.clientRect = null;
  37021. // @ts-ignore
  37022. this.hls = this.streamController = null;
  37023. };
  37024. _proto.registerListeners = function registerListeners() {
  37025. var hls = this.hls;
  37026. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this);
  37027. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  37028. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  37029. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CODECS, this.onBufferCodecs, this);
  37030. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  37031. };
  37032. _proto.unregisterListener = function unregisterListener() {
  37033. var hls = this.hls;
  37034. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP_LEVEL_CAPPING, this.onFpsDropLevelCapping, this);
  37035. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  37036. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  37037. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CODECS, this.onBufferCodecs, this);
  37038. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  37039. };
  37040. _proto.onFpsDropLevelCapping = function onFpsDropLevelCapping(event, data) {
  37041. // Don't add a restricted level more than once
  37042. if (CapLevelController.isLevelAllowed(data.droppedLevel, this.restrictedLevels)) {
  37043. this.restrictedLevels.push(data.droppedLevel);
  37044. }
  37045. };
  37046. _proto.onMediaAttaching = function onMediaAttaching(event, data) {
  37047. this.media = data.media instanceof HTMLVideoElement ? data.media : null;
  37048. this.clientRect = null;
  37049. };
  37050. _proto.onManifestParsed = function onManifestParsed(event, data) {
  37051. var hls = this.hls;
  37052. this.restrictedLevels = [];
  37053. this.firstLevel = data.firstLevel;
  37054. if (hls.config.capLevelToPlayerSize && data.video) {
  37055. // Start capping immediately if the manifest has signaled video codecs
  37056. this.startCapping();
  37057. }
  37058. }
  37059. // Only activate capping when playing a video stream; otherwise, multi-bitrate audio-only streams will be restricted
  37060. // to the first level
  37061. ;
  37062. _proto.onBufferCodecs = function onBufferCodecs(event, data) {
  37063. var hls = this.hls;
  37064. if (hls.config.capLevelToPlayerSize && data.video) {
  37065. // If the manifest did not signal a video codec capping has been deferred until we're certain video is present
  37066. this.startCapping();
  37067. }
  37068. };
  37069. _proto.onMediaDetaching = function onMediaDetaching() {
  37070. this.stopCapping();
  37071. };
  37072. _proto.detectPlayerSize = function detectPlayerSize() {
  37073. if (this.media && this.mediaHeight > 0 && this.mediaWidth > 0) {
  37074. var levels = this.hls.levels;
  37075. if (levels.length) {
  37076. var hls = this.hls;
  37077. hls.autoLevelCapping = this.getMaxLevel(levels.length - 1);
  37078. if (hls.autoLevelCapping > this.autoLevelCapping && this.streamController) {
  37079. // if auto level capping has a higher value for the previous one, flush the buffer using nextLevelSwitch
  37080. // usually happen when the user go to the fullscreen mode.
  37081. this.streamController.nextLevelSwitch();
  37082. }
  37083. this.autoLevelCapping = hls.autoLevelCapping;
  37084. }
  37085. }
  37086. }
  37087. /*
  37088. * returns level should be the one with the dimensions equal or greater than the media (player) dimensions (so the video will be downscaled)
  37089. */;
  37090. _proto.getMaxLevel = function getMaxLevel(capLevelIndex) {
  37091. var _this = this;
  37092. var levels = this.hls.levels;
  37093. if (!levels.length) {
  37094. return -1;
  37095. }
  37096. var validLevels = levels.filter(function (level, index) {
  37097. return CapLevelController.isLevelAllowed(index, _this.restrictedLevels) && index <= capLevelIndex;
  37098. });
  37099. this.clientRect = null;
  37100. return CapLevelController.getMaxLevelByMediaSize(validLevels, this.mediaWidth, this.mediaHeight);
  37101. };
  37102. _proto.startCapping = function startCapping() {
  37103. if (this.timer) {
  37104. // Don't reset capping if started twice; this can happen if the manifest signals a video codec
  37105. return;
  37106. }
  37107. this.autoLevelCapping = Number.POSITIVE_INFINITY;
  37108. this.hls.firstLevel = this.getMaxLevel(this.firstLevel);
  37109. self.clearInterval(this.timer);
  37110. this.timer = self.setInterval(this.detectPlayerSize.bind(this), 1000);
  37111. this.detectPlayerSize();
  37112. };
  37113. _proto.stopCapping = function stopCapping() {
  37114. this.restrictedLevels = [];
  37115. this.firstLevel = -1;
  37116. this.autoLevelCapping = Number.POSITIVE_INFINITY;
  37117. if (this.timer) {
  37118. self.clearInterval(this.timer);
  37119. this.timer = undefined;
  37120. }
  37121. };
  37122. _proto.getDimensions = function getDimensions() {
  37123. if (this.clientRect) {
  37124. return this.clientRect;
  37125. }
  37126. var media = this.media;
  37127. var boundsRect = {
  37128. width: 0,
  37129. height: 0
  37130. };
  37131. if (media) {
  37132. var clientRect = media.getBoundingClientRect();
  37133. boundsRect.width = clientRect.width;
  37134. boundsRect.height = clientRect.height;
  37135. if (!boundsRect.width && !boundsRect.height) {
  37136. // When the media element has no width or height (equivalent to not being in the DOM),
  37137. // then use its width and height attributes (media.width, media.height)
  37138. boundsRect.width = clientRect.right - clientRect.left || media.width || 0;
  37139. boundsRect.height = clientRect.bottom - clientRect.top || media.height || 0;
  37140. }
  37141. }
  37142. this.clientRect = boundsRect;
  37143. return boundsRect;
  37144. };
  37145. CapLevelController.isLevelAllowed = function isLevelAllowed(level, restrictedLevels) {
  37146. if (restrictedLevels === void 0) {
  37147. restrictedLevels = [];
  37148. }
  37149. return restrictedLevels.indexOf(level) === -1;
  37150. };
  37151. CapLevelController.getMaxLevelByMediaSize = function getMaxLevelByMediaSize(levels, width, height) {
  37152. if (!levels || !levels.length) {
  37153. return -1;
  37154. }
  37155. // Levels can have the same dimensions but differing bandwidths - since levels are ordered, we can look to the next
  37156. // to determine whether we've chosen the greatest bandwidth for the media's dimensions
  37157. var atGreatestBandwidth = function atGreatestBandwidth(curLevel, nextLevel) {
  37158. if (!nextLevel) {
  37159. return true;
  37160. }
  37161. return curLevel.width !== nextLevel.width || curLevel.height !== nextLevel.height;
  37162. };
  37163. // If we run through the loop without breaking, the media's dimensions are greater than every level, so default to
  37164. // the max level
  37165. var maxLevelIndex = levels.length - 1;
  37166. for (var i = 0; i < levels.length; i += 1) {
  37167. var level = levels[i];
  37168. if ((level.width >= width || level.height >= height) && atGreatestBandwidth(level, levels[i + 1])) {
  37169. maxLevelIndex = i;
  37170. break;
  37171. }
  37172. }
  37173. return maxLevelIndex;
  37174. };
  37175. _createClass(CapLevelController, [{
  37176. key: "mediaWidth",
  37177. get: function get() {
  37178. return this.getDimensions().width * this.contentScaleFactor;
  37179. }
  37180. }, {
  37181. key: "mediaHeight",
  37182. get: function get() {
  37183. return this.getDimensions().height * this.contentScaleFactor;
  37184. }
  37185. }, {
  37186. key: "contentScaleFactor",
  37187. get: function get() {
  37188. var pixelRatio = 1;
  37189. if (!this.hls.config.ignoreDevicePixelRatio) {
  37190. try {
  37191. pixelRatio = self.devicePixelRatio;
  37192. } catch (e) {
  37193. /* no-op */
  37194. }
  37195. }
  37196. return pixelRatio;
  37197. }
  37198. }]);
  37199. return CapLevelController;
  37200. }();
  37201. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (CapLevelController);
  37202. /***/ }),
  37203. /***/ "./src/controller/cmcd-controller.ts":
  37204. /*!*******************************************!*\
  37205. !*** ./src/controller/cmcd-controller.ts ***!
  37206. \*******************************************/
  37207. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  37208. "use strict";
  37209. __webpack_require__.r(__webpack_exports__);
  37210. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  37211. /* harmony export */ "default": () => (/* binding */ CMCDController)
  37212. /* harmony export */ });
  37213. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  37214. /* harmony import */ var _types_cmcd__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/cmcd */ "./src/types/cmcd.ts");
  37215. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  37216. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  37217. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  37218. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  37219. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  37220. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  37221. function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
  37222. function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
  37223. function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
  37224. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  37225. /**
  37226. * Controller to deal with Common Media Client Data (CMCD)
  37227. * @see https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf
  37228. */
  37229. var CMCDController = /*#__PURE__*/function () {
  37230. // eslint-disable-line no-restricted-globals
  37231. // eslint-disable-line no-restricted-globals
  37232. function CMCDController(hls) {
  37233. var _this = this;
  37234. this.hls = void 0;
  37235. this.config = void 0;
  37236. this.media = void 0;
  37237. this.sid = void 0;
  37238. this.cid = void 0;
  37239. this.useHeaders = false;
  37240. this.initialized = false;
  37241. this.starved = false;
  37242. this.buffering = true;
  37243. this.audioBuffer = void 0;
  37244. this.videoBuffer = void 0;
  37245. this.onWaiting = function () {
  37246. if (_this.initialized) {
  37247. _this.starved = true;
  37248. }
  37249. _this.buffering = true;
  37250. };
  37251. this.onPlaying = function () {
  37252. if (!_this.initialized) {
  37253. _this.initialized = true;
  37254. }
  37255. _this.buffering = false;
  37256. };
  37257. this.applyPlaylistData = function (context) {
  37258. try {
  37259. _this.apply(context, {
  37260. ot: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MANIFEST,
  37261. su: !_this.initialized
  37262. });
  37263. } catch (error) {
  37264. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Could not generate manifest CMCD data.', error);
  37265. }
  37266. };
  37267. this.applyFragmentData = function (context) {
  37268. try {
  37269. var fragment = context.frag;
  37270. var level = _this.hls.levels[fragment.level];
  37271. var ot = _this.getObjectType(fragment);
  37272. var data = {
  37273. d: fragment.duration * 1000,
  37274. ot: ot
  37275. };
  37276. if (ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.VIDEO || ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO || ot == _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MUXED) {
  37277. data.br = level.bitrate / 1000;
  37278. data.tb = _this.getTopBandwidth(ot) / 1000;
  37279. data.bl = _this.getBufferLength(ot);
  37280. }
  37281. _this.apply(context, data);
  37282. } catch (error) {
  37283. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Could not generate segment CMCD data.', error);
  37284. }
  37285. };
  37286. this.hls = hls;
  37287. var config = this.config = hls.config;
  37288. var cmcd = config.cmcd;
  37289. if (cmcd != null) {
  37290. config.pLoader = this.createPlaylistLoader();
  37291. config.fLoader = this.createFragmentLoader();
  37292. this.sid = cmcd.sessionId || CMCDController.uuid();
  37293. this.cid = cmcd.contentId;
  37294. this.useHeaders = cmcd.useHeaders === true;
  37295. this.registerListeners();
  37296. }
  37297. }
  37298. var _proto = CMCDController.prototype;
  37299. _proto.registerListeners = function registerListeners() {
  37300. var hls = this.hls;
  37301. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  37302. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED, this.onMediaDetached, this);
  37303. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CREATED, this.onBufferCreated, this);
  37304. };
  37305. _proto.unregisterListeners = function unregisterListeners() {
  37306. var hls = this.hls;
  37307. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  37308. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED, this.onMediaDetached, this);
  37309. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_CREATED, this.onBufferCreated, this);
  37310. this.onMediaDetached();
  37311. };
  37312. _proto.destroy = function destroy() {
  37313. this.unregisterListeners();
  37314. // @ts-ignore
  37315. this.hls = this.config = this.audioBuffer = this.videoBuffer = null;
  37316. };
  37317. _proto.onMediaAttached = function onMediaAttached(event, data) {
  37318. this.media = data.media;
  37319. this.media.addEventListener('waiting', this.onWaiting);
  37320. this.media.addEventListener('playing', this.onPlaying);
  37321. };
  37322. _proto.onMediaDetached = function onMediaDetached() {
  37323. if (!this.media) {
  37324. return;
  37325. }
  37326. this.media.removeEventListener('waiting', this.onWaiting);
  37327. this.media.removeEventListener('playing', this.onPlaying);
  37328. // @ts-ignore
  37329. this.media = null;
  37330. };
  37331. _proto.onBufferCreated = function onBufferCreated(event, data) {
  37332. var _data$tracks$audio, _data$tracks$video;
  37333. this.audioBuffer = (_data$tracks$audio = data.tracks.audio) === null || _data$tracks$audio === void 0 ? void 0 : _data$tracks$audio.buffer;
  37334. this.videoBuffer = (_data$tracks$video = data.tracks.video) === null || _data$tracks$video === void 0 ? void 0 : _data$tracks$video.buffer;
  37335. };
  37336. /**
  37337. * Create baseline CMCD data
  37338. */
  37339. _proto.createData = function createData() {
  37340. var _this$media;
  37341. return {
  37342. v: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDVersion,
  37343. sf: _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDStreamingFormat.HLS,
  37344. sid: this.sid,
  37345. cid: this.cid,
  37346. pr: (_this$media = this.media) === null || _this$media === void 0 ? void 0 : _this$media.playbackRate,
  37347. mtp: this.hls.bandwidthEstimate / 1000
  37348. };
  37349. }
  37350. /**
  37351. * Apply CMCD data to a request.
  37352. */;
  37353. _proto.apply = function apply(context, data) {
  37354. if (data === void 0) {
  37355. data = {};
  37356. }
  37357. // apply baseline data
  37358. _extends(data, this.createData());
  37359. var isVideo = data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.INIT || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.VIDEO || data.ot === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MUXED;
  37360. if (this.starved && isVideo) {
  37361. data.bs = true;
  37362. data.su = true;
  37363. this.starved = false;
  37364. }
  37365. if (data.su == null) {
  37366. data.su = this.buffering;
  37367. }
  37368. // TODO: Implement rtp, nrr, nor, dl
  37369. if (this.useHeaders) {
  37370. var headers = CMCDController.toHeaders(data);
  37371. if (!Object.keys(headers).length) {
  37372. return;
  37373. }
  37374. if (!context.headers) {
  37375. context.headers = {};
  37376. }
  37377. _extends(context.headers, headers);
  37378. } else {
  37379. var query = CMCDController.toQuery(data);
  37380. if (!query) {
  37381. return;
  37382. }
  37383. context.url = CMCDController.appendQueryToUri(context.url, query);
  37384. }
  37385. }
  37386. /**
  37387. * Apply CMCD data to a manifest request.
  37388. */;
  37389. /**
  37390. * The CMCD object type.
  37391. */
  37392. _proto.getObjectType = function getObjectType(fragment) {
  37393. var type = fragment.type;
  37394. if (type === 'subtitle') {
  37395. return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.TIMED_TEXT;
  37396. }
  37397. if (fragment.sn === 'initSegment') {
  37398. return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.INIT;
  37399. }
  37400. if (type === 'audio') {
  37401. return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO;
  37402. }
  37403. if (type === 'main') {
  37404. if (!this.hls.audioTracks.length) {
  37405. return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.MUXED;
  37406. }
  37407. return _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.VIDEO;
  37408. }
  37409. return undefined;
  37410. }
  37411. /**
  37412. * Get the highest bitrate.
  37413. */;
  37414. _proto.getTopBandwidth = function getTopBandwidth(type) {
  37415. var bitrate = 0;
  37416. var levels;
  37417. var hls = this.hls;
  37418. if (type === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO) {
  37419. levels = hls.audioTracks;
  37420. } else {
  37421. var max = hls.maxAutoLevel;
  37422. var len = max > -1 ? max + 1 : hls.levels.length;
  37423. levels = hls.levels.slice(0, len);
  37424. }
  37425. for (var _iterator = _createForOfIteratorHelperLoose(levels), _step; !(_step = _iterator()).done;) {
  37426. var level = _step.value;
  37427. if (level.bitrate > bitrate) {
  37428. bitrate = level.bitrate;
  37429. }
  37430. }
  37431. return bitrate > 0 ? bitrate : NaN;
  37432. }
  37433. /**
  37434. * Get the buffer length for a media type in milliseconds
  37435. */;
  37436. _proto.getBufferLength = function getBufferLength(type) {
  37437. var media = this.hls.media;
  37438. var buffer = type === _types_cmcd__WEBPACK_IMPORTED_MODULE_1__.CMCDObjectType.AUDIO ? this.audioBuffer : this.videoBuffer;
  37439. if (!buffer || !media) {
  37440. return NaN;
  37441. }
  37442. var info = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_2__.BufferHelper.bufferInfo(buffer, media.currentTime, this.config.maxBufferHole);
  37443. return info.len * 1000;
  37444. }
  37445. /**
  37446. * Create a playlist loader
  37447. */;
  37448. _proto.createPlaylistLoader = function createPlaylistLoader() {
  37449. var pLoader = this.config.pLoader;
  37450. var apply = this.applyPlaylistData;
  37451. var Ctor = pLoader || this.config.loader;
  37452. return /*#__PURE__*/function () {
  37453. function CmcdPlaylistLoader(config) {
  37454. this.loader = void 0;
  37455. this.loader = new Ctor(config);
  37456. }
  37457. var _proto2 = CmcdPlaylistLoader.prototype;
  37458. _proto2.destroy = function destroy() {
  37459. this.loader.destroy();
  37460. };
  37461. _proto2.abort = function abort() {
  37462. this.loader.abort();
  37463. };
  37464. _proto2.load = function load(context, config, callbacks) {
  37465. apply(context);
  37466. this.loader.load(context, config, callbacks);
  37467. };
  37468. _createClass(CmcdPlaylistLoader, [{
  37469. key: "stats",
  37470. get: function get() {
  37471. return this.loader.stats;
  37472. }
  37473. }, {
  37474. key: "context",
  37475. get: function get() {
  37476. return this.loader.context;
  37477. }
  37478. }]);
  37479. return CmcdPlaylistLoader;
  37480. }();
  37481. }
  37482. /**
  37483. * Create a playlist loader
  37484. */;
  37485. _proto.createFragmentLoader = function createFragmentLoader() {
  37486. var fLoader = this.config.fLoader;
  37487. var apply = this.applyFragmentData;
  37488. var Ctor = fLoader || this.config.loader;
  37489. return /*#__PURE__*/function () {
  37490. function CmcdFragmentLoader(config) {
  37491. this.loader = void 0;
  37492. this.loader = new Ctor(config);
  37493. }
  37494. var _proto3 = CmcdFragmentLoader.prototype;
  37495. _proto3.destroy = function destroy() {
  37496. this.loader.destroy();
  37497. };
  37498. _proto3.abort = function abort() {
  37499. this.loader.abort();
  37500. };
  37501. _proto3.load = function load(context, config, callbacks) {
  37502. apply(context);
  37503. this.loader.load(context, config, callbacks);
  37504. };
  37505. _createClass(CmcdFragmentLoader, [{
  37506. key: "stats",
  37507. get: function get() {
  37508. return this.loader.stats;
  37509. }
  37510. }, {
  37511. key: "context",
  37512. get: function get() {
  37513. return this.loader.context;
  37514. }
  37515. }]);
  37516. return CmcdFragmentLoader;
  37517. }();
  37518. }
  37519. /**
  37520. * Generate a random v4 UUI
  37521. *
  37522. * @returns {string}
  37523. */;
  37524. CMCDController.uuid = function uuid() {
  37525. var url = URL.createObjectURL(new Blob());
  37526. var uuid = url.toString();
  37527. URL.revokeObjectURL(url);
  37528. return uuid.slice(uuid.lastIndexOf('/') + 1);
  37529. }
  37530. /**
  37531. * Serialize a CMCD data object according to the rules defined in the
  37532. * section 3.2 of
  37533. * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
  37534. */;
  37535. CMCDController.serialize = function serialize(data) {
  37536. var results = [];
  37537. var isValid = function isValid(value) {
  37538. return !Number.isNaN(value) && value != null && value !== '' && value !== false;
  37539. };
  37540. var toRounded = function toRounded(value) {
  37541. return Math.round(value);
  37542. };
  37543. var toHundred = function toHundred(value) {
  37544. return toRounded(value / 100) * 100;
  37545. };
  37546. var toUrlSafe = function toUrlSafe(value) {
  37547. return encodeURIComponent(value);
  37548. };
  37549. var formatters = {
  37550. br: toRounded,
  37551. d: toRounded,
  37552. bl: toHundred,
  37553. dl: toHundred,
  37554. mtp: toHundred,
  37555. nor: toUrlSafe,
  37556. rtp: toHundred,
  37557. tb: toRounded
  37558. };
  37559. var keys = Object.keys(data || {}).sort();
  37560. for (var _iterator2 = _createForOfIteratorHelperLoose(keys), _step2; !(_step2 = _iterator2()).done;) {
  37561. var key = _step2.value;
  37562. var value = data[key];
  37563. // ignore invalid values
  37564. if (!isValid(value)) {
  37565. continue;
  37566. }
  37567. // Version should only be reported if not equal to 1.
  37568. if (key === 'v' && value === 1) {
  37569. continue;
  37570. }
  37571. // Playback rate should only be sent if not equal to 1.
  37572. if (key == 'pr' && value === 1) {
  37573. continue;
  37574. }
  37575. // Certain values require special formatting
  37576. var formatter = formatters[key];
  37577. if (formatter) {
  37578. value = formatter(value);
  37579. }
  37580. // Serialize the key/value pair
  37581. var type = typeof value;
  37582. var result = void 0;
  37583. if (key === 'ot' || key === 'sf' || key === 'st') {
  37584. result = key + "=" + value;
  37585. } else if (type === 'boolean') {
  37586. result = key;
  37587. } else if (type === 'number') {
  37588. result = key + "=" + value;
  37589. } else {
  37590. result = key + "=" + JSON.stringify(value);
  37591. }
  37592. results.push(result);
  37593. }
  37594. return results.join(',');
  37595. }
  37596. /**
  37597. * Convert a CMCD data object to request headers according to the rules
  37598. * defined in the section 2.1 and 3.2 of
  37599. * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
  37600. */;
  37601. CMCDController.toHeaders = function toHeaders(data) {
  37602. var keys = Object.keys(data);
  37603. var headers = {};
  37604. var headerNames = ['Object', 'Request', 'Session', 'Status'];
  37605. var headerGroups = [{}, {}, {}, {}];
  37606. var headerMap = {
  37607. br: 0,
  37608. d: 0,
  37609. ot: 0,
  37610. tb: 0,
  37611. bl: 1,
  37612. dl: 1,
  37613. mtp: 1,
  37614. nor: 1,
  37615. nrr: 1,
  37616. su: 1,
  37617. cid: 2,
  37618. pr: 2,
  37619. sf: 2,
  37620. sid: 2,
  37621. st: 2,
  37622. v: 2,
  37623. bs: 3,
  37624. rtp: 3
  37625. };
  37626. for (var _i = 0, _keys = keys; _i < _keys.length; _i++) {
  37627. var key = _keys[_i];
  37628. // Unmapped fields are mapped to the Request header
  37629. var index = headerMap[key] != null ? headerMap[key] : 1;
  37630. headerGroups[index][key] = data[key];
  37631. }
  37632. for (var i = 0; i < headerGroups.length; i++) {
  37633. var value = CMCDController.serialize(headerGroups[i]);
  37634. if (value) {
  37635. headers["CMCD-" + headerNames[i]] = value;
  37636. }
  37637. }
  37638. return headers;
  37639. }
  37640. /**
  37641. * Convert a CMCD data object to query args according to the rules
  37642. * defined in the section 2.2 and 3.2 of
  37643. * [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
  37644. */;
  37645. CMCDController.toQuery = function toQuery(data) {
  37646. return "CMCD=" + encodeURIComponent(CMCDController.serialize(data));
  37647. }
  37648. /**
  37649. * Append query args to a uri.
  37650. */;
  37651. CMCDController.appendQueryToUri = function appendQueryToUri(uri, query) {
  37652. if (!query) {
  37653. return uri;
  37654. }
  37655. var separator = uri.includes('?') ? '&' : '?';
  37656. return "" + uri + separator + query;
  37657. };
  37658. return CMCDController;
  37659. }();
  37660. /***/ }),
  37661. /***/ "./src/controller/eme-controller.ts":
  37662. /*!******************************************!*\
  37663. !*** ./src/controller/eme-controller.ts ***!
  37664. \******************************************/
  37665. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  37666. "use strict";
  37667. __webpack_require__.r(__webpack_exports__);
  37668. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  37669. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  37670. /* harmony export */ });
  37671. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  37672. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  37673. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  37674. /* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts");
  37675. /* harmony import */ var _utils_keysystem_util__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/keysystem-util */ "./src/utils/keysystem-util.ts");
  37676. /* harmony import */ var _utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/numeric-encoding-utils */ "./src/utils/numeric-encoding-utils.ts");
  37677. /* harmony import */ var _loader_level_key__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../loader/level-key */ "./src/loader/level-key.ts");
  37678. /* harmony import */ var _utils_hex__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/hex */ "./src/utils/hex.ts");
  37679. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  37680. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js");
  37681. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_9__);
  37682. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  37683. function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
  37684. function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
  37685. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
  37686. function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
  37687. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  37688. function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
  37689. /**
  37690. * @author Stephan Hesse <disparat@gmail.com> | <tchakabam@gmail.com>
  37691. *
  37692. * DRM support for Hls.js
  37693. */
  37694. var MAX_LICENSE_REQUEST_FAILURES = 3;
  37695. var LOGGER_PREFIX = '[eme]';
  37696. /**
  37697. * Controller to deal with encrypted media extensions (EME)
  37698. * @see https://developer.mozilla.org/en-US/docs/Web/API/Encrypted_Media_Extensions_API
  37699. *
  37700. * @class
  37701. * @constructor
  37702. */
  37703. var EMEController = /*#__PURE__*/function () {
  37704. function EMEController(hls) {
  37705. this.hls = void 0;
  37706. this.config = void 0;
  37707. this.media = null;
  37708. this.keyFormatPromise = null;
  37709. this.keySystemAccessPromises = {};
  37710. this._requestLicenseFailureCount = 0;
  37711. this.mediaKeySessions = [];
  37712. this.keyIdToKeySessionPromise = {};
  37713. this.setMediaKeysQueue = EMEController.CDMCleanupPromise ? [EMEController.CDMCleanupPromise] : [];
  37714. this.onMediaEncrypted = this._onMediaEncrypted.bind(this);
  37715. this.onWaitingForKey = this._onWaitingForKey.bind(this);
  37716. this.debug = _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.debug.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger, LOGGER_PREFIX);
  37717. this.log = _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger, LOGGER_PREFIX);
  37718. this.warn = _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger, LOGGER_PREFIX);
  37719. this.error = _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.error.bind(_utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger, LOGGER_PREFIX);
  37720. this.hls = hls;
  37721. this.config = hls.config;
  37722. this.registerListeners();
  37723. }
  37724. var _proto = EMEController.prototype;
  37725. _proto.destroy = function destroy() {
  37726. this.unregisterListeners();
  37727. this.onMediaDetached();
  37728. // @ts-ignore
  37729. this.hls = this.onMediaEncrypted = this.onWaitingForKey = this.keyIdToKeySessionPromise = null;
  37730. };
  37731. _proto.registerListeners = function registerListeners() {
  37732. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  37733. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED, this.onMediaDetached, this);
  37734. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADED, this.onManifestLoaded, this);
  37735. };
  37736. _proto.unregisterListeners = function unregisterListeners() {
  37737. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  37738. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHED, this.onMediaDetached, this);
  37739. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADED, this.onManifestLoaded, this);
  37740. };
  37741. _proto.getLicenseServerUrl = function getLicenseServerUrl(keySystem) {
  37742. var _this$config = this.config,
  37743. drmSystems = _this$config.drmSystems,
  37744. widevineLicenseUrl = _this$config.widevineLicenseUrl;
  37745. var keySystemConfiguration = drmSystems[keySystem];
  37746. if (keySystemConfiguration) {
  37747. return keySystemConfiguration.licenseUrl;
  37748. }
  37749. // For backward compatibility
  37750. if (keySystem === _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.WIDEVINE && widevineLicenseUrl) {
  37751. return widevineLicenseUrl;
  37752. }
  37753. throw new Error("no license server URL configured for key-system \"" + keySystem + "\"");
  37754. };
  37755. _proto.getServerCertificateUrl = function getServerCertificateUrl(keySystem) {
  37756. var drmSystems = this.config.drmSystems;
  37757. var keySystemConfiguration = drmSystems[keySystem];
  37758. if (keySystemConfiguration) {
  37759. return keySystemConfiguration.serverCertificateUrl;
  37760. } else {
  37761. this.log("No Server Certificate in config.drmSystems[\"" + keySystem + "\"]");
  37762. }
  37763. };
  37764. _proto.attemptKeySystemAccess = function attemptKeySystemAccess(keySystemsToAttempt) {
  37765. var _this = this;
  37766. var levels = this.hls.levels;
  37767. var uniqueCodec = function uniqueCodec(value, i, a) {
  37768. return !!value && a.indexOf(value) === i;
  37769. };
  37770. var audioCodecs = levels.map(function (level) {
  37771. return level.audioCodec;
  37772. }).filter(uniqueCodec);
  37773. var videoCodecs = levels.map(function (level) {
  37774. return level.videoCodec;
  37775. }).filter(uniqueCodec);
  37776. if (audioCodecs.length + videoCodecs.length === 0) {
  37777. videoCodecs.push('avc1.42e01e');
  37778. }
  37779. return new Promise(function (resolve, reject) {
  37780. var attempt = function attempt(keySystems) {
  37781. var keySystem = keySystems.shift();
  37782. _this.getMediaKeysPromise(keySystem, audioCodecs, videoCodecs).then(function (mediaKeys) {
  37783. return resolve({
  37784. keySystem: keySystem,
  37785. mediaKeys: mediaKeys
  37786. });
  37787. }).catch(function (error) {
  37788. if (keySystems.length) {
  37789. attempt(keySystems);
  37790. } else if (error instanceof EMEKeyError) {
  37791. reject(error);
  37792. } else {
  37793. reject(new EMEKeyError({
  37794. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  37795. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_ACCESS,
  37796. error: error,
  37797. fatal: true
  37798. }, error.message));
  37799. }
  37800. });
  37801. };
  37802. attempt(keySystemsToAttempt);
  37803. });
  37804. };
  37805. _proto.requestMediaKeySystemAccess = function requestMediaKeySystemAccess(keySystem, supportedConfigurations) {
  37806. var requestMediaKeySystemAccessFunc = this.config.requestMediaKeySystemAccessFunc;
  37807. if (!(typeof requestMediaKeySystemAccessFunc === 'function')) {
  37808. var errMessage = "Configured requestMediaKeySystemAccess is not a function " + requestMediaKeySystemAccessFunc;
  37809. if (_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.requestMediaKeySystemAccess === null && self.location.protocol === 'http:') {
  37810. errMessage = "navigator.requestMediaKeySystemAccess is not available over insecure protocol " + location.protocol;
  37811. }
  37812. return Promise.reject(new Error(errMessage));
  37813. }
  37814. return requestMediaKeySystemAccessFunc(keySystem, supportedConfigurations);
  37815. };
  37816. _proto.getMediaKeysPromise = function getMediaKeysPromise(keySystem, audioCodecs, videoCodecs) {
  37817. var _this2 = this;
  37818. // This can throw, but is caught in event handler callpath
  37819. var mediaKeySystemConfigs = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getSupportedMediaKeySystemConfigurations)(keySystem, audioCodecs, videoCodecs, this.config.drmSystemOptions);
  37820. var keySystemAccessPromises = this.keySystemAccessPromises[keySystem];
  37821. var keySystemAccess = keySystemAccessPromises === null || keySystemAccessPromises === void 0 ? void 0 : keySystemAccessPromises.keySystemAccess;
  37822. if (!keySystemAccess) {
  37823. this.log("Requesting encrypted media \"" + keySystem + "\" key-system access with config: " + JSON.stringify(mediaKeySystemConfigs));
  37824. keySystemAccess = this.requestMediaKeySystemAccess(keySystem, mediaKeySystemConfigs);
  37825. var _keySystemAccessPromises = this.keySystemAccessPromises[keySystem] = {
  37826. keySystemAccess: keySystemAccess
  37827. };
  37828. keySystemAccess.catch(function (error) {
  37829. _this2.log("Failed to obtain access to key-system \"" + keySystem + "\": " + error);
  37830. });
  37831. return keySystemAccess.then(function (mediaKeySystemAccess) {
  37832. _this2.log("Access for key-system \"" + mediaKeySystemAccess.keySystem + "\" obtained");
  37833. var certificateRequest = _this2.fetchServerCertificate(keySystem);
  37834. _this2.log("Create media-keys for \"" + keySystem + "\"");
  37835. _keySystemAccessPromises.mediaKeys = mediaKeySystemAccess.createMediaKeys().then(function (mediaKeys) {
  37836. _this2.log("Media-keys created for \"" + keySystem + "\"");
  37837. return certificateRequest.then(function (certificate) {
  37838. if (certificate) {
  37839. return _this2.setMediaKeysServerCertificate(mediaKeys, keySystem, certificate);
  37840. }
  37841. return mediaKeys;
  37842. });
  37843. });
  37844. _keySystemAccessPromises.mediaKeys.catch(function (error) {
  37845. _this2.error("Failed to create media-keys for \"" + keySystem + "\"}: " + error);
  37846. });
  37847. return _keySystemAccessPromises.mediaKeys;
  37848. });
  37849. }
  37850. return keySystemAccess.then(function () {
  37851. return keySystemAccessPromises.mediaKeys;
  37852. });
  37853. };
  37854. _proto.createMediaKeySessionContext = function createMediaKeySessionContext(_ref) {
  37855. var decryptdata = _ref.decryptdata,
  37856. keySystem = _ref.keySystem,
  37857. mediaKeys = _ref.mediaKeys;
  37858. console.assert(!!mediaKeys, 'mediaKeys is defined');
  37859. this.log("Creating key-system session \"" + keySystem + "\" keyId: " + _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(decryptdata.keyId || []));
  37860. var mediaKeysSession = mediaKeys.createSession();
  37861. var mediaKeySessionContext = {
  37862. decryptdata: decryptdata,
  37863. keySystem: keySystem,
  37864. mediaKeys: mediaKeys,
  37865. mediaKeysSession: mediaKeysSession,
  37866. keyStatus: 'status-pending'
  37867. };
  37868. this.mediaKeySessions.push(mediaKeySessionContext);
  37869. return mediaKeySessionContext;
  37870. };
  37871. _proto.renewKeySession = function renewKeySession(mediaKeySessionContext) {
  37872. var decryptdata = mediaKeySessionContext.decryptdata;
  37873. if (decryptdata.pssh) {
  37874. var keySessionContext = this.createMediaKeySessionContext(mediaKeySessionContext);
  37875. var _keyId = this.getKeyIdString(decryptdata);
  37876. var scheme = 'cenc';
  37877. this.keyIdToKeySessionPromise[_keyId] = this.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'expired');
  37878. } else {
  37879. this.warn("Could not renew expired session. Missing pssh initData.");
  37880. }
  37881. this.removeSession(mediaKeySessionContext);
  37882. };
  37883. _proto.getKeyIdString = function getKeyIdString(decryptdata) {
  37884. if (!decryptdata) {
  37885. throw new Error('Could not read keyId of undefined decryptdata');
  37886. }
  37887. if (decryptdata.keyId === null) {
  37888. throw new Error('keyId is null');
  37889. }
  37890. return _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(decryptdata.keyId);
  37891. };
  37892. _proto.updateKeySession = function updateKeySession(mediaKeySessionContext, data) {
  37893. var _mediaKeySessionConte;
  37894. var keySession = mediaKeySessionContext.mediaKeysSession;
  37895. this.log("Updating key-session \"" + keySession.sessionId + "\" for keyID " + _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(((_mediaKeySessionConte = mediaKeySessionContext.decryptdata) === null || _mediaKeySessionConte === void 0 ? void 0 : _mediaKeySessionConte.keyId) || []) + "\n } (data length: " + (data ? data.byteLength : data) + ")");
  37896. return keySession.update(data);
  37897. };
  37898. _proto.selectKeySystemFormat = function selectKeySystemFormat(frag) {
  37899. var keyFormats = Object.keys(frag.levelkeys || {});
  37900. if (!this.keyFormatPromise) {
  37901. this.log("Selecting key-system from fragment (sn: " + frag.sn + " " + frag.type + ": " + frag.level + ") key formats " + keyFormats.join(', '));
  37902. this.keyFormatPromise = this.getKeyFormatPromise(keyFormats);
  37903. }
  37904. return this.keyFormatPromise;
  37905. };
  37906. _proto.getKeyFormatPromise = function getKeyFormatPromise(keyFormats) {
  37907. var _this3 = this;
  37908. return new Promise(function (resolve, reject) {
  37909. var keySystemsInConfig = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getKeySystemsForConfig)(_this3.config);
  37910. var keySystemsToAttempt = keyFormats.map(_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemFormatToKeySystemDomain).filter(function (value) {
  37911. return !!value && keySystemsInConfig.indexOf(value) !== -1;
  37912. });
  37913. return _this3.getKeySystemSelectionPromise(keySystemsToAttempt).then(function (_ref2) {
  37914. var keySystem = _ref2.keySystem;
  37915. var keySystemFormat = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemDomainToKeySystemFormat)(keySystem);
  37916. if (keySystemFormat) {
  37917. resolve(keySystemFormat);
  37918. } else {
  37919. reject(new Error("Unable to find format for key-system \"" + keySystem + "\""));
  37920. }
  37921. }).catch(reject);
  37922. });
  37923. };
  37924. _proto.loadKey = function loadKey(data) {
  37925. var _this4 = this;
  37926. var decryptdata = data.keyInfo.decryptdata;
  37927. var keyId = this.getKeyIdString(decryptdata);
  37928. var keyDetails = "(keyId: " + keyId + " format: \"" + decryptdata.keyFormat + "\" method: " + decryptdata.method + " uri: " + decryptdata.uri + ")";
  37929. this.log("Starting session for key " + keyDetails);
  37930. var keySessionContextPromise = this.keyIdToKeySessionPromise[keyId];
  37931. if (!keySessionContextPromise) {
  37932. keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (_ref3) {
  37933. var keySystem = _ref3.keySystem,
  37934. mediaKeys = _ref3.mediaKeys;
  37935. _this4.throwIfDestroyed();
  37936. _this4.log("Handle encrypted media sn: " + data.frag.sn + " " + data.frag.type + ": " + data.frag.level + " using key " + keyDetails);
  37937. return _this4.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
  37938. _this4.throwIfDestroyed();
  37939. var keySessionContext = _this4.createMediaKeySessionContext({
  37940. keySystem: keySystem,
  37941. mediaKeys: mediaKeys,
  37942. decryptdata: decryptdata
  37943. });
  37944. var scheme = 'cenc';
  37945. return _this4.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'playlist-key');
  37946. });
  37947. });
  37948. keySessionContextPromise.catch(function (error) {
  37949. return _this4.handleError(error);
  37950. });
  37951. }
  37952. return keySessionContextPromise;
  37953. };
  37954. _proto.throwIfDestroyed = function throwIfDestroyed(message) {
  37955. if (message === void 0) {
  37956. message = 'Invalid state';
  37957. }
  37958. if (!this.hls) {
  37959. throw new Error('invalid state');
  37960. }
  37961. };
  37962. _proto.handleError = function handleError(error) {
  37963. if (!this.hls) {
  37964. return;
  37965. }
  37966. this.error(error.message);
  37967. if (error instanceof EMEKeyError) {
  37968. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, error.data);
  37969. } else {
  37970. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, {
  37971. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  37972. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_KEYS,
  37973. error: error,
  37974. fatal: true
  37975. });
  37976. }
  37977. };
  37978. _proto.getKeySystemForKeyPromise = function getKeySystemForKeyPromise(decryptdata) {
  37979. var keyId = this.getKeyIdString(decryptdata);
  37980. var mediaKeySessionContext = this.keyIdToKeySessionPromise[keyId];
  37981. if (!mediaKeySessionContext) {
  37982. var keySystem = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemFormatToKeySystemDomain)(decryptdata.keyFormat);
  37983. var keySystemsToAttempt = keySystem ? [keySystem] : (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getKeySystemsForConfig)(this.config);
  37984. return this.attemptKeySystemAccess(keySystemsToAttempt);
  37985. }
  37986. return mediaKeySessionContext;
  37987. };
  37988. _proto.getKeySystemSelectionPromise = function getKeySystemSelectionPromise(keySystemsToAttempt) {
  37989. if (!keySystemsToAttempt.length) {
  37990. keySystemsToAttempt = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.getKeySystemsForConfig)(this.config);
  37991. }
  37992. if (keySystemsToAttempt.length === 0) {
  37993. throw new EMEKeyError({
  37994. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  37995. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_CONFIGURED_LICENSE,
  37996. fatal: true
  37997. }, "Missing key-system license configuration options " + JSON.stringify({
  37998. drmSystems: this.config.drmSystems
  37999. }));
  38000. }
  38001. return this.attemptKeySystemAccess(keySystemsToAttempt);
  38002. };
  38003. _proto._onMediaEncrypted = function _onMediaEncrypted(event) {
  38004. var _this5 = this;
  38005. var initDataType = event.initDataType,
  38006. initData = event.initData;
  38007. this.debug("\"" + event.type + "\" event: init data type: \"" + initDataType + "\"");
  38008. // Ignore event when initData is null
  38009. if (initData === null) {
  38010. return;
  38011. }
  38012. var keyId;
  38013. var keySystemDomain;
  38014. if (initDataType === 'sinf' && this.config.drmSystems[_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.FAIRPLAY]) {
  38015. // Match sinf keyId to playlist skd://keyId=
  38016. var json = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.bin2str)(new Uint8Array(initData));
  38017. try {
  38018. var sinf = (0,_utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_5__.base64Decode)(JSON.parse(json).sinf);
  38019. var tenc = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.parseSinf)(new Uint8Array(sinf));
  38020. if (!tenc) {
  38021. return;
  38022. }
  38023. keyId = tenc.subarray(8, 24);
  38024. keySystemDomain = _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.FAIRPLAY;
  38025. } catch (error) {
  38026. this.warn('Failed to parse sinf "encrypted" event message initData');
  38027. return;
  38028. }
  38029. } else {
  38030. // Support clear-lead key-session creation (otherwise depend on playlist keys)
  38031. var psshInfo = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_8__.parsePssh)(initData);
  38032. if (psshInfo === null) {
  38033. return;
  38034. }
  38035. if (psshInfo.version === 0 && psshInfo.systemId === _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystemIds.WIDEVINE && psshInfo.data) {
  38036. keyId = psshInfo.data.subarray(8, 24);
  38037. }
  38038. keySystemDomain = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemIdToKeySystemDomain)(psshInfo.systemId);
  38039. }
  38040. if (!keySystemDomain || !keyId) {
  38041. return;
  38042. }
  38043. var keyIdHex = _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(keyId);
  38044. var keyIdToKeySessionPromise = this.keyIdToKeySessionPromise,
  38045. mediaKeySessions = this.mediaKeySessions;
  38046. var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
  38047. var _loop = function _loop(i) {
  38048. // Match playlist key
  38049. var keyContext = mediaKeySessions[i];
  38050. var decryptdata = keyContext.decryptdata;
  38051. if (decryptdata.pssh || !decryptdata.keyId) {
  38052. return "continue";
  38053. }
  38054. var oldKeyIdHex = _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(decryptdata.keyId);
  38055. if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
  38056. keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
  38057. delete keyIdToKeySessionPromise[oldKeyIdHex];
  38058. decryptdata.pssh = new Uint8Array(initData);
  38059. decryptdata.keyId = keyId;
  38060. keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
  38061. return _this5.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
  38062. });
  38063. return "break";
  38064. }
  38065. };
  38066. for (var i = 0; i < mediaKeySessions.length; i++) {
  38067. var _ret = _loop(i);
  38068. if (_ret === "continue") continue;
  38069. if (_ret === "break") break;
  38070. }
  38071. if (!keySessionContextPromise) {
  38072. // Clear-lead key (not encountered in playlist)
  38073. keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref4) {
  38074. var _keySystemToKeySystem;
  38075. var keySystem = _ref4.keySystem,
  38076. mediaKeys = _ref4.mediaKeys;
  38077. _this5.throwIfDestroyed();
  38078. var decryptdata = new _loader_level_key__WEBPACK_IMPORTED_MODULE_6__.LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = (0,_utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.keySystemDomainToKeySystemFormat)(keySystem)) != null ? _keySystemToKeySystem : '');
  38079. decryptdata.pssh = new Uint8Array(initData);
  38080. decryptdata.keyId = keyId;
  38081. return _this5.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
  38082. _this5.throwIfDestroyed();
  38083. var keySessionContext = _this5.createMediaKeySessionContext({
  38084. decryptdata: decryptdata,
  38085. keySystem: keySystem,
  38086. mediaKeys: mediaKeys
  38087. });
  38088. return _this5.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
  38089. });
  38090. });
  38091. }
  38092. keySessionContextPromise.catch(function (error) {
  38093. return _this5.handleError(error);
  38094. });
  38095. };
  38096. _proto._onWaitingForKey = function _onWaitingForKey(event) {
  38097. this.log("\"" + event.type + "\" event");
  38098. };
  38099. _proto.attemptSetMediaKeys = function attemptSetMediaKeys(keySystem, mediaKeys) {
  38100. var _this6 = this;
  38101. var queue = this.setMediaKeysQueue.slice();
  38102. this.log("Setting media-keys for \"" + keySystem + "\"");
  38103. // Only one setMediaKeys() can run at one time, and multiple setMediaKeys() operations
  38104. // can be queued for execution for multiple key sessions.
  38105. var setMediaKeysPromise = Promise.all(queue).then(function () {
  38106. if (!_this6.media) {
  38107. throw new Error('Attempted to set mediaKeys without media element attached');
  38108. }
  38109. return _this6.media.setMediaKeys(mediaKeys);
  38110. });
  38111. this.setMediaKeysQueue.push(setMediaKeysPromise);
  38112. return setMediaKeysPromise.then(function () {
  38113. _this6.log("Media-keys set for \"" + keySystem + "\"");
  38114. queue.push(setMediaKeysPromise);
  38115. _this6.setMediaKeysQueue = _this6.setMediaKeysQueue.filter(function (p) {
  38116. return queue.indexOf(p) === -1;
  38117. });
  38118. });
  38119. };
  38120. _proto.generateRequestWithPreferredKeySession = function generateRequestWithPreferredKeySession(context, initDataType, initData, reason) {
  38121. var _this$config$drmSyste,
  38122. _this$config$drmSyste2,
  38123. _this7 = this;
  38124. var generateRequestFilter = (_this$config$drmSyste = this.config.drmSystems) === null || _this$config$drmSyste === void 0 ? void 0 : (_this$config$drmSyste2 = _this$config$drmSyste[context.keySystem]) === null || _this$config$drmSyste2 === void 0 ? void 0 : _this$config$drmSyste2.generateRequest;
  38125. if (generateRequestFilter) {
  38126. try {
  38127. var mappedInitData = generateRequestFilter.call(this.hls, initDataType, initData, context);
  38128. if (!mappedInitData) {
  38129. throw new Error('Invalid response from configured generateRequest filter');
  38130. }
  38131. initDataType = mappedInitData.initDataType;
  38132. initData = context.decryptdata.pssh = mappedInitData.initData ? new Uint8Array(mappedInitData.initData) : null;
  38133. } catch (error) {
  38134. var _this$hls;
  38135. this.warn(error.message);
  38136. if ((_this$hls = this.hls) !== null && _this$hls !== void 0 && _this$hls.config.debug) {
  38137. throw error;
  38138. }
  38139. }
  38140. }
  38141. if (initData === null) {
  38142. this.log("Skipping key-session request for \"" + reason + "\" (no initData)");
  38143. return Promise.resolve(context);
  38144. }
  38145. var keyId = this.getKeyIdString(context.decryptdata);
  38146. this.log("Generating key-session request for \"" + reason + "\": " + keyId + " (init data type: " + initDataType + " length: " + (initData ? initData.byteLength : null) + ")");
  38147. var licenseStatus = new (eventemitter3__WEBPACK_IMPORTED_MODULE_9___default())();
  38148. context.mediaKeysSession.onmessage = function (event) {
  38149. var keySession = context.mediaKeysSession;
  38150. if (!keySession) {
  38151. licenseStatus.emit('error', new Error('invalid state'));
  38152. return;
  38153. }
  38154. var messageType = event.messageType,
  38155. message = event.message;
  38156. _this7.log("\"" + messageType + "\" message event for session \"" + keySession.sessionId + "\" message size: " + message.byteLength);
  38157. if (messageType === 'license-request' || messageType === 'license-renewal') {
  38158. _this7.renewLicense(context, message).catch(function (error) {
  38159. _this7.handleError(error);
  38160. licenseStatus.emit('error', error);
  38161. });
  38162. } else if (messageType === 'license-release') {
  38163. if (context.keySystem === _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_3__.KeySystems.FAIRPLAY) {
  38164. _this7.updateKeySession(context, (0,_utils_keysystem_util__WEBPACK_IMPORTED_MODULE_4__.strToUtf8array)('acknowledged'));
  38165. _this7.removeSession(context);
  38166. }
  38167. } else {
  38168. _this7.warn("unhandled media key message type \"" + messageType + "\"");
  38169. }
  38170. };
  38171. context.mediaKeysSession.onkeystatuseschange = function (event) {
  38172. var keySession = context.mediaKeysSession;
  38173. if (!keySession) {
  38174. licenseStatus.emit('error', new Error('invalid state'));
  38175. return;
  38176. }
  38177. _this7.onKeyStatusChange(context);
  38178. var keyStatus = context.keyStatus;
  38179. licenseStatus.emit('keyStatus', keyStatus);
  38180. if (keyStatus === 'expired') {
  38181. _this7.warn(context.keySystem + " expired for key " + keyId);
  38182. _this7.renewKeySession(context);
  38183. }
  38184. };
  38185. var keyUsablePromise = new Promise(function (resolve, reject) {
  38186. licenseStatus.on('error', reject);
  38187. licenseStatus.on('keyStatus', function (keyStatus) {
  38188. if (keyStatus.startsWith('usable')) {
  38189. resolve();
  38190. } else if (keyStatus === 'output-restricted') {
  38191. reject(new EMEKeyError({
  38192. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38193. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED,
  38194. fatal: false
  38195. }, 'HDCP level output restricted'));
  38196. } else if (keyStatus === 'internal-error') {
  38197. reject(new EMEKeyError({
  38198. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38199. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_STATUS_INTERNAL_ERROR,
  38200. fatal: true
  38201. }, "key status changed to \"" + keyStatus + "\""));
  38202. } else if (keyStatus === 'expired') {
  38203. reject(new Error('key expired while generating request'));
  38204. } else {
  38205. _this7.warn("unhandled key status change \"" + keyStatus + "\"");
  38206. }
  38207. });
  38208. });
  38209. return context.mediaKeysSession.generateRequest(initDataType, initData).then(function () {
  38210. var _context$mediaKeysSes;
  38211. _this7.log("Request generated for key-session \"" + ((_context$mediaKeysSes = context.mediaKeysSession) === null || _context$mediaKeysSes === void 0 ? void 0 : _context$mediaKeysSes.sessionId) + "\" keyId: " + keyId);
  38212. }).catch(function (error) {
  38213. throw new EMEKeyError({
  38214. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38215. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_NO_SESSION,
  38216. error: error,
  38217. fatal: false
  38218. }, "Error generating key-session request: " + error);
  38219. }).then(function () {
  38220. return keyUsablePromise;
  38221. }).catch(function (error) {
  38222. licenseStatus.removeAllListeners();
  38223. _this7.removeSession(context);
  38224. throw error;
  38225. }).then(function () {
  38226. licenseStatus.removeAllListeners();
  38227. return context;
  38228. });
  38229. };
  38230. _proto.onKeyStatusChange = function onKeyStatusChange(mediaKeySessionContext) {
  38231. var _this8 = this;
  38232. mediaKeySessionContext.mediaKeysSession.keyStatuses.forEach(function (status, keyId) {
  38233. _this8.log("key status change \"" + status + "\" for keyStatuses keyId: " + _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump('buffer' in keyId ? new Uint8Array(keyId.buffer, keyId.byteOffset, keyId.byteLength) : new Uint8Array(keyId)) + " session keyId: " + _utils_hex__WEBPACK_IMPORTED_MODULE_7__["default"].hexDump(new Uint8Array(mediaKeySessionContext.decryptdata.keyId || [])) + " uri: " + mediaKeySessionContext.decryptdata.uri);
  38234. mediaKeySessionContext.keyStatus = status;
  38235. });
  38236. };
  38237. _proto.fetchServerCertificate = function fetchServerCertificate(keySystem) {
  38238. var _this9 = this;
  38239. return new Promise(function (resolve, reject) {
  38240. var url = _this9.getServerCertificateUrl(keySystem);
  38241. if (!url) {
  38242. return resolve();
  38243. }
  38244. _this9.log("Fetching serverCertificate for \"" + keySystem + "\"");
  38245. var xhr = new XMLHttpRequest();
  38246. xhr.open('GET', url, true);
  38247. xhr.responseType = 'arraybuffer';
  38248. xhr.onreadystatechange = function () {
  38249. if (xhr.readyState === XMLHttpRequest.DONE) {
  38250. if (xhr.status === 200) {
  38251. resolve(xhr.response);
  38252. } else {
  38253. reject(new EMEKeyError({
  38254. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38255. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED,
  38256. fatal: true,
  38257. networkDetails: xhr
  38258. }, "\"" + keySystem + "\" certificate request XHR failed (" + url + "). Status: " + xhr.status + " (" + xhr.statusText + ")"));
  38259. }
  38260. }
  38261. };
  38262. xhr.send();
  38263. });
  38264. };
  38265. _proto.setMediaKeysServerCertificate = function setMediaKeysServerCertificate(mediaKeys, keySystem, cert) {
  38266. var _this10 = this;
  38267. return new Promise(function (resolve, reject) {
  38268. mediaKeys.setServerCertificate(cert).then(function (success) {
  38269. _this10.log("setServerCertificate " + (success ? 'success' : 'not supported by CDM') + " (" + (cert === null || cert === void 0 ? void 0 : cert.byteLength) + ") on \"" + keySystem + "\"");
  38270. resolve(mediaKeys);
  38271. }).catch(function (error) {
  38272. reject(new EMEKeyError({
  38273. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38274. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED,
  38275. error: error,
  38276. fatal: true
  38277. }, error.message));
  38278. });
  38279. });
  38280. };
  38281. _proto.renewLicense = function renewLicense(context, keyMessage) {
  38282. var _this11 = this;
  38283. return this.requestLicense(context, new Uint8Array(keyMessage)).then(function (data) {
  38284. return _this11.updateKeySession(context, new Uint8Array(data)).catch(function (error) {
  38285. throw new EMEKeyError({
  38286. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38287. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_SESSION_UPDATE_FAILED,
  38288. error: error,
  38289. fatal: true
  38290. }, error.message);
  38291. });
  38292. });
  38293. };
  38294. _proto.setupLicenseXHR = function setupLicenseXHR(xhr, url, keysListItem, licenseChallenge) {
  38295. var _this12 = this;
  38296. var licenseXhrSetup = this.config.licenseXhrSetup;
  38297. if (!licenseXhrSetup) {
  38298. xhr.open('POST', url, true);
  38299. return Promise.resolve({
  38300. xhr: xhr,
  38301. licenseChallenge: licenseChallenge
  38302. });
  38303. }
  38304. return Promise.resolve().then(function () {
  38305. if (!keysListItem.decryptdata) {
  38306. throw new Error('Key removed');
  38307. }
  38308. return licenseXhrSetup.call(_this12.hls, xhr, url, keysListItem, licenseChallenge);
  38309. }).catch(function (error) {
  38310. if (!keysListItem.decryptdata) {
  38311. // Key session removed. Cancel license request.
  38312. throw error;
  38313. }
  38314. // let's try to open before running setup
  38315. xhr.open('POST', url, true);
  38316. return licenseXhrSetup.call(_this12.hls, xhr, url, keysListItem, licenseChallenge);
  38317. }).then(function (licenseXhrSetupResult) {
  38318. // if licenseXhrSetup did not yet call open, let's do it now
  38319. if (!xhr.readyState) {
  38320. xhr.open('POST', url, true);
  38321. }
  38322. var finalLicenseChallenge = licenseXhrSetupResult ? licenseXhrSetupResult : licenseChallenge;
  38323. return {
  38324. xhr: xhr,
  38325. licenseChallenge: finalLicenseChallenge
  38326. };
  38327. });
  38328. };
  38329. _proto.requestLicense = function requestLicense(keySessionContext, licenseChallenge) {
  38330. var _this13 = this;
  38331. return new Promise(function (resolve, reject) {
  38332. var url = _this13.getLicenseServerUrl(keySessionContext.keySystem);
  38333. _this13.log("Sending license request to URL: " + url);
  38334. var xhr = new XMLHttpRequest();
  38335. xhr.responseType = 'arraybuffer';
  38336. xhr.onreadystatechange = function () {
  38337. if (!_this13.hls || !keySessionContext.mediaKeysSession) {
  38338. return reject(new Error('invalid state'));
  38339. }
  38340. if (xhr.readyState === 4) {
  38341. if (xhr.status === 200) {
  38342. _this13._requestLicenseFailureCount = 0;
  38343. var data = xhr.response;
  38344. _this13.log("License received " + (data instanceof ArrayBuffer ? data.byteLength : data));
  38345. var licenseResponseCallback = _this13.config.licenseResponseCallback;
  38346. if (licenseResponseCallback) {
  38347. try {
  38348. data = licenseResponseCallback.call(_this13.hls, xhr, url, keySessionContext);
  38349. } catch (error) {
  38350. _this13.error(error);
  38351. }
  38352. }
  38353. resolve(data);
  38354. } else {
  38355. _this13._requestLicenseFailureCount++;
  38356. if (_this13._requestLicenseFailureCount > MAX_LICENSE_REQUEST_FAILURES || xhr.status >= 400 && xhr.status < 500) {
  38357. reject(new EMEKeyError({
  38358. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.KEY_SYSTEM_ERROR,
  38359. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.KEY_SYSTEM_LICENSE_REQUEST_FAILED,
  38360. fatal: true,
  38361. networkDetails: xhr
  38362. }, "License Request XHR failed (" + url + "). Status: " + xhr.status + " (" + xhr.statusText + ")"));
  38363. } else {
  38364. var attemptsLeft = MAX_LICENSE_REQUEST_FAILURES - _this13._requestLicenseFailureCount + 1;
  38365. _this13.warn("Retrying license request, " + attemptsLeft + " attempts left");
  38366. _this13.requestLicense(keySessionContext, licenseChallenge).then(resolve, reject);
  38367. }
  38368. }
  38369. }
  38370. };
  38371. if (keySessionContext.licenseXhr && keySessionContext.licenseXhr.readyState !== XMLHttpRequest.DONE) {
  38372. keySessionContext.licenseXhr.abort();
  38373. }
  38374. keySessionContext.licenseXhr = xhr;
  38375. _this13.setupLicenseXHR(xhr, url, keySessionContext, licenseChallenge).then(function (_ref5) {
  38376. var xhr = _ref5.xhr,
  38377. licenseChallenge = _ref5.licenseChallenge;
  38378. xhr.send(licenseChallenge);
  38379. });
  38380. });
  38381. };
  38382. _proto.onMediaAttached = function onMediaAttached(event, data) {
  38383. if (!this.config.emeEnabled) {
  38384. return;
  38385. }
  38386. var media = data.media;
  38387. // keep reference of media
  38388. this.media = media;
  38389. media.addEventListener('encrypted', this.onMediaEncrypted);
  38390. media.addEventListener('waitingforkey', this.onWaitingForKey);
  38391. };
  38392. _proto.onMediaDetached = function onMediaDetached() {
  38393. var _this14 = this;
  38394. var media = this.media;
  38395. var mediaKeysList = this.mediaKeySessions;
  38396. if (media) {
  38397. media.removeEventListener('encrypted', this.onMediaEncrypted);
  38398. media.removeEventListener('waitingforkey', this.onWaitingForKey);
  38399. this.media = null;
  38400. }
  38401. this._requestLicenseFailureCount = 0;
  38402. this.setMediaKeysQueue = [];
  38403. this.mediaKeySessions = [];
  38404. this.keyIdToKeySessionPromise = {};
  38405. _loader_level_key__WEBPACK_IMPORTED_MODULE_6__.LevelKey.clearKeyUriToKeyIdMap();
  38406. // Close all sessions and remove media keys from the video element.
  38407. var keySessionCount = mediaKeysList.length;
  38408. EMEController.CDMCleanupPromise = Promise.all(mediaKeysList.map(function (mediaKeySessionContext) {
  38409. return _this14.removeSession(mediaKeySessionContext);
  38410. }).concat(media === null || media === void 0 ? void 0 : media.setMediaKeys(null).catch(function (error) {
  38411. _this14.log("Could not clear media keys: " + error + ". media.src: " + (media === null || media === void 0 ? void 0 : media.src));
  38412. }))).then(function () {
  38413. if (keySessionCount) {
  38414. _this14.log('finished closing key sessions and clearing media keys');
  38415. mediaKeysList.length = 0;
  38416. }
  38417. }).catch(function (error) {
  38418. _this14.log("Could not close sessions and clear media keys: " + error + ". media.src: " + (media === null || media === void 0 ? void 0 : media.src));
  38419. });
  38420. };
  38421. _proto.onManifestLoaded = function onManifestLoaded(event, _ref6) {
  38422. var sessionKeys = _ref6.sessionKeys;
  38423. if (!sessionKeys || !this.config.emeEnabled) {
  38424. return;
  38425. }
  38426. if (!this.keyFormatPromise) {
  38427. var keyFormats = sessionKeys.reduce(function (formats, sessionKey) {
  38428. if (formats.indexOf(sessionKey.keyFormat) === -1) {
  38429. formats.push(sessionKey.keyFormat);
  38430. }
  38431. return formats;
  38432. }, []);
  38433. this.log("Selecting key-system from session-keys " + keyFormats.join(', '));
  38434. this.keyFormatPromise = this.getKeyFormatPromise(keyFormats);
  38435. }
  38436. };
  38437. _proto.removeSession = function removeSession(mediaKeySessionContext) {
  38438. var _this15 = this;
  38439. var mediaKeysSession = mediaKeySessionContext.mediaKeysSession,
  38440. licenseXhr = mediaKeySessionContext.licenseXhr;
  38441. if (mediaKeysSession) {
  38442. this.log("Remove licenses and keys and close session " + mediaKeysSession.sessionId);
  38443. mediaKeysSession.onmessage = null;
  38444. mediaKeysSession.onkeystatuseschange = null;
  38445. if (licenseXhr && licenseXhr.readyState !== XMLHttpRequest.DONE) {
  38446. licenseXhr.abort();
  38447. }
  38448. mediaKeySessionContext.mediaKeysSession = mediaKeySessionContext.decryptdata = mediaKeySessionContext.licenseXhr = undefined;
  38449. var index = this.mediaKeySessions.indexOf(mediaKeySessionContext);
  38450. if (index > -1) {
  38451. this.mediaKeySessions.splice(index, 1);
  38452. }
  38453. return mediaKeysSession.remove().catch(function (error) {
  38454. _this15.log("Could not remove session: " + error);
  38455. }).then(function () {
  38456. return mediaKeysSession.close();
  38457. }).catch(function (error) {
  38458. _this15.log("Could not close session: " + error);
  38459. });
  38460. }
  38461. };
  38462. return EMEController;
  38463. }();
  38464. EMEController.CDMCleanupPromise = void 0;
  38465. var EMEKeyError = /*#__PURE__*/function (_Error) {
  38466. _inheritsLoose(EMEKeyError, _Error);
  38467. function EMEKeyError(data, message) {
  38468. var _this16;
  38469. _this16 = _Error.call(this, message) || this;
  38470. _this16.data = void 0;
  38471. _this16.data = data;
  38472. data.err = data.error;
  38473. return _this16;
  38474. }
  38475. return EMEKeyError;
  38476. }( /*#__PURE__*/_wrapNativeSuper(Error));
  38477. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EMEController);
  38478. /***/ }),
  38479. /***/ "./src/controller/fps-controller.ts":
  38480. /*!******************************************!*\
  38481. !*** ./src/controller/fps-controller.ts ***!
  38482. \******************************************/
  38483. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  38484. "use strict";
  38485. __webpack_require__.r(__webpack_exports__);
  38486. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  38487. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  38488. /* harmony export */ });
  38489. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  38490. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  38491. var FPSController = /*#__PURE__*/function () {
  38492. // stream controller must be provided as a dependency!
  38493. function FPSController(hls) {
  38494. this.hls = void 0;
  38495. this.isVideoPlaybackQualityAvailable = false;
  38496. this.timer = void 0;
  38497. this.media = null;
  38498. this.lastTime = void 0;
  38499. this.lastDroppedFrames = 0;
  38500. this.lastDecodedFrames = 0;
  38501. this.streamController = void 0;
  38502. this.hls = hls;
  38503. this.registerListeners();
  38504. }
  38505. var _proto = FPSController.prototype;
  38506. _proto.setStreamController = function setStreamController(streamController) {
  38507. this.streamController = streamController;
  38508. };
  38509. _proto.registerListeners = function registerListeners() {
  38510. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  38511. };
  38512. _proto.unregisterListeners = function unregisterListeners() {
  38513. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHING, this.onMediaAttaching);
  38514. };
  38515. _proto.destroy = function destroy() {
  38516. if (this.timer) {
  38517. clearInterval(this.timer);
  38518. }
  38519. this.unregisterListeners();
  38520. this.isVideoPlaybackQualityAvailable = false;
  38521. this.media = null;
  38522. };
  38523. _proto.onMediaAttaching = function onMediaAttaching(event, data) {
  38524. var config = this.hls.config;
  38525. if (config.capLevelOnFPSDrop) {
  38526. var media = data.media instanceof self.HTMLVideoElement ? data.media : null;
  38527. this.media = media;
  38528. if (media && typeof media.getVideoPlaybackQuality === 'function') {
  38529. this.isVideoPlaybackQualityAvailable = true;
  38530. }
  38531. self.clearInterval(this.timer);
  38532. this.timer = self.setInterval(this.checkFPSInterval.bind(this), config.fpsDroppedMonitoringPeriod);
  38533. }
  38534. };
  38535. _proto.checkFPS = function checkFPS(video, decodedFrames, droppedFrames) {
  38536. var currentTime = performance.now();
  38537. if (decodedFrames) {
  38538. if (this.lastTime) {
  38539. var currentPeriod = currentTime - this.lastTime;
  38540. var currentDropped = droppedFrames - this.lastDroppedFrames;
  38541. var currentDecoded = decodedFrames - this.lastDecodedFrames;
  38542. var droppedFPS = 1000 * currentDropped / currentPeriod;
  38543. var hls = this.hls;
  38544. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP, {
  38545. currentDropped: currentDropped,
  38546. currentDecoded: currentDecoded,
  38547. totalDroppedFrames: droppedFrames
  38548. });
  38549. if (droppedFPS > 0) {
  38550. // logger.log('checkFPS : droppedFPS/decodedFPS:' + droppedFPS/(1000 * currentDecoded / currentPeriod));
  38551. if (currentDropped > hls.config.fpsDroppedMonitoringThreshold * currentDecoded) {
  38552. var currentLevel = hls.currentLevel;
  38553. _utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('drop FPS ratio greater than max allowed value for currentLevel: ' + currentLevel);
  38554. if (currentLevel > 0 && (hls.autoLevelCapping === -1 || hls.autoLevelCapping >= currentLevel)) {
  38555. currentLevel = currentLevel - 1;
  38556. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FPS_DROP_LEVEL_CAPPING, {
  38557. level: currentLevel,
  38558. droppedLevel: hls.currentLevel
  38559. });
  38560. hls.autoLevelCapping = currentLevel;
  38561. this.streamController.nextLevelSwitch();
  38562. }
  38563. }
  38564. }
  38565. }
  38566. this.lastTime = currentTime;
  38567. this.lastDroppedFrames = droppedFrames;
  38568. this.lastDecodedFrames = decodedFrames;
  38569. }
  38570. };
  38571. _proto.checkFPSInterval = function checkFPSInterval() {
  38572. var video = this.media;
  38573. if (video) {
  38574. if (this.isVideoPlaybackQualityAvailable) {
  38575. var videoPlaybackQuality = video.getVideoPlaybackQuality();
  38576. this.checkFPS(video, videoPlaybackQuality.totalVideoFrames, videoPlaybackQuality.droppedVideoFrames);
  38577. } else {
  38578. // HTMLVideoElement doesn't include the webkit types
  38579. this.checkFPS(video, video.webkitDecodedFrameCount, video.webkitDroppedFrameCount);
  38580. }
  38581. }
  38582. };
  38583. return FPSController;
  38584. }();
  38585. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FPSController);
  38586. /***/ }),
  38587. /***/ "./src/controller/fragment-finders.ts":
  38588. /*!********************************************!*\
  38589. !*** ./src/controller/fragment-finders.ts ***!
  38590. \********************************************/
  38591. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  38592. "use strict";
  38593. __webpack_require__.r(__webpack_exports__);
  38594. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  38595. /* harmony export */ "findFragWithCC": () => (/* binding */ findFragWithCC),
  38596. /* harmony export */ "findFragmentByPDT": () => (/* binding */ findFragmentByPDT),
  38597. /* harmony export */ "findFragmentByPTS": () => (/* binding */ findFragmentByPTS),
  38598. /* harmony export */ "fragmentWithinToleranceTest": () => (/* binding */ fragmentWithinToleranceTest),
  38599. /* harmony export */ "pdtWithinToleranceTest": () => (/* binding */ pdtWithinToleranceTest)
  38600. /* harmony export */ });
  38601. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  38602. /* harmony import */ var _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/binary-search */ "./src/utils/binary-search.ts");
  38603. /**
  38604. * Returns first fragment whose endPdt value exceeds the given PDT.
  38605. * @param {Array<Fragment>} fragments - The array of candidate fragments
  38606. * @param {number|null} [PDTValue = null] - The PDT value which must be exceeded
  38607. * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start/end can be within in order to be considered contiguous
  38608. * @returns {*|null} fragment - The best matching fragment
  38609. */
  38610. function findFragmentByPDT(fragments, PDTValue, maxFragLookUpTolerance) {
  38611. if (PDTValue === null || !Array.isArray(fragments) || !fragments.length || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(PDTValue)) {
  38612. return null;
  38613. }
  38614. // if less than start
  38615. var startPDT = fragments[0].programDateTime;
  38616. if (PDTValue < (startPDT || 0)) {
  38617. return null;
  38618. }
  38619. var endPDT = fragments[fragments.length - 1].endProgramDateTime;
  38620. if (PDTValue >= (endPDT || 0)) {
  38621. return null;
  38622. }
  38623. maxFragLookUpTolerance = maxFragLookUpTolerance || 0;
  38624. for (var seg = 0; seg < fragments.length; ++seg) {
  38625. var frag = fragments[seg];
  38626. if (pdtWithinToleranceTest(PDTValue, maxFragLookUpTolerance, frag)) {
  38627. return frag;
  38628. }
  38629. }
  38630. return null;
  38631. }
  38632. /**
  38633. * Finds a fragment based on the SN of the previous fragment; or based on the needs of the current buffer.
  38634. * This method compensates for small buffer gaps by applying a tolerance to the start of any candidate fragment, thus
  38635. * breaking any traps which would cause the same fragment to be continuously selected within a small range.
  38636. * @param {*} fragPrevious - The last frag successfully appended
  38637. * @param {Array} fragments - The array of candidate fragments
  38638. * @param {number} [bufferEnd = 0] - The end of the contiguous buffered range the playhead is currently within
  38639. * @param {number} maxFragLookUpTolerance - The amount of time that a fragment's start/end can be within in order to be considered contiguous
  38640. * @returns {*} foundFrag - The best matching fragment
  38641. */
  38642. function findFragmentByPTS(fragPrevious, fragments, bufferEnd, maxFragLookUpTolerance) {
  38643. if (bufferEnd === void 0) {
  38644. bufferEnd = 0;
  38645. }
  38646. if (maxFragLookUpTolerance === void 0) {
  38647. maxFragLookUpTolerance = 0;
  38648. }
  38649. var fragNext = null;
  38650. if (fragPrevious) {
  38651. fragNext = fragments[fragPrevious.sn - fragments[0].sn + 1] || null;
  38652. } else if (bufferEnd === 0 && fragments[0].start === 0) {
  38653. fragNext = fragments[0];
  38654. }
  38655. // Prefer the next fragment if it's within tolerance
  38656. if (fragNext && fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, fragNext) === 0) {
  38657. return fragNext;
  38658. }
  38659. // We might be seeking past the tolerance so find the best match
  38660. var foundFragment = _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments, fragmentWithinToleranceTest.bind(null, bufferEnd, maxFragLookUpTolerance));
  38661. if (foundFragment && (foundFragment !== fragPrevious || !fragNext)) {
  38662. return foundFragment;
  38663. }
  38664. // If no match was found return the next fragment after fragPrevious, or null
  38665. return fragNext;
  38666. }
  38667. /**
  38668. * The test function used by the findFragmentBySn's BinarySearch to look for the best match to the current buffer conditions.
  38669. * @param {*} candidate - The fragment to test
  38670. * @param {number} [bufferEnd = 0] - The end of the current buffered range the playhead is currently within
  38671. * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous
  38672. * @returns {number} - 0 if it matches, 1 if too low, -1 if too high
  38673. */
  38674. function fragmentWithinToleranceTest(bufferEnd, maxFragLookUpTolerance, candidate) {
  38675. if (bufferEnd === void 0) {
  38676. bufferEnd = 0;
  38677. }
  38678. if (maxFragLookUpTolerance === void 0) {
  38679. maxFragLookUpTolerance = 0;
  38680. }
  38681. // eagerly accept an accurate match (no tolerance)
  38682. if (candidate.start <= bufferEnd && candidate.start + candidate.duration > bufferEnd) {
  38683. return 0;
  38684. }
  38685. // offset should be within fragment boundary - config.maxFragLookUpTolerance
  38686. // this is to cope with situations like
  38687. // bufferEnd = 9.991
  38688. // frag[Ø] : [0,10]
  38689. // frag[1] : [10,20]
  38690. // bufferEnd is within frag[0] range ... although what we are expecting is to return frag[1] here
  38691. // frag start frag start+duration
  38692. // |-----------------------------|
  38693. // <---> <--->
  38694. // ...--------><-----------------------------><---------....
  38695. // previous frag matching fragment next frag
  38696. // return -1 return 0 return 1
  38697. // logger.log(`level/sn/start/end/bufEnd:${level}/${candidate.sn}/${candidate.start}/${(candidate.start+candidate.duration)}/${bufferEnd}`);
  38698. // Set the lookup tolerance to be small enough to detect the current segment - ensures we don't skip over very small segments
  38699. var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0));
  38700. if (candidate.start + candidate.duration - candidateLookupTolerance <= bufferEnd) {
  38701. return 1;
  38702. } else if (candidate.start - candidateLookupTolerance > bufferEnd && candidate.start) {
  38703. // if maxFragLookUpTolerance will have negative value then don't return -1 for first element
  38704. return -1;
  38705. }
  38706. return 0;
  38707. }
  38708. /**
  38709. * The test function used by the findFragmentByPdt's BinarySearch to look for the best match to the current buffer conditions.
  38710. * This function tests the candidate's program date time values, as represented in Unix time
  38711. * @param {*} candidate - The fragment to test
  38712. * @param {number} [pdtBufferEnd = 0] - The Unix time representing the end of the current buffered range
  38713. * @param {number} [maxFragLookUpTolerance = 0] - The amount of time that a fragment's start can be within in order to be considered contiguous
  38714. * @returns {boolean} True if contiguous, false otherwise
  38715. */
  38716. function pdtWithinToleranceTest(pdtBufferEnd, maxFragLookUpTolerance, candidate) {
  38717. var candidateLookupTolerance = Math.min(maxFragLookUpTolerance, candidate.duration + (candidate.deltaPTS ? candidate.deltaPTS : 0)) * 1000;
  38718. // endProgramDateTime can be null, default to zero
  38719. var endProgramDateTime = candidate.endProgramDateTime || 0;
  38720. return endProgramDateTime - candidateLookupTolerance > pdtBufferEnd;
  38721. }
  38722. function findFragWithCC(fragments, cc) {
  38723. return _utils_binary_search__WEBPACK_IMPORTED_MODULE_1__["default"].search(fragments, function (candidate) {
  38724. if (candidate.cc < cc) {
  38725. return 1;
  38726. } else if (candidate.cc > cc) {
  38727. return -1;
  38728. } else {
  38729. return 0;
  38730. }
  38731. });
  38732. }
  38733. /***/ }),
  38734. /***/ "./src/controller/fragment-tracker.ts":
  38735. /*!********************************************!*\
  38736. !*** ./src/controller/fragment-tracker.ts ***!
  38737. \********************************************/
  38738. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  38739. "use strict";
  38740. __webpack_require__.r(__webpack_exports__);
  38741. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  38742. /* harmony export */ "FragmentState": () => (/* binding */ FragmentState),
  38743. /* harmony export */ "FragmentTracker": () => (/* binding */ FragmentTracker)
  38744. /* harmony export */ });
  38745. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  38746. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  38747. var FragmentState;
  38748. (function (FragmentState) {
  38749. FragmentState["NOT_LOADED"] = "NOT_LOADED";
  38750. FragmentState["APPENDING"] = "APPENDING";
  38751. FragmentState["PARTIAL"] = "PARTIAL";
  38752. FragmentState["OK"] = "OK";
  38753. })(FragmentState || (FragmentState = {}));
  38754. var FragmentTracker = /*#__PURE__*/function () {
  38755. function FragmentTracker(hls) {
  38756. this.activeFragment = null;
  38757. this.activeParts = null;
  38758. this.endListFragments = Object.create(null);
  38759. this.fragments = Object.create(null);
  38760. this.timeRanges = Object.create(null);
  38761. this.bufferPadding = 0.2;
  38762. this.hls = void 0;
  38763. this.hls = hls;
  38764. this._registerListeners();
  38765. }
  38766. var _proto = FragmentTracker.prototype;
  38767. _proto._registerListeners = function _registerListeners() {
  38768. var hls = this.hls;
  38769. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_APPENDED, this.onBufferAppended, this);
  38770. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  38771. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_LOADED, this.onFragLoaded, this);
  38772. };
  38773. _proto._unregisterListeners = function _unregisterListeners() {
  38774. var hls = this.hls;
  38775. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_APPENDED, this.onBufferAppended, this);
  38776. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  38777. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_LOADED, this.onFragLoaded, this);
  38778. };
  38779. _proto.destroy = function destroy() {
  38780. this._unregisterListeners();
  38781. // @ts-ignore
  38782. this.fragments =
  38783. // @ts-ignore
  38784. this.endListFragments = this.timeRanges = this.activeFragment = this.activeParts = null;
  38785. }
  38786. /**
  38787. * Return a Fragment with an appended range that matches the position and levelType.
  38788. * If not found any Fragment, return null
  38789. */;
  38790. _proto.getAppendedFrag = function getAppendedFrag(position, levelType) {
  38791. if (levelType === _types_loader__WEBPACK_IMPORTED_MODULE_1__.PlaylistLevelType.MAIN) {
  38792. var activeFragment = this.activeFragment,
  38793. activeParts = this.activeParts;
  38794. if (!activeFragment) {
  38795. return null;
  38796. }
  38797. if (activeParts) {
  38798. for (var i = activeParts.length; i--;) {
  38799. var activePart = activeParts[i];
  38800. var appendedPTS = activePart ? activePart.end : activeFragment.appendedPTS;
  38801. if (activePart.start <= position && appendedPTS !== undefined && position <= appendedPTS) {
  38802. // 9 is a magic number. remove parts from lookup after a match but keep some short seeks back.
  38803. if (i > 9) {
  38804. this.activeParts = activeParts.slice(i - 9);
  38805. }
  38806. return activePart;
  38807. }
  38808. }
  38809. } else if (activeFragment.start <= position && activeFragment.appendedPTS !== undefined && position <= activeFragment.appendedPTS) {
  38810. return activeFragment;
  38811. }
  38812. }
  38813. return this.getBufferedFrag(position, levelType);
  38814. }
  38815. /**
  38816. * Return a buffered Fragment that matches the position and levelType.
  38817. * A buffered Fragment is one whose loading, parsing and appending is done (completed or "partial" meaning aborted).
  38818. * If not found any Fragment, return null
  38819. */;
  38820. _proto.getBufferedFrag = function getBufferedFrag(position, levelType) {
  38821. var fragments = this.fragments;
  38822. var keys = Object.keys(fragments);
  38823. for (var i = keys.length; i--;) {
  38824. var fragmentEntity = fragments[keys[i]];
  38825. if ((fragmentEntity === null || fragmentEntity === void 0 ? void 0 : fragmentEntity.body.type) === levelType && fragmentEntity.buffered) {
  38826. var frag = fragmentEntity.body;
  38827. if (frag.start <= position && position <= frag.end) {
  38828. return frag;
  38829. }
  38830. }
  38831. }
  38832. return null;
  38833. }
  38834. /**
  38835. * Partial fragments effected by coded frame eviction will be removed
  38836. * The browser will unload parts of the buffer to free up memory for new buffer data
  38837. * Fragments will need to be reloaded when the buffer is freed up, removing partial fragments will allow them to reload(since there might be parts that are still playable)
  38838. */;
  38839. _proto.detectEvictedFragments = function detectEvictedFragments(elementaryStream, timeRange, playlistType) {
  38840. var _this = this;
  38841. if (this.timeRanges) {
  38842. this.timeRanges[elementaryStream] = timeRange;
  38843. }
  38844. // Check if any flagged fragments have been unloaded
  38845. Object.keys(this.fragments).forEach(function (key) {
  38846. var fragmentEntity = _this.fragments[key];
  38847. if (!fragmentEntity) {
  38848. return;
  38849. }
  38850. if (!fragmentEntity.buffered && !fragmentEntity.loaded) {
  38851. if (fragmentEntity.body.type === playlistType) {
  38852. _this.removeFragment(fragmentEntity.body);
  38853. }
  38854. return;
  38855. }
  38856. var esData = fragmentEntity.range[elementaryStream];
  38857. if (!esData) {
  38858. return;
  38859. }
  38860. esData.time.some(function (time) {
  38861. var isNotBuffered = !_this.isTimeBuffered(time.startPTS, time.endPTS, timeRange);
  38862. if (isNotBuffered) {
  38863. // Unregister partial fragment as it needs to load again to be reused
  38864. _this.removeFragment(fragmentEntity.body);
  38865. }
  38866. return isNotBuffered;
  38867. });
  38868. });
  38869. }
  38870. /**
  38871. * Checks if the fragment passed in is loaded in the buffer properly
  38872. * Partially loaded fragments will be registered as a partial fragment
  38873. */;
  38874. _proto.detectPartialFragments = function detectPartialFragments(data) {
  38875. var _this2 = this;
  38876. var timeRanges = this.timeRanges;
  38877. var frag = data.frag,
  38878. part = data.part;
  38879. if (!timeRanges || frag.sn === 'initSegment') {
  38880. return;
  38881. }
  38882. var fragKey = getFragmentKey(frag);
  38883. var fragmentEntity = this.fragments[fragKey];
  38884. if (!fragmentEntity) {
  38885. return;
  38886. }
  38887. Object.keys(timeRanges).forEach(function (elementaryStream) {
  38888. var streamInfo = frag.elementaryStreams[elementaryStream];
  38889. if (!streamInfo) {
  38890. return;
  38891. }
  38892. var timeRange = timeRanges[elementaryStream];
  38893. var partial = part !== null || streamInfo.partial === true;
  38894. fragmentEntity.range[elementaryStream] = _this2.getBufferedTimes(frag, part, partial, timeRange);
  38895. });
  38896. fragmentEntity.loaded = null;
  38897. if (Object.keys(fragmentEntity.range).length) {
  38898. fragmentEntity.buffered = true;
  38899. if (fragmentEntity.body.endList) {
  38900. this.endListFragments[fragmentEntity.body.type] = fragmentEntity;
  38901. }
  38902. } else {
  38903. // remove fragment if nothing was appended
  38904. this.removeFragment(fragmentEntity.body);
  38905. }
  38906. };
  38907. _proto.fragBuffered = function fragBuffered(frag) {
  38908. var fragKey = getFragmentKey(frag);
  38909. var fragmentEntity = this.fragments[fragKey];
  38910. if (fragmentEntity) {
  38911. fragmentEntity.loaded = null;
  38912. fragmentEntity.buffered = true;
  38913. }
  38914. };
  38915. _proto.getBufferedTimes = function getBufferedTimes(fragment, part, partial, timeRange) {
  38916. var buffered = {
  38917. time: [],
  38918. partial: partial
  38919. };
  38920. var startPTS = part ? part.start : fragment.start;
  38921. var endPTS = part ? part.end : fragment.end;
  38922. var minEndPTS = fragment.minEndPTS || endPTS;
  38923. var maxStartPTS = fragment.maxStartPTS || startPTS;
  38924. for (var i = 0; i < timeRange.length; i++) {
  38925. var startTime = timeRange.start(i) - this.bufferPadding;
  38926. var endTime = timeRange.end(i) + this.bufferPadding;
  38927. if (maxStartPTS >= startTime && minEndPTS <= endTime) {
  38928. // Fragment is entirely contained in buffer
  38929. // No need to check the other timeRange times since it's completely playable
  38930. buffered.time.push({
  38931. startPTS: Math.max(startPTS, timeRange.start(i)),
  38932. endPTS: Math.min(endPTS, timeRange.end(i))
  38933. });
  38934. break;
  38935. } else if (startPTS < endTime && endPTS > startTime) {
  38936. buffered.partial = true;
  38937. // Check for intersection with buffer
  38938. // Get playable sections of the fragment
  38939. buffered.time.push({
  38940. startPTS: Math.max(startPTS, timeRange.start(i)),
  38941. endPTS: Math.min(endPTS, timeRange.end(i))
  38942. });
  38943. } else if (endPTS <= startTime) {
  38944. // No need to check the rest of the timeRange as it is in order
  38945. break;
  38946. }
  38947. }
  38948. return buffered;
  38949. }
  38950. /**
  38951. * Gets the partial fragment for a certain time
  38952. */;
  38953. _proto.getPartialFragment = function getPartialFragment(time) {
  38954. var bestFragment = null;
  38955. var timePadding;
  38956. var startTime;
  38957. var endTime;
  38958. var bestOverlap = 0;
  38959. var bufferPadding = this.bufferPadding,
  38960. fragments = this.fragments;
  38961. Object.keys(fragments).forEach(function (key) {
  38962. var fragmentEntity = fragments[key];
  38963. if (!fragmentEntity) {
  38964. return;
  38965. }
  38966. if (isPartial(fragmentEntity)) {
  38967. startTime = fragmentEntity.body.start - bufferPadding;
  38968. endTime = fragmentEntity.body.end + bufferPadding;
  38969. if (time >= startTime && time <= endTime) {
  38970. // Use the fragment that has the most padding from start and end time
  38971. timePadding = Math.min(time - startTime, endTime - time);
  38972. if (bestOverlap <= timePadding) {
  38973. bestFragment = fragmentEntity.body;
  38974. bestOverlap = timePadding;
  38975. }
  38976. }
  38977. }
  38978. });
  38979. return bestFragment;
  38980. };
  38981. _proto.isEndListAppended = function isEndListAppended(type) {
  38982. var lastFragmentEntity = this.endListFragments[type];
  38983. return lastFragmentEntity !== undefined && (lastFragmentEntity.buffered || isPartial(lastFragmentEntity));
  38984. };
  38985. _proto.getState = function getState(fragment) {
  38986. var fragKey = getFragmentKey(fragment);
  38987. var fragmentEntity = this.fragments[fragKey];
  38988. if (fragmentEntity) {
  38989. if (!fragmentEntity.buffered) {
  38990. return FragmentState.APPENDING;
  38991. } else if (isPartial(fragmentEntity)) {
  38992. return FragmentState.PARTIAL;
  38993. } else {
  38994. return FragmentState.OK;
  38995. }
  38996. }
  38997. return FragmentState.NOT_LOADED;
  38998. };
  38999. _proto.isTimeBuffered = function isTimeBuffered(startPTS, endPTS, timeRange) {
  39000. var startTime;
  39001. var endTime;
  39002. for (var i = 0; i < timeRange.length; i++) {
  39003. startTime = timeRange.start(i) - this.bufferPadding;
  39004. endTime = timeRange.end(i) + this.bufferPadding;
  39005. if (startPTS >= startTime && endPTS <= endTime) {
  39006. return true;
  39007. }
  39008. if (endPTS <= startTime) {
  39009. // No need to check the rest of the timeRange as it is in order
  39010. return false;
  39011. }
  39012. }
  39013. return false;
  39014. };
  39015. _proto.onFragLoaded = function onFragLoaded(event, data) {
  39016. var frag = data.frag,
  39017. part = data.part;
  39018. // don't track initsegment (for which sn is not a number)
  39019. // don't track frags used for bitrateTest, they're irrelevant.
  39020. // don't track parts for memory efficiency
  39021. if (frag.sn === 'initSegment' || frag.bitrateTest || part) {
  39022. return;
  39023. }
  39024. var fragKey = getFragmentKey(frag);
  39025. this.fragments[fragKey] = {
  39026. body: frag,
  39027. loaded: data,
  39028. buffered: false,
  39029. range: Object.create(null)
  39030. };
  39031. };
  39032. _proto.onBufferAppended = function onBufferAppended(event, data) {
  39033. var _this3 = this;
  39034. var frag = data.frag,
  39035. part = data.part,
  39036. timeRanges = data.timeRanges;
  39037. if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_1__.PlaylistLevelType.MAIN) {
  39038. if (this.activeFragment !== frag) {
  39039. this.activeFragment = frag;
  39040. frag.appendedPTS = undefined;
  39041. }
  39042. if (part) {
  39043. var activeParts = this.activeParts;
  39044. if (!activeParts) {
  39045. this.activeParts = activeParts = [];
  39046. }
  39047. activeParts.push(part);
  39048. } else {
  39049. this.activeParts = null;
  39050. }
  39051. }
  39052. // Store the latest timeRanges loaded in the buffer
  39053. this.timeRanges = timeRanges;
  39054. Object.keys(timeRanges).forEach(function (elementaryStream) {
  39055. var timeRange = timeRanges[elementaryStream];
  39056. _this3.detectEvictedFragments(elementaryStream, timeRange);
  39057. if (!part && frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_1__.PlaylistLevelType.MAIN) {
  39058. var streamInfo = frag.elementaryStreams[elementaryStream];
  39059. if (!streamInfo) {
  39060. return;
  39061. }
  39062. for (var i = 0; i < timeRange.length; i++) {
  39063. var rangeEnd = timeRange.end(i);
  39064. if (rangeEnd <= streamInfo.endPTS && rangeEnd > streamInfo.startPTS) {
  39065. frag.appendedPTS = Math.max(rangeEnd, frag.appendedPTS || 0);
  39066. } else {
  39067. frag.appendedPTS = streamInfo.endPTS;
  39068. }
  39069. }
  39070. }
  39071. });
  39072. };
  39073. _proto.onFragBuffered = function onFragBuffered(event, data) {
  39074. this.detectPartialFragments(data);
  39075. };
  39076. _proto.hasFragment = function hasFragment(fragment) {
  39077. var fragKey = getFragmentKey(fragment);
  39078. return !!this.fragments[fragKey];
  39079. };
  39080. _proto.removeFragmentsInRange = function removeFragmentsInRange(start, end, playlistType) {
  39081. var _this4 = this;
  39082. Object.keys(this.fragments).forEach(function (key) {
  39083. var fragmentEntity = _this4.fragments[key];
  39084. if (!fragmentEntity) {
  39085. return;
  39086. }
  39087. if (fragmentEntity.buffered) {
  39088. var frag = fragmentEntity.body;
  39089. if (frag.type === playlistType && frag.start < end && frag.end > start) {
  39090. _this4.removeFragment(frag);
  39091. }
  39092. }
  39093. });
  39094. };
  39095. _proto.removeFragment = function removeFragment(fragment) {
  39096. var fragKey = getFragmentKey(fragment);
  39097. fragment.stats.loaded = 0;
  39098. fragment.clearElementaryStreamInfo();
  39099. fragment.appendedPTS = undefined;
  39100. delete this.fragments[fragKey];
  39101. if (fragment.endList) {
  39102. delete this.endListFragments[fragment.type];
  39103. }
  39104. };
  39105. _proto.removeAllFragments = function removeAllFragments() {
  39106. this.fragments = Object.create(null);
  39107. this.endListFragments = Object.create(null);
  39108. this.activeFragment = null;
  39109. this.activeParts = null;
  39110. };
  39111. return FragmentTracker;
  39112. }();
  39113. function isPartial(fragmentEntity) {
  39114. var _fragmentEntity$range, _fragmentEntity$range2;
  39115. return fragmentEntity.buffered && (((_fragmentEntity$range = fragmentEntity.range.video) === null || _fragmentEntity$range === void 0 ? void 0 : _fragmentEntity$range.partial) || ((_fragmentEntity$range2 = fragmentEntity.range.audio) === null || _fragmentEntity$range2 === void 0 ? void 0 : _fragmentEntity$range2.partial));
  39116. }
  39117. function getFragmentKey(fragment) {
  39118. return fragment.type + "_" + fragment.level + "_" + fragment.urlId + "_" + fragment.sn;
  39119. }
  39120. /***/ }),
  39121. /***/ "./src/controller/gap-controller.ts":
  39122. /*!******************************************!*\
  39123. !*** ./src/controller/gap-controller.ts ***!
  39124. \******************************************/
  39125. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  39126. "use strict";
  39127. __webpack_require__.r(__webpack_exports__);
  39128. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  39129. /* harmony export */ "MAX_START_GAP_JUMP": () => (/* binding */ MAX_START_GAP_JUMP),
  39130. /* harmony export */ "SKIP_BUFFER_HOLE_STEP_SECONDS": () => (/* binding */ SKIP_BUFFER_HOLE_STEP_SECONDS),
  39131. /* harmony export */ "SKIP_BUFFER_RANGE_START": () => (/* binding */ SKIP_BUFFER_RANGE_START),
  39132. /* harmony export */ "STALL_MINIMUM_DURATION_MS": () => (/* binding */ STALL_MINIMUM_DURATION_MS),
  39133. /* harmony export */ "default": () => (/* binding */ GapController)
  39134. /* harmony export */ });
  39135. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  39136. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  39137. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  39138. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  39139. var STALL_MINIMUM_DURATION_MS = 250;
  39140. var MAX_START_GAP_JUMP = 2.0;
  39141. var SKIP_BUFFER_HOLE_STEP_SECONDS = 0.1;
  39142. var SKIP_BUFFER_RANGE_START = 0.05;
  39143. var GapController = /*#__PURE__*/function () {
  39144. function GapController(config, media, fragmentTracker, hls) {
  39145. this.config = void 0;
  39146. this.media = null;
  39147. this.fragmentTracker = void 0;
  39148. this.hls = void 0;
  39149. this.nudgeRetry = 0;
  39150. this.stallReported = false;
  39151. this.stalled = null;
  39152. this.moved = false;
  39153. this.seeking = false;
  39154. this.config = config;
  39155. this.media = media;
  39156. this.fragmentTracker = fragmentTracker;
  39157. this.hls = hls;
  39158. }
  39159. var _proto = GapController.prototype;
  39160. _proto.destroy = function destroy() {
  39161. this.media = null;
  39162. // @ts-ignore
  39163. this.hls = this.fragmentTracker = null;
  39164. }
  39165. /**
  39166. * Checks if the playhead is stuck within a gap, and if so, attempts to free it.
  39167. * A gap is an unbuffered range between two buffered ranges (or the start and the first buffered range).
  39168. *
  39169. * @param {number} lastCurrentTime Previously read playhead position
  39170. */;
  39171. _proto.poll = function poll(lastCurrentTime, activeFrag) {
  39172. var config = this.config,
  39173. media = this.media,
  39174. stalled = this.stalled;
  39175. if (media === null) {
  39176. return;
  39177. }
  39178. var currentTime = media.currentTime,
  39179. seeking = media.seeking;
  39180. var seeked = this.seeking && !seeking;
  39181. var beginSeek = !this.seeking && seeking;
  39182. this.seeking = seeking;
  39183. // The playhead is moving, no-op
  39184. if (currentTime !== lastCurrentTime) {
  39185. this.moved = true;
  39186. if (stalled !== null) {
  39187. // The playhead is now moving, but was previously stalled
  39188. if (this.stallReported) {
  39189. var _stalledDuration = self.performance.now() - stalled;
  39190. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("playback not stuck anymore @" + currentTime + ", after " + Math.round(_stalledDuration) + "ms");
  39191. this.stallReported = false;
  39192. }
  39193. this.stalled = null;
  39194. this.nudgeRetry = 0;
  39195. }
  39196. return;
  39197. }
  39198. // Clear stalled state when beginning or finishing seeking so that we don't report stalls coming out of a seek
  39199. if (beginSeek || seeked) {
  39200. this.stalled = null;
  39201. }
  39202. // The playhead should not be moving
  39203. if (media.paused && !seeking || media.ended || media.playbackRate === 0 || !_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.getBuffered(media).length) {
  39204. return;
  39205. }
  39206. var bufferInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.bufferInfo(media, currentTime, 0);
  39207. var isBuffered = bufferInfo.len > 0;
  39208. var nextStart = bufferInfo.nextStart || 0;
  39209. // There is no playable buffer (seeked, waiting for buffer)
  39210. if (!isBuffered && !nextStart) {
  39211. return;
  39212. }
  39213. if (seeking) {
  39214. // Waiting for seeking in a buffered range to complete
  39215. var hasEnoughBuffer = bufferInfo.len > MAX_START_GAP_JUMP;
  39216. // Next buffered range is too far ahead to jump to while still seeking
  39217. var noBufferGap = !nextStart || activeFrag && activeFrag.start <= currentTime || nextStart - currentTime > MAX_START_GAP_JUMP && !this.fragmentTracker.getPartialFragment(currentTime);
  39218. if (hasEnoughBuffer || noBufferGap) {
  39219. return;
  39220. }
  39221. // Reset moved state when seeking to a point in or before a gap
  39222. this.moved = false;
  39223. }
  39224. // Skip start gaps if we haven't played, but the last poll detected the start of a stall
  39225. // The addition poll gives the browser a chance to jump the gap for us
  39226. if (!this.moved && this.stalled !== null) {
  39227. var _level$details;
  39228. // Jump start gaps within jump threshold
  39229. var startJump = Math.max(nextStart, bufferInfo.start || 0) - currentTime;
  39230. // When joining a live stream with audio tracks, account for live playlist window sliding by allowing
  39231. // a larger jump over start gaps caused by the audio-stream-controller buffering a start fragment
  39232. // that begins over 1 target duration after the video start position.
  39233. var level = this.hls.levels ? this.hls.levels[this.hls.currentLevel] : null;
  39234. var isLive = level === null || level === void 0 ? void 0 : (_level$details = level.details) === null || _level$details === void 0 ? void 0 : _level$details.live;
  39235. var maxStartGapJump = isLive ? level.details.targetduration * 2 : MAX_START_GAP_JUMP;
  39236. if (startJump > 0 && startJump <= maxStartGapJump) {
  39237. this._trySkipBufferHole(null);
  39238. return;
  39239. }
  39240. }
  39241. // Start tracking stall time
  39242. var tnow = self.performance.now();
  39243. if (stalled === null) {
  39244. this.stalled = tnow;
  39245. return;
  39246. }
  39247. var stalledDuration = tnow - stalled;
  39248. if (!seeking && stalledDuration >= STALL_MINIMUM_DURATION_MS) {
  39249. // Report stalling after trying to fix
  39250. this._reportStall(bufferInfo);
  39251. if (!this.media) {
  39252. return;
  39253. }
  39254. }
  39255. var bufferedWithHoles = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.bufferInfo(media, currentTime, config.maxBufferHole);
  39256. this._tryFixBufferStall(bufferedWithHoles, stalledDuration);
  39257. }
  39258. /**
  39259. * Detects and attempts to fix known buffer stalling issues.
  39260. * @param bufferInfo - The properties of the current buffer.
  39261. * @param stalledDurationMs - The amount of time Hls.js has been stalling for.
  39262. * @private
  39263. */;
  39264. _proto._tryFixBufferStall = function _tryFixBufferStall(bufferInfo, stalledDurationMs) {
  39265. var config = this.config,
  39266. fragmentTracker = this.fragmentTracker,
  39267. media = this.media;
  39268. if (media === null) {
  39269. return;
  39270. }
  39271. var currentTime = media.currentTime;
  39272. var partial = fragmentTracker.getPartialFragment(currentTime);
  39273. if (partial) {
  39274. // Try to skip over the buffer hole caused by a partial fragment
  39275. // This method isn't limited by the size of the gap between buffered ranges
  39276. var targetTime = this._trySkipBufferHole(partial);
  39277. // we return here in this case, meaning
  39278. // the branch below only executes when we don't handle a partial fragment
  39279. if (targetTime || !this.media) {
  39280. return;
  39281. }
  39282. }
  39283. // if we haven't had to skip over a buffer hole of a partial fragment
  39284. // we may just have to "nudge" the playlist as the browser decoding/rendering engine
  39285. // needs to cross some sort of threshold covering all source-buffers content
  39286. // to start playing properly.
  39287. if (bufferInfo.len > config.maxBufferHole && stalledDurationMs > config.highBufferWatchdogPeriod * 1000) {
  39288. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Trying to nudge playhead over buffer-hole');
  39289. // Try to nudge currentTime over a buffer hole if we've been stalling for the configured amount of seconds
  39290. // We only try to jump the hole if it's under the configured size
  39291. // Reset stalled so to rearm watchdog timer
  39292. this.stalled = null;
  39293. this._tryNudgeBuffer();
  39294. }
  39295. }
  39296. /**
  39297. * Triggers a BUFFER_STALLED_ERROR event, but only once per stall period.
  39298. * @param bufferLen - The playhead distance from the end of the current buffer segment.
  39299. * @private
  39300. */;
  39301. _proto._reportStall = function _reportStall(bufferInfo) {
  39302. var hls = this.hls,
  39303. media = this.media,
  39304. stallReported = this.stallReported;
  39305. if (!stallReported && media) {
  39306. // Report stalled error once
  39307. this.stallReported = true;
  39308. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("Playback stalling at @" + media.currentTime + " due to low buffer (" + JSON.stringify(bufferInfo) + ")");
  39309. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, {
  39310. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  39311. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_STALLED_ERROR,
  39312. fatal: false,
  39313. buffer: bufferInfo.len
  39314. });
  39315. }
  39316. }
  39317. /**
  39318. * Attempts to fix buffer stalls by jumping over known gaps caused by partial fragments
  39319. * @param partial - The partial fragment found at the current time (where playback is stalling).
  39320. * @private
  39321. */;
  39322. _proto._trySkipBufferHole = function _trySkipBufferHole(partial) {
  39323. var config = this.config,
  39324. hls = this.hls,
  39325. media = this.media;
  39326. if (media === null) {
  39327. return 0;
  39328. }
  39329. var currentTime = media.currentTime;
  39330. var lastEndTime = 0;
  39331. // Check if currentTime is between unbuffered regions of partial fragments
  39332. var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_0__.BufferHelper.getBuffered(media);
  39333. for (var i = 0; i < buffered.length; i++) {
  39334. var startTime = buffered.start(i);
  39335. if (currentTime + config.maxBufferHole >= lastEndTime && currentTime < startTime) {
  39336. var targetTime = Math.max(startTime + SKIP_BUFFER_RANGE_START, media.currentTime + SKIP_BUFFER_HOLE_STEP_SECONDS);
  39337. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("skipping hole, adjusting currentTime from " + currentTime + " to " + targetTime);
  39338. this.moved = true;
  39339. this.stalled = null;
  39340. media.currentTime = targetTime;
  39341. if (partial) {
  39342. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, {
  39343. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  39344. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_SEEK_OVER_HOLE,
  39345. fatal: false,
  39346. reason: "fragment loaded with buffer holes, seeking from " + currentTime + " to " + targetTime,
  39347. frag: partial
  39348. });
  39349. }
  39350. return targetTime;
  39351. }
  39352. lastEndTime = buffered.end(i);
  39353. }
  39354. return 0;
  39355. }
  39356. /**
  39357. * Attempts to fix buffer stalls by advancing the mediaElement's current time by a small amount.
  39358. * @private
  39359. */;
  39360. _proto._tryNudgeBuffer = function _tryNudgeBuffer() {
  39361. var config = this.config,
  39362. hls = this.hls,
  39363. media = this.media,
  39364. nudgeRetry = this.nudgeRetry;
  39365. if (media === null) {
  39366. return;
  39367. }
  39368. var currentTime = media.currentTime;
  39369. this.nudgeRetry++;
  39370. if (nudgeRetry < config.nudgeMaxRetry) {
  39371. var targetTime = currentTime + (nudgeRetry + 1) * config.nudgeOffset;
  39372. // playback stalled in buffered area ... let's nudge currentTime to try to overcome this
  39373. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("Nudging 'currentTime' from " + currentTime + " to " + targetTime);
  39374. media.currentTime = targetTime;
  39375. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, {
  39376. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  39377. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_NUDGE_ON_STALL,
  39378. fatal: false
  39379. });
  39380. } else {
  39381. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.error("Playhead still not moving while enough data buffered @" + currentTime + " after " + config.nudgeMaxRetry + " nudges");
  39382. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, {
  39383. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  39384. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.BUFFER_STALLED_ERROR,
  39385. fatal: true
  39386. });
  39387. }
  39388. };
  39389. return GapController;
  39390. }();
  39391. /***/ }),
  39392. /***/ "./src/controller/id3-track-controller.ts":
  39393. /*!************************************************!*\
  39394. !*** ./src/controller/id3-track-controller.ts ***!
  39395. \************************************************/
  39396. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  39397. "use strict";
  39398. __webpack_require__.r(__webpack_exports__);
  39399. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  39400. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  39401. /* harmony export */ });
  39402. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  39403. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  39404. /* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts");
  39405. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  39406. /* harmony import */ var _loader_date_range__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../loader/date-range */ "./src/loader/date-range.ts");
  39407. /* harmony import */ var _types_demuxer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/demuxer */ "./src/types/demuxer.ts");
  39408. var MIN_CUE_DURATION = 0.25;
  39409. function getCueClass() {
  39410. // Attempt to recreate Safari functionality by creating
  39411. // WebKitDataCue objects when available and store the decoded
  39412. // ID3 data in the value property of the cue
  39413. return self.WebKitDataCue || self.VTTCue || self.TextTrackCue;
  39414. }
  39415. // VTTCue latest draft allows an infinite duration, fallback
  39416. // to MAX_VALUE if necessary
  39417. var MAX_CUE_ENDTIME = function () {
  39418. var Cue = getCueClass();
  39419. try {
  39420. new Cue(0, Number.POSITIVE_INFINITY, '');
  39421. } catch (e) {
  39422. return Number.MAX_VALUE;
  39423. }
  39424. return Number.POSITIVE_INFINITY;
  39425. }();
  39426. function dateRangeDateToTimelineSeconds(date, offset) {
  39427. return date.getTime() / 1000 - offset;
  39428. }
  39429. function hexToArrayBuffer(str) {
  39430. return Uint8Array.from(str.replace(/^0x/, '').replace(/([\da-fA-F]{2}) ?/g, '0x$1 ').replace(/ +$/, '').split(' ')).buffer;
  39431. }
  39432. var ID3TrackController = /*#__PURE__*/function () {
  39433. function ID3TrackController(hls) {
  39434. this.hls = void 0;
  39435. this.id3Track = null;
  39436. this.media = null;
  39437. this.dateRangeCuesAppended = {};
  39438. this.hls = hls;
  39439. this._registerListeners();
  39440. }
  39441. var _proto = ID3TrackController.prototype;
  39442. _proto.destroy = function destroy() {
  39443. this._unregisterListeners();
  39444. this.id3Track = null;
  39445. this.media = null;
  39446. this.dateRangeCuesAppended = {};
  39447. // @ts-ignore
  39448. this.hls = null;
  39449. };
  39450. _proto._registerListeners = function _registerListeners() {
  39451. var hls = this.hls;
  39452. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  39453. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  39454. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  39455. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_METADATA, this.onFragParsingMetadata, this);
  39456. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  39457. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED, this.onLevelUpdated, this);
  39458. };
  39459. _proto._unregisterListeners = function _unregisterListeners() {
  39460. var hls = this.hls;
  39461. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  39462. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  39463. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  39464. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_METADATA, this.onFragParsingMetadata, this);
  39465. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  39466. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED, this.onLevelUpdated, this);
  39467. }
  39468. // Add ID3 metatadata text track.
  39469. ;
  39470. _proto.onMediaAttached = function onMediaAttached(event, data) {
  39471. this.media = data.media;
  39472. };
  39473. _proto.onMediaDetaching = function onMediaDetaching() {
  39474. if (!this.id3Track) {
  39475. return;
  39476. }
  39477. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.clearCurrentCues)(this.id3Track);
  39478. this.id3Track = null;
  39479. this.media = null;
  39480. this.dateRangeCuesAppended = {};
  39481. };
  39482. _proto.onManifestLoading = function onManifestLoading() {
  39483. this.dateRangeCuesAppended = {};
  39484. };
  39485. _proto.createTrack = function createTrack(media) {
  39486. var track = this.getID3Track(media.textTracks);
  39487. track.mode = 'hidden';
  39488. return track;
  39489. };
  39490. _proto.getID3Track = function getID3Track(textTracks) {
  39491. if (!this.media) {
  39492. return;
  39493. }
  39494. for (var i = 0; i < textTracks.length; i++) {
  39495. var textTrack = textTracks[i];
  39496. if (textTrack.kind === 'metadata' && textTrack.label === 'id3') {
  39497. // send 'addtrack' when reusing the textTrack for metadata,
  39498. // same as what we do for captions
  39499. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.sendAddTrackEvent)(textTrack, this.media);
  39500. return textTrack;
  39501. }
  39502. }
  39503. return this.media.addTextTrack('metadata', 'id3');
  39504. };
  39505. _proto.onFragParsingMetadata = function onFragParsingMetadata(event, data) {
  39506. if (!this.media) {
  39507. return;
  39508. }
  39509. var _this$hls$config = this.hls.config,
  39510. enableEmsgMetadataCues = _this$hls$config.enableEmsgMetadataCues,
  39511. enableID3MetadataCues = _this$hls$config.enableID3MetadataCues;
  39512. if (!enableEmsgMetadataCues && !enableID3MetadataCues) {
  39513. return;
  39514. }
  39515. var samples = data.samples;
  39516. // create track dynamically
  39517. if (!this.id3Track) {
  39518. this.id3Track = this.createTrack(this.media);
  39519. }
  39520. var Cue = getCueClass();
  39521. for (var i = 0; i < samples.length; i++) {
  39522. var type = samples[i].type;
  39523. if (type === _types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.emsg && !enableEmsgMetadataCues || !enableID3MetadataCues) {
  39524. continue;
  39525. }
  39526. var frames = _demux_id3__WEBPACK_IMPORTED_MODULE_3__.getID3Frames(samples[i].data);
  39527. if (frames) {
  39528. var startTime = samples[i].pts;
  39529. var endTime = startTime + samples[i].duration;
  39530. if (endTime > MAX_CUE_ENDTIME) {
  39531. endTime = MAX_CUE_ENDTIME;
  39532. }
  39533. var timeDiff = endTime - startTime;
  39534. if (timeDiff <= 0) {
  39535. endTime = startTime + MIN_CUE_DURATION;
  39536. }
  39537. for (var j = 0; j < frames.length; j++) {
  39538. var frame = frames[j];
  39539. // Safari doesn't put the timestamp frame in the TextTrack
  39540. if (!_demux_id3__WEBPACK_IMPORTED_MODULE_3__.isTimeStampFrame(frame)) {
  39541. // add a bounds to any unbounded cues
  39542. this.updateId3CueEnds(startTime);
  39543. var cue = new Cue(startTime, endTime, '');
  39544. cue.value = frame;
  39545. if (type) {
  39546. cue.type = type;
  39547. }
  39548. this.id3Track.addCue(cue);
  39549. }
  39550. }
  39551. }
  39552. }
  39553. };
  39554. _proto.updateId3CueEnds = function updateId3CueEnds(startTime) {
  39555. var _this$id3Track;
  39556. var cues = (_this$id3Track = this.id3Track) === null || _this$id3Track === void 0 ? void 0 : _this$id3Track.cues;
  39557. if (cues) {
  39558. for (var i = cues.length; i--;) {
  39559. var cue = cues[i];
  39560. if (cue.startTime < startTime && cue.endTime === MAX_CUE_ENDTIME) {
  39561. cue.endTime = startTime;
  39562. }
  39563. }
  39564. }
  39565. };
  39566. _proto.onBufferFlushing = function onBufferFlushing(event, _ref) {
  39567. var startOffset = _ref.startOffset,
  39568. endOffset = _ref.endOffset,
  39569. type = _ref.type;
  39570. var id3Track = this.id3Track,
  39571. hls = this.hls;
  39572. if (!hls) {
  39573. return;
  39574. }
  39575. var _hls$config = hls.config,
  39576. enableEmsgMetadataCues = _hls$config.enableEmsgMetadataCues,
  39577. enableID3MetadataCues = _hls$config.enableID3MetadataCues;
  39578. if (id3Track && (enableEmsgMetadataCues || enableID3MetadataCues)) {
  39579. var predicate;
  39580. if (type === 'audio') {
  39581. predicate = function predicate(cue) {
  39582. return cue.type === _types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.audioId3 && enableID3MetadataCues;
  39583. };
  39584. } else if (type === 'video') {
  39585. predicate = function predicate(cue) {
  39586. return cue.type === _types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.emsg && enableEmsgMetadataCues;
  39587. };
  39588. } else {
  39589. predicate = function predicate(cue) {
  39590. return cue.type === _types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.audioId3 && enableID3MetadataCues || cue.type === _types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.emsg && enableEmsgMetadataCues;
  39591. };
  39592. }
  39593. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.removeCuesInRange)(id3Track, startOffset, endOffset, predicate);
  39594. }
  39595. };
  39596. _proto.onLevelUpdated = function onLevelUpdated(event, _ref2) {
  39597. var _this = this;
  39598. var details = _ref2.details;
  39599. if (!this.media || !details.hasProgramDateTime || !this.hls.config.enableDateRangeMetadataCues) {
  39600. return;
  39601. }
  39602. var dateRangeCuesAppended = this.dateRangeCuesAppended,
  39603. id3Track = this.id3Track;
  39604. var dateRanges = details.dateRanges;
  39605. var ids = Object.keys(dateRanges);
  39606. // Remove cues from track not found in details.dateRanges
  39607. if (id3Track) {
  39608. var idsToRemove = Object.keys(dateRangeCuesAppended).filter(function (id) {
  39609. return !ids.includes(id);
  39610. });
  39611. var _loop = function _loop(i) {
  39612. var id = idsToRemove[i];
  39613. Object.keys(dateRangeCuesAppended[id].cues).forEach(function (key) {
  39614. id3Track.removeCue(dateRangeCuesAppended[id].cues[key]);
  39615. });
  39616. delete dateRangeCuesAppended[id];
  39617. };
  39618. for (var i = idsToRemove.length; i--;) {
  39619. _loop(i);
  39620. }
  39621. }
  39622. // Exit if the playlist does not have Date Ranges or does not have Program Date Time
  39623. var lastFragment = details.fragments[details.fragments.length - 1];
  39624. if (ids.length === 0 || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(lastFragment === null || lastFragment === void 0 ? void 0 : lastFragment.programDateTime)) {
  39625. return;
  39626. }
  39627. if (!this.id3Track) {
  39628. this.id3Track = this.createTrack(this.media);
  39629. }
  39630. var dateTimeOffset = lastFragment.programDateTime / 1000 - lastFragment.start;
  39631. var Cue = getCueClass();
  39632. var _loop2 = function _loop2(_i) {
  39633. var id = ids[_i];
  39634. var dateRange = dateRanges[id];
  39635. var appendedDateRangeCues = dateRangeCuesAppended[id];
  39636. var cues = (appendedDateRangeCues === null || appendedDateRangeCues === void 0 ? void 0 : appendedDateRangeCues.cues) || {};
  39637. var durationKnown = (appendedDateRangeCues === null || appendedDateRangeCues === void 0 ? void 0 : appendedDateRangeCues.durationKnown) || false;
  39638. var startTime = dateRangeDateToTimelineSeconds(dateRange.startDate, dateTimeOffset);
  39639. var endTime = MAX_CUE_ENDTIME;
  39640. var endDate = dateRange.endDate;
  39641. if (endDate) {
  39642. endTime = dateRangeDateToTimelineSeconds(endDate, dateTimeOffset);
  39643. durationKnown = true;
  39644. } else if (dateRange.endOnNext && !durationKnown) {
  39645. var nextDateRangeWithSameClass = ids.reduce(function (filterMapArray, id) {
  39646. var candidate = dateRanges[id];
  39647. if (candidate.class === dateRange.class && candidate.id !== id && candidate.startDate > dateRange.startDate) {
  39648. filterMapArray.push(candidate);
  39649. }
  39650. return filterMapArray;
  39651. }, []).sort(function (a, b) {
  39652. return a.startDate.getTime() - b.startDate.getTime();
  39653. })[0];
  39654. if (nextDateRangeWithSameClass) {
  39655. endTime = dateRangeDateToTimelineSeconds(nextDateRangeWithSameClass.startDate, dateTimeOffset);
  39656. durationKnown = true;
  39657. }
  39658. }
  39659. var attributes = Object.keys(dateRange.attr);
  39660. for (var j = 0; j < attributes.length; j++) {
  39661. var key = attributes[j];
  39662. if (key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.ID || key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.CLASS || key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.START_DATE || key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.DURATION || key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.END_DATE || key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.END_ON_NEXT) {
  39663. continue;
  39664. }
  39665. var cue = cues[key];
  39666. if (cue) {
  39667. if (durationKnown && !appendedDateRangeCues.durationKnown) {
  39668. cue.endTime = endTime;
  39669. }
  39670. } else {
  39671. var data = dateRange.attr[key];
  39672. cue = new Cue(startTime, endTime, '');
  39673. if (key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.SCTE35_OUT || key === _loader_date_range__WEBPACK_IMPORTED_MODULE_4__.DateRangeAttribute.SCTE35_IN) {
  39674. data = hexToArrayBuffer(data);
  39675. }
  39676. cue.value = {
  39677. key: key,
  39678. data: data
  39679. };
  39680. cue.type = _types_demuxer__WEBPACK_IMPORTED_MODULE_5__.MetadataSchema.dateRange;
  39681. _this.id3Track.addCue(cue);
  39682. cues[key] = cue;
  39683. }
  39684. }
  39685. dateRangeCuesAppended[id] = {
  39686. cues: cues,
  39687. dateRange: dateRange,
  39688. durationKnown: durationKnown
  39689. };
  39690. };
  39691. for (var _i = 0; _i < ids.length; _i++) {
  39692. _loop2(_i);
  39693. }
  39694. };
  39695. return ID3TrackController;
  39696. }();
  39697. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ID3TrackController);
  39698. /***/ }),
  39699. /***/ "./src/controller/latency-controller.ts":
  39700. /*!**********************************************!*\
  39701. !*** ./src/controller/latency-controller.ts ***!
  39702. \**********************************************/
  39703. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  39704. "use strict";
  39705. __webpack_require__.r(__webpack_exports__);
  39706. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  39707. /* harmony export */ "default": () => (/* binding */ LatencyController)
  39708. /* harmony export */ });
  39709. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  39710. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  39711. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  39712. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  39713. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  39714. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  39715. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  39716. var LatencyController = /*#__PURE__*/function () {
  39717. function LatencyController(hls) {
  39718. var _this = this;
  39719. this.hls = void 0;
  39720. this.config = void 0;
  39721. this.media = null;
  39722. this.levelDetails = null;
  39723. this.currentTime = 0;
  39724. this.stallCount = 0;
  39725. this._latency = null;
  39726. this.timeupdateHandler = function () {
  39727. return _this.timeupdate();
  39728. };
  39729. this.hls = hls;
  39730. this.config = hls.config;
  39731. this.registerListeners();
  39732. }
  39733. var _proto = LatencyController.prototype;
  39734. _proto.destroy = function destroy() {
  39735. this.unregisterListeners();
  39736. this.onMediaDetaching();
  39737. this.levelDetails = null;
  39738. // @ts-ignore
  39739. this.hls = this.timeupdateHandler = null;
  39740. };
  39741. _proto.registerListeners = function registerListeners() {
  39742. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  39743. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  39744. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  39745. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED, this.onLevelUpdated, this);
  39746. this.hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, this.onError, this);
  39747. };
  39748. _proto.unregisterListeners = function unregisterListeners() {
  39749. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHED, this.onMediaAttached);
  39750. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching);
  39751. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading);
  39752. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_UPDATED, this.onLevelUpdated);
  39753. this.hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, this.onError);
  39754. };
  39755. _proto.onMediaAttached = function onMediaAttached(event, data) {
  39756. this.media = data.media;
  39757. this.media.addEventListener('timeupdate', this.timeupdateHandler);
  39758. };
  39759. _proto.onMediaDetaching = function onMediaDetaching() {
  39760. if (this.media) {
  39761. this.media.removeEventListener('timeupdate', this.timeupdateHandler);
  39762. this.media = null;
  39763. }
  39764. };
  39765. _proto.onManifestLoading = function onManifestLoading() {
  39766. this.levelDetails = null;
  39767. this._latency = null;
  39768. this.stallCount = 0;
  39769. };
  39770. _proto.onLevelUpdated = function onLevelUpdated(event, _ref) {
  39771. var details = _ref.details;
  39772. this.levelDetails = details;
  39773. if (details.advanced) {
  39774. this.timeupdate();
  39775. }
  39776. if (!details.live && this.media) {
  39777. this.media.removeEventListener('timeupdate', this.timeupdateHandler);
  39778. }
  39779. };
  39780. _proto.onError = function onError(event, data) {
  39781. if (data.details !== _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.BUFFER_STALLED_ERROR) {
  39782. return;
  39783. }
  39784. this.stallCount++;
  39785. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn('[playback-rate-controller]: Stall detected, adjusting target latency');
  39786. };
  39787. _proto.timeupdate = function timeupdate() {
  39788. var media = this.media,
  39789. levelDetails = this.levelDetails;
  39790. if (!media || !levelDetails) {
  39791. return;
  39792. }
  39793. this.currentTime = media.currentTime;
  39794. var latency = this.computeLatency();
  39795. if (latency === null) {
  39796. return;
  39797. }
  39798. this._latency = latency;
  39799. // Adapt playbackRate to meet target latency in low-latency mode
  39800. var _this$config = this.config,
  39801. lowLatencyMode = _this$config.lowLatencyMode,
  39802. maxLiveSyncPlaybackRate = _this$config.maxLiveSyncPlaybackRate;
  39803. if (!lowLatencyMode || maxLiveSyncPlaybackRate === 1) {
  39804. return;
  39805. }
  39806. var targetLatency = this.targetLatency;
  39807. if (targetLatency === null) {
  39808. return;
  39809. }
  39810. var distanceFromTarget = latency - targetLatency;
  39811. // Only adjust playbackRate when within one target duration of targetLatency
  39812. // and more than one second from under-buffering.
  39813. // Playback further than one target duration from target can be considered DVR playback.
  39814. var liveMinLatencyDuration = Math.min(this.maxLatency, targetLatency + levelDetails.targetduration);
  39815. var inLiveRange = distanceFromTarget < liveMinLatencyDuration;
  39816. if (levelDetails.live && inLiveRange && distanceFromTarget > 0.05 && this.forwardBufferLength > 1) {
  39817. var max = Math.min(2, Math.max(1.0, maxLiveSyncPlaybackRate));
  39818. var rate = Math.round(2 / (1 + Math.exp(-0.75 * distanceFromTarget - this.edgeStalled)) * 20) / 20;
  39819. media.playbackRate = Math.min(max, Math.max(1, rate));
  39820. } else if (media.playbackRate !== 1 && media.playbackRate !== 0) {
  39821. media.playbackRate = 1;
  39822. }
  39823. };
  39824. _proto.estimateLiveEdge = function estimateLiveEdge() {
  39825. var levelDetails = this.levelDetails;
  39826. if (levelDetails === null) {
  39827. return null;
  39828. }
  39829. return levelDetails.edge + levelDetails.age;
  39830. };
  39831. _proto.computeLatency = function computeLatency() {
  39832. var liveEdge = this.estimateLiveEdge();
  39833. if (liveEdge === null) {
  39834. return null;
  39835. }
  39836. return liveEdge - this.currentTime;
  39837. };
  39838. _createClass(LatencyController, [{
  39839. key: "latency",
  39840. get: function get() {
  39841. return this._latency || 0;
  39842. }
  39843. }, {
  39844. key: "maxLatency",
  39845. get: function get() {
  39846. var config = this.config,
  39847. levelDetails = this.levelDetails;
  39848. if (config.liveMaxLatencyDuration !== undefined) {
  39849. return config.liveMaxLatencyDuration;
  39850. }
  39851. return levelDetails ? config.liveMaxLatencyDurationCount * levelDetails.targetduration : 0;
  39852. }
  39853. }, {
  39854. key: "targetLatency",
  39855. get: function get() {
  39856. var levelDetails = this.levelDetails;
  39857. if (levelDetails === null) {
  39858. return null;
  39859. }
  39860. var holdBack = levelDetails.holdBack,
  39861. partHoldBack = levelDetails.partHoldBack,
  39862. targetduration = levelDetails.targetduration;
  39863. var _this$config2 = this.config,
  39864. liveSyncDuration = _this$config2.liveSyncDuration,
  39865. liveSyncDurationCount = _this$config2.liveSyncDurationCount,
  39866. lowLatencyMode = _this$config2.lowLatencyMode;
  39867. var userConfig = this.hls.userConfig;
  39868. var targetLatency = lowLatencyMode ? partHoldBack || holdBack : holdBack;
  39869. if (userConfig.liveSyncDuration || userConfig.liveSyncDurationCount || targetLatency === 0) {
  39870. targetLatency = liveSyncDuration !== undefined ? liveSyncDuration : liveSyncDurationCount * targetduration;
  39871. }
  39872. var maxLiveSyncOnStallIncrease = targetduration;
  39873. var liveSyncOnStallIncrease = 1.0;
  39874. return targetLatency + Math.min(this.stallCount * liveSyncOnStallIncrease, maxLiveSyncOnStallIncrease);
  39875. }
  39876. }, {
  39877. key: "liveSyncPosition",
  39878. get: function get() {
  39879. var liveEdge = this.estimateLiveEdge();
  39880. var targetLatency = this.targetLatency;
  39881. var levelDetails = this.levelDetails;
  39882. if (liveEdge === null || targetLatency === null || levelDetails === null) {
  39883. return null;
  39884. }
  39885. var edge = levelDetails.edge;
  39886. var syncPosition = liveEdge - targetLatency - this.edgeStalled;
  39887. var min = edge - levelDetails.totalduration;
  39888. var max = edge - (this.config.lowLatencyMode && levelDetails.partTarget || levelDetails.targetduration);
  39889. return Math.min(Math.max(min, syncPosition), max);
  39890. }
  39891. }, {
  39892. key: "drift",
  39893. get: function get() {
  39894. var levelDetails = this.levelDetails;
  39895. if (levelDetails === null) {
  39896. return 1;
  39897. }
  39898. return levelDetails.drift;
  39899. }
  39900. }, {
  39901. key: "edgeStalled",
  39902. get: function get() {
  39903. var levelDetails = this.levelDetails;
  39904. if (levelDetails === null) {
  39905. return 0;
  39906. }
  39907. var maxLevelUpdateAge = (this.config.lowLatencyMode && levelDetails.partTarget || levelDetails.targetduration) * 3;
  39908. return Math.max(levelDetails.age - maxLevelUpdateAge, 0);
  39909. }
  39910. }, {
  39911. key: "forwardBufferLength",
  39912. get: function get() {
  39913. var media = this.media,
  39914. levelDetails = this.levelDetails;
  39915. if (!media || !levelDetails) {
  39916. return 0;
  39917. }
  39918. var bufferedRanges = media.buffered.length;
  39919. return (bufferedRanges ? media.buffered.end(bufferedRanges - 1) : levelDetails.edge) - this.currentTime;
  39920. }
  39921. }]);
  39922. return LatencyController;
  39923. }();
  39924. /***/ }),
  39925. /***/ "./src/controller/level-controller.ts":
  39926. /*!********************************************!*\
  39927. !*** ./src/controller/level-controller.ts ***!
  39928. \********************************************/
  39929. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  39930. "use strict";
  39931. __webpack_require__.r(__webpack_exports__);
  39932. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  39933. /* harmony export */ "default": () => (/* binding */ LevelController)
  39934. /* harmony export */ });
  39935. /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts");
  39936. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  39937. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  39938. /* harmony import */ var _utils_codecs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/codecs */ "./src/utils/codecs.ts");
  39939. /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts");
  39940. /* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts");
  39941. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  39942. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  39943. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  39944. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  39945. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  39946. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  39947. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  39948. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  39949. /*
  39950. * Level Controller
  39951. */
  39952. var chromeOrFirefox = /chrome|firefox/.test(navigator.userAgent.toLowerCase());
  39953. var LevelController = /*#__PURE__*/function (_BasePlaylistControll) {
  39954. _inheritsLoose(LevelController, _BasePlaylistControll);
  39955. function LevelController(hls) {
  39956. var _this;
  39957. _this = _BasePlaylistControll.call(this, hls, '[level-controller]') || this;
  39958. _this._levels = [];
  39959. _this._firstLevel = -1;
  39960. _this._startLevel = void 0;
  39961. _this.currentLevelIndex = -1;
  39962. _this.manualLevelIndex = -1;
  39963. _this.onParsedComplete = void 0;
  39964. _this._registerListeners();
  39965. return _this;
  39966. }
  39967. var _proto = LevelController.prototype;
  39968. _proto._registerListeners = function _registerListeners() {
  39969. var hls = this.hls;
  39970. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED, this.onManifestLoaded, this);
  39971. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  39972. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
  39973. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED, this.onFragLoaded, this);
  39974. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, this.onError, this);
  39975. };
  39976. _proto._unregisterListeners = function _unregisterListeners() {
  39977. var hls = this.hls;
  39978. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED, this.onManifestLoaded, this);
  39979. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  39980. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
  39981. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED, this.onFragLoaded, this);
  39982. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, this.onError, this);
  39983. };
  39984. _proto.destroy = function destroy() {
  39985. this._unregisterListeners();
  39986. this.manualLevelIndex = -1;
  39987. this._levels.length = 0;
  39988. _BasePlaylistControll.prototype.destroy.call(this);
  39989. };
  39990. _proto.startLoad = function startLoad() {
  39991. var levels = this._levels;
  39992. // clean up live level details to force reload them, and reset load errors
  39993. levels.forEach(function (level) {
  39994. level.loadError = 0;
  39995. });
  39996. _BasePlaylistControll.prototype.startLoad.call(this);
  39997. };
  39998. _proto.onManifestLoaded = function onManifestLoaded(event, data) {
  39999. var levels = [];
  40000. var audioTracks = [];
  40001. var subtitleTracks = [];
  40002. var bitrateStart;
  40003. var levelSet = {};
  40004. var levelFromSet;
  40005. var resolutionFound = false;
  40006. var videoCodecFound = false;
  40007. var audioCodecFound = false;
  40008. // regroup redundant levels together
  40009. data.levels.forEach(function (levelParsed) {
  40010. var attributes = levelParsed.attrs;
  40011. resolutionFound = resolutionFound || !!(levelParsed.width && levelParsed.height);
  40012. videoCodecFound = videoCodecFound || !!levelParsed.videoCodec;
  40013. audioCodecFound = audioCodecFound || !!levelParsed.audioCodec;
  40014. // erase audio codec info if browser does not support mp4a.40.34.
  40015. // demuxer will autodetect codec and fallback to mpeg/audio
  40016. if (chromeOrFirefox && levelParsed.audioCodec && levelParsed.audioCodec.indexOf('mp4a.40.34') !== -1) {
  40017. levelParsed.audioCodec = undefined;
  40018. }
  40019. var levelKey = levelParsed.bitrate + "-" + levelParsed.attrs.RESOLUTION + "-" + levelParsed.attrs.CODECS;
  40020. levelFromSet = levelSet[levelKey];
  40021. if (!levelFromSet) {
  40022. levelFromSet = new _types_level__WEBPACK_IMPORTED_MODULE_0__.Level(levelParsed);
  40023. levelSet[levelKey] = levelFromSet;
  40024. levels.push(levelFromSet);
  40025. } else {
  40026. levelFromSet.url.push(levelParsed.url);
  40027. }
  40028. if (attributes) {
  40029. if (attributes.AUDIO) {
  40030. (0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addGroupId)(levelFromSet, 'audio', attributes.AUDIO);
  40031. }
  40032. if (attributes.SUBTITLES) {
  40033. (0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addGroupId)(levelFromSet, 'text', attributes.SUBTITLES);
  40034. }
  40035. }
  40036. });
  40037. // remove audio-only level if we also have levels with video codecs or RESOLUTION signalled
  40038. if ((resolutionFound || videoCodecFound) && audioCodecFound) {
  40039. levels = levels.filter(function (_ref) {
  40040. var videoCodec = _ref.videoCodec,
  40041. width = _ref.width,
  40042. height = _ref.height;
  40043. return !!videoCodec || !!(width && height);
  40044. });
  40045. }
  40046. // only keep levels with supported audio/video codecs
  40047. levels = levels.filter(function (_ref2) {
  40048. var audioCodec = _ref2.audioCodec,
  40049. videoCodec = _ref2.videoCodec;
  40050. return (!audioCodec || (0,_utils_codecs__WEBPACK_IMPORTED_MODULE_3__.isCodecSupportedInMp4)(audioCodec, 'audio')) && (!videoCodec || (0,_utils_codecs__WEBPACK_IMPORTED_MODULE_3__.isCodecSupportedInMp4)(videoCodec, 'video'));
  40051. });
  40052. if (data.audioTracks) {
  40053. audioTracks = data.audioTracks.filter(function (track) {
  40054. return !track.audioCodec || (0,_utils_codecs__WEBPACK_IMPORTED_MODULE_3__.isCodecSupportedInMp4)(track.audioCodec, 'audio');
  40055. });
  40056. // Assign ids after filtering as array indices by group-id
  40057. (0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.assignTrackIdsByGroup)(audioTracks);
  40058. }
  40059. if (data.subtitles) {
  40060. subtitleTracks = data.subtitles;
  40061. (0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.assignTrackIdsByGroup)(subtitleTracks);
  40062. }
  40063. if (levels.length > 0) {
  40064. // start bitrate is the first bitrate of the manifest
  40065. bitrateStart = levels[0].bitrate;
  40066. // sort levels from lowest to highest
  40067. levels.sort(function (a, b) {
  40068. if (a.attrs['HDCP-LEVEL'] !== b.attrs['HDCP-LEVEL']) {
  40069. return (a.attrs['HDCP-LEVEL'] || '') > (b.attrs['HDCP-LEVEL'] || '') ? 1 : -1;
  40070. }
  40071. if (a.bitrate !== b.bitrate) {
  40072. return a.bitrate - b.bitrate;
  40073. }
  40074. if (a.attrs.SCORE !== b.attrs.SCORE) {
  40075. return a.attrs.decimalFloatingPoint('SCORE') - b.attrs.decimalFloatingPoint('SCORE');
  40076. }
  40077. if (resolutionFound && a.height !== b.height) {
  40078. return a.height - b.height;
  40079. }
  40080. return 0;
  40081. });
  40082. this._levels = levels;
  40083. // find index of first level in sorted levels
  40084. for (var i = 0; i < levels.length; i++) {
  40085. if (levels[i].bitrate === bitrateStart) {
  40086. this._firstLevel = i;
  40087. this.log("manifest loaded, " + levels.length + " level(s) found, first bitrate: " + bitrateStart);
  40088. break;
  40089. }
  40090. }
  40091. // Audio is only alternate if manifest include a URI along with the audio group tag,
  40092. // and this is not an audio-only stream where levels contain audio-only
  40093. var audioOnly = audioCodecFound && !videoCodecFound;
  40094. var edata = {
  40095. levels: levels,
  40096. audioTracks: audioTracks,
  40097. subtitleTracks: subtitleTracks,
  40098. sessionData: data.sessionData,
  40099. sessionKeys: data.sessionKeys,
  40100. firstLevel: this._firstLevel,
  40101. stats: data.stats,
  40102. audio: audioCodecFound,
  40103. video: videoCodecFound,
  40104. altAudio: !audioOnly && audioTracks.some(function (t) {
  40105. return !!t.url;
  40106. })
  40107. };
  40108. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_PARSED, edata);
  40109. // Initiate loading after all controllers have received MANIFEST_PARSED
  40110. if (this.hls.config.autoStartLoad || this.hls.forceStartLoad) {
  40111. this.hls.startLoad(this.hls.config.startPosition);
  40112. }
  40113. } else {
  40114. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  40115. type: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.MEDIA_ERROR,
  40116. details: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_INCOMPATIBLE_CODECS_ERROR,
  40117. fatal: true,
  40118. url: data.url,
  40119. reason: 'no level with compatible codecs found in manifest'
  40120. });
  40121. }
  40122. };
  40123. _proto.onError = function onError(event, data) {
  40124. var _data$frag, _data$level;
  40125. _BasePlaylistControll.prototype.onError.call(this, event, data);
  40126. if (data.fatal) {
  40127. return;
  40128. }
  40129. // Switch to redundant level when track fails to load
  40130. var context = data.context;
  40131. var level = this._levels[this.currentLevelIndex];
  40132. if (context && (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistContextType.AUDIO_TRACK && level.audioGroupIds && context.groupId === level.audioGroupIds[level.urlId] || context.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistContextType.SUBTITLE_TRACK && level.textGroupIds && context.groupId === level.textGroupIds[level.urlId])) {
  40133. this.redundantFailover(this.currentLevelIndex);
  40134. return;
  40135. }
  40136. var levelError = false;
  40137. var levelSwitch = true;
  40138. var levelIndex;
  40139. // try to recover not fatal errors
  40140. switch (data.details) {
  40141. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.FRAG_LOAD_ERROR:
  40142. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.FRAG_LOAD_TIMEOUT:
  40143. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_LOAD_ERROR:
  40144. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_LOAD_TIMEOUT:
  40145. if (data.frag) {
  40146. // Share fragment error count accross media options (main, audio, subs)
  40147. // This allows for level based rendition switching when media option assets fail
  40148. var variantLevelIndex = data.frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN ? data.frag.level : this.currentLevelIndex;
  40149. var _level = this._levels[variantLevelIndex];
  40150. // Set levelIndex when we're out of fragment retries
  40151. if (_level) {
  40152. _level.fragmentError++;
  40153. if (_level.fragmentError > this.hls.config.fragLoadingMaxRetry) {
  40154. levelIndex = variantLevelIndex;
  40155. }
  40156. } else {
  40157. levelIndex = variantLevelIndex;
  40158. }
  40159. }
  40160. break;
  40161. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED:
  40162. {
  40163. var restrictedHdcpLevel = level.attrs['HDCP-LEVEL'];
  40164. if (restrictedHdcpLevel) {
  40165. this.hls.maxHdcpLevel = _types_level__WEBPACK_IMPORTED_MODULE_0__.HdcpLevels[_types_level__WEBPACK_IMPORTED_MODULE_0__.HdcpLevels.indexOf(restrictedHdcpLevel) - 1];
  40166. this.warn("Restricting playback to HDCP-LEVEL of \"" + this.hls.maxHdcpLevel + "\" or lower");
  40167. }
  40168. }
  40169. // eslint-disable-next-line no-fallthrough
  40170. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.FRAG_PARSING_ERROR:
  40171. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.KEY_SYSTEM_NO_SESSION:
  40172. levelIndex = ((_data$frag = data.frag) === null || _data$frag === void 0 ? void 0 : _data$frag.type) === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN ? data.frag.level : this.currentLevelIndex;
  40173. // Do not retry level. Escalate to fatal if switching levels fails.
  40174. data.levelRetry = false;
  40175. break;
  40176. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_ERROR:
  40177. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_TIMEOUT:
  40178. // Do not perform level switch if an error occurred using delivery directives
  40179. // Attempt to reload level without directives first
  40180. if (context) {
  40181. if (context.deliveryDirectives) {
  40182. levelSwitch = false;
  40183. }
  40184. levelIndex = context.level;
  40185. }
  40186. levelError = true;
  40187. break;
  40188. case _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.REMUX_ALLOC_ERROR:
  40189. levelIndex = (_data$level = data.level) != null ? _data$level : this.currentLevelIndex;
  40190. levelError = true;
  40191. break;
  40192. }
  40193. if (levelIndex !== undefined) {
  40194. this.recoverLevel(data, levelIndex, levelError, levelSwitch);
  40195. }
  40196. }
  40197. /**
  40198. * Switch to a redundant stream if any available.
  40199. * If redundant stream is not available, emergency switch down if ABR mode is enabled.
  40200. */;
  40201. _proto.recoverLevel = function recoverLevel(errorEvent, levelIndex, levelError, levelSwitch) {
  40202. var errorDetails = errorEvent.details;
  40203. var level = this._levels[levelIndex];
  40204. level.loadError++;
  40205. if (levelError) {
  40206. var retrying = this.retryLoadingOrFail(errorEvent);
  40207. if (retrying) {
  40208. // boolean used to inform stream controller not to switch back to IDLE on non fatal error
  40209. errorEvent.levelRetry = true;
  40210. } else {
  40211. this.currentLevelIndex = -1;
  40212. return;
  40213. }
  40214. }
  40215. if (levelSwitch) {
  40216. var redundantLevels = level.url.length;
  40217. // Try redundant fail-over until level.loadError reaches redundantLevels
  40218. if (redundantLevels > 1 && level.loadError < redundantLevels) {
  40219. errorEvent.levelRetry = true;
  40220. this.redundantFailover(levelIndex);
  40221. } else if (this.manualLevelIndex === -1) {
  40222. // Search for next level to retry
  40223. var nextLevel = -1;
  40224. var levels = this._levels;
  40225. for (var i = levels.length; i--;) {
  40226. var candidate = (i + this.currentLevelIndex) % levels.length;
  40227. if (candidate !== this.currentLevelIndex && levels[candidate].loadError === 0) {
  40228. nextLevel = candidate;
  40229. break;
  40230. }
  40231. }
  40232. if (nextLevel > -1 && this.currentLevelIndex !== nextLevel) {
  40233. this.warn(errorDetails + ": switch to " + nextLevel);
  40234. errorEvent.levelRetry = true;
  40235. this.hls.nextAutoLevel = nextLevel;
  40236. } else if (errorEvent.levelRetry === false) {
  40237. // No levels to switch to and no more retries
  40238. errorEvent.fatal = true;
  40239. }
  40240. }
  40241. }
  40242. };
  40243. _proto.redundantFailover = function redundantFailover(levelIndex) {
  40244. var level = this._levels[levelIndex];
  40245. var redundantLevels = level.url.length;
  40246. if (redundantLevels > 1) {
  40247. // Update the url id of all levels so that we stay on the same set of variants when level switching
  40248. var newUrlId = (level.urlId + 1) % redundantLevels;
  40249. this.warn("Switching to redundant URL-id " + newUrlId);
  40250. this._levels.forEach(function (level) {
  40251. level.urlId = newUrlId;
  40252. });
  40253. this.level = levelIndex;
  40254. }
  40255. }
  40256. // reset errors on the successful load of a fragment
  40257. ;
  40258. _proto.onFragLoaded = function onFragLoaded(event, _ref3) {
  40259. var frag = _ref3.frag;
  40260. if (frag !== undefined && frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN) {
  40261. var level = this._levels[frag.level];
  40262. if (level !== undefined) {
  40263. level.fragmentError = 0;
  40264. level.loadError = 0;
  40265. }
  40266. }
  40267. };
  40268. _proto.onLevelLoaded = function onLevelLoaded(event, data) {
  40269. var _data$deliveryDirecti2;
  40270. var level = data.level,
  40271. details = data.details;
  40272. var curLevel = this._levels[level];
  40273. if (!curLevel) {
  40274. var _data$deliveryDirecti;
  40275. this.warn("Invalid level index " + level);
  40276. if ((_data$deliveryDirecti = data.deliveryDirectives) !== null && _data$deliveryDirecti !== void 0 && _data$deliveryDirecti.skip) {
  40277. details.deltaUpdateFailed = true;
  40278. }
  40279. return;
  40280. }
  40281. // only process level loaded events matching with expected level
  40282. if (level === this.currentLevelIndex) {
  40283. // reset level load error counter on successful level loaded only if there is no issues with fragments
  40284. if (curLevel.fragmentError === 0) {
  40285. curLevel.loadError = 0;
  40286. this.retryCount = 0;
  40287. }
  40288. this.playlistLoaded(level, data, curLevel.details);
  40289. } else if ((_data$deliveryDirecti2 = data.deliveryDirectives) !== null && _data$deliveryDirecti2 !== void 0 && _data$deliveryDirecti2.skip) {
  40290. // received a delta playlist update that cannot be merged
  40291. details.deltaUpdateFailed = true;
  40292. }
  40293. };
  40294. _proto.onAudioTrackSwitched = function onAudioTrackSwitched(event, data) {
  40295. var currentLevel = this.hls.levels[this.currentLevelIndex];
  40296. if (!currentLevel) {
  40297. return;
  40298. }
  40299. if (currentLevel.audioGroupIds) {
  40300. var urlId = -1;
  40301. var audioGroupId = this.hls.audioTracks[data.id].groupId;
  40302. for (var i = 0; i < currentLevel.audioGroupIds.length; i++) {
  40303. if (currentLevel.audioGroupIds[i] === audioGroupId) {
  40304. urlId = i;
  40305. break;
  40306. }
  40307. }
  40308. if (urlId !== currentLevel.urlId) {
  40309. currentLevel.urlId = urlId;
  40310. this.startLoad();
  40311. }
  40312. }
  40313. };
  40314. _proto.loadPlaylist = function loadPlaylist(hlsUrlParameters) {
  40315. _BasePlaylistControll.prototype.loadPlaylist.call(this);
  40316. var level = this.currentLevelIndex;
  40317. var currentLevel = this._levels[level];
  40318. if (this.canLoad && currentLevel && currentLevel.url.length > 0) {
  40319. var id = currentLevel.urlId;
  40320. var url = currentLevel.url[id];
  40321. if (hlsUrlParameters) {
  40322. try {
  40323. url = hlsUrlParameters.addDirectives(url);
  40324. } catch (error) {
  40325. this.warn("Could not construct new URL with HLS Delivery Directives: " + error);
  40326. }
  40327. }
  40328. this.log("Attempt loading level index " + level + ((hlsUrlParameters === null || hlsUrlParameters === void 0 ? void 0 : hlsUrlParameters.msn) !== undefined ? ' at sn ' + hlsUrlParameters.msn + ' part ' + hlsUrlParameters.part : '') + " with URL-id " + id + " " + url);
  40329. // console.log('Current audio track group ID:', this.hls.audioTracks[this.hls.audioTrack].groupId);
  40330. // console.log('New video quality level audio group id:', levelObject.attrs.AUDIO, level);
  40331. this.clearTimer();
  40332. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADING, {
  40333. url: url,
  40334. level: level,
  40335. id: id,
  40336. deliveryDirectives: hlsUrlParameters || null
  40337. });
  40338. }
  40339. };
  40340. _proto.removeLevel = function removeLevel(levelIndex, urlId) {
  40341. var filterLevelAndGroupByIdIndex = function filterLevelAndGroupByIdIndex(url, id) {
  40342. return id !== urlId;
  40343. };
  40344. var levels = this._levels.filter(function (level, index) {
  40345. if (index !== levelIndex) {
  40346. return true;
  40347. }
  40348. if (level.url.length > 1 && urlId !== undefined) {
  40349. level.url = level.url.filter(filterLevelAndGroupByIdIndex);
  40350. if (level.audioGroupIds) {
  40351. level.audioGroupIds = level.audioGroupIds.filter(filterLevelAndGroupByIdIndex);
  40352. }
  40353. if (level.textGroupIds) {
  40354. level.textGroupIds = level.textGroupIds.filter(filterLevelAndGroupByIdIndex);
  40355. }
  40356. level.urlId = 0;
  40357. return true;
  40358. }
  40359. return false;
  40360. }).map(function (level, index) {
  40361. var details = level.details;
  40362. if (details !== null && details !== void 0 && details.fragments) {
  40363. details.fragments.forEach(function (fragment) {
  40364. fragment.level = index;
  40365. });
  40366. }
  40367. return level;
  40368. });
  40369. this._levels = levels;
  40370. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVELS_UPDATED, {
  40371. levels: levels
  40372. });
  40373. };
  40374. _createClass(LevelController, [{
  40375. key: "levels",
  40376. get: function get() {
  40377. if (this._levels.length === 0) {
  40378. return null;
  40379. }
  40380. return this._levels;
  40381. }
  40382. }, {
  40383. key: "level",
  40384. get: function get() {
  40385. return this.currentLevelIndex;
  40386. },
  40387. set: function set(newLevel) {
  40388. var _levels$newLevel;
  40389. var levels = this._levels;
  40390. if (levels.length === 0) {
  40391. return;
  40392. }
  40393. if (this.currentLevelIndex === newLevel && (_levels$newLevel = levels[newLevel]) !== null && _levels$newLevel !== void 0 && _levels$newLevel.details) {
  40394. return;
  40395. }
  40396. // check if level idx is valid
  40397. if (newLevel < 0 || newLevel >= levels.length) {
  40398. // invalid level id given, trigger error
  40399. var fatal = newLevel < 0;
  40400. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  40401. type: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.OTHER_ERROR,
  40402. details: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_SWITCH_ERROR,
  40403. level: newLevel,
  40404. fatal: fatal,
  40405. reason: 'invalid level idx'
  40406. });
  40407. if (fatal) {
  40408. return;
  40409. }
  40410. newLevel = Math.min(newLevel, levels.length - 1);
  40411. }
  40412. // stopping live reloading timer if any
  40413. this.clearTimer();
  40414. var lastLevelIndex = this.currentLevelIndex;
  40415. var lastLevel = levels[lastLevelIndex];
  40416. var level = levels[newLevel];
  40417. this.log("switching to level " + newLevel + " from " + lastLevelIndex);
  40418. this.currentLevelIndex = newLevel;
  40419. var levelSwitchingData = _extends({}, level, {
  40420. level: newLevel,
  40421. maxBitrate: level.maxBitrate,
  40422. uri: level.uri,
  40423. urlId: level.urlId
  40424. });
  40425. // @ts-ignore
  40426. delete levelSwitchingData._urlId;
  40427. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_SWITCHING, levelSwitchingData);
  40428. // check if we need to load playlist for this level
  40429. var levelDetails = level.details;
  40430. if (!levelDetails || levelDetails.live) {
  40431. // level not retrieved yet, or live playlist we need to (re)load it
  40432. var hlsUrlParameters = this.switchParams(level.uri, lastLevel === null || lastLevel === void 0 ? void 0 : lastLevel.details);
  40433. this.loadPlaylist(hlsUrlParameters);
  40434. }
  40435. }
  40436. }, {
  40437. key: "manualLevel",
  40438. get: function get() {
  40439. return this.manualLevelIndex;
  40440. },
  40441. set: function set(newLevel) {
  40442. this.manualLevelIndex = newLevel;
  40443. if (this._startLevel === undefined) {
  40444. this._startLevel = newLevel;
  40445. }
  40446. if (newLevel !== -1) {
  40447. this.level = newLevel;
  40448. }
  40449. }
  40450. }, {
  40451. key: "firstLevel",
  40452. get: function get() {
  40453. return this._firstLevel;
  40454. },
  40455. set: function set(newLevel) {
  40456. this._firstLevel = newLevel;
  40457. }
  40458. }, {
  40459. key: "startLevel",
  40460. get: function get() {
  40461. // hls.startLevel takes precedence over config.startLevel
  40462. // if none of these values are defined, fallback on this._firstLevel (first quality level appearing in variant manifest)
  40463. if (this._startLevel === undefined) {
  40464. var configStartLevel = this.hls.config.startLevel;
  40465. if (configStartLevel !== undefined) {
  40466. return configStartLevel;
  40467. } else {
  40468. return this._firstLevel;
  40469. }
  40470. } else {
  40471. return this._startLevel;
  40472. }
  40473. },
  40474. set: function set(newLevel) {
  40475. this._startLevel = newLevel;
  40476. }
  40477. }, {
  40478. key: "nextLoadLevel",
  40479. get: function get() {
  40480. if (this.manualLevelIndex !== -1) {
  40481. return this.manualLevelIndex;
  40482. } else {
  40483. return this.hls.nextAutoLevel;
  40484. }
  40485. },
  40486. set: function set(nextLevel) {
  40487. this.level = nextLevel;
  40488. if (this.manualLevelIndex === -1) {
  40489. this.hls.nextAutoLevel = nextLevel;
  40490. }
  40491. }
  40492. }]);
  40493. return LevelController;
  40494. }(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_5__["default"]);
  40495. /***/ }),
  40496. /***/ "./src/controller/level-helper.ts":
  40497. /*!****************************************!*\
  40498. !*** ./src/controller/level-helper.ts ***!
  40499. \****************************************/
  40500. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  40501. "use strict";
  40502. __webpack_require__.r(__webpack_exports__);
  40503. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  40504. /* harmony export */ "addGroupId": () => (/* binding */ addGroupId),
  40505. /* harmony export */ "addSliding": () => (/* binding */ addSliding),
  40506. /* harmony export */ "adjustSliding": () => (/* binding */ adjustSliding),
  40507. /* harmony export */ "assignTrackIdsByGroup": () => (/* binding */ assignTrackIdsByGroup),
  40508. /* harmony export */ "computeReloadInterval": () => (/* binding */ computeReloadInterval),
  40509. /* harmony export */ "getFragmentWithSN": () => (/* binding */ getFragmentWithSN),
  40510. /* harmony export */ "getPartWith": () => (/* binding */ getPartWith),
  40511. /* harmony export */ "mapFragmentIntersection": () => (/* binding */ mapFragmentIntersection),
  40512. /* harmony export */ "mapPartIntersection": () => (/* binding */ mapPartIntersection),
  40513. /* harmony export */ "mergeDetails": () => (/* binding */ mergeDetails),
  40514. /* harmony export */ "updateFragPTSDTS": () => (/* binding */ updateFragPTSDTS),
  40515. /* harmony export */ "updatePTS": () => (/* binding */ updatePTS)
  40516. /* harmony export */ });
  40517. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  40518. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  40519. /* harmony import */ var _loader_date_range__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../loader/date-range */ "./src/loader/date-range.ts");
  40520. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  40521. /**
  40522. * @module LevelHelper
  40523. * Providing methods dealing with playlist sliding and drift
  40524. * */
  40525. function addGroupId(level, type, id) {
  40526. switch (type) {
  40527. case 'audio':
  40528. if (!level.audioGroupIds) {
  40529. level.audioGroupIds = [];
  40530. }
  40531. level.audioGroupIds.push(id);
  40532. break;
  40533. case 'text':
  40534. if (!level.textGroupIds) {
  40535. level.textGroupIds = [];
  40536. }
  40537. level.textGroupIds.push(id);
  40538. break;
  40539. }
  40540. }
  40541. function assignTrackIdsByGroup(tracks) {
  40542. var groups = {};
  40543. tracks.forEach(function (track) {
  40544. var groupId = track.groupId || '';
  40545. track.id = groups[groupId] = groups[groupId] || 0;
  40546. groups[groupId]++;
  40547. });
  40548. }
  40549. function updatePTS(fragments, fromIdx, toIdx) {
  40550. var fragFrom = fragments[fromIdx];
  40551. var fragTo = fragments[toIdx];
  40552. updateFromToPTS(fragFrom, fragTo);
  40553. }
  40554. function updateFromToPTS(fragFrom, fragTo) {
  40555. var fragToPTS = fragTo.startPTS;
  40556. // if we know startPTS[toIdx]
  40557. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(fragToPTS)) {
  40558. // update fragment duration.
  40559. // it helps to fix drifts between playlist reported duration and fragment real duration
  40560. var duration = 0;
  40561. var frag;
  40562. if (fragTo.sn > fragFrom.sn) {
  40563. duration = fragToPTS - fragFrom.start;
  40564. frag = fragFrom;
  40565. } else {
  40566. duration = fragFrom.start - fragToPTS;
  40567. frag = fragTo;
  40568. }
  40569. // TODO? Drift can go either way, or the playlist could be completely accurate
  40570. // console.assert(duration > 0,
  40571. // `duration of ${duration} computed for frag ${frag.sn}, level ${frag.level}, there should be some duration drift between playlist and fragment!`);
  40572. if (frag.duration !== duration) {
  40573. frag.duration = duration;
  40574. }
  40575. // we dont know startPTS[toIdx]
  40576. } else if (fragTo.sn > fragFrom.sn) {
  40577. var contiguous = fragFrom.cc === fragTo.cc;
  40578. // TODO: With part-loading end/durations we need to confirm the whole fragment is loaded before using (or setting) minEndPTS
  40579. if (contiguous && fragFrom.minEndPTS) {
  40580. fragTo.start = fragFrom.start + (fragFrom.minEndPTS - fragFrom.start);
  40581. } else {
  40582. fragTo.start = fragFrom.start + fragFrom.duration;
  40583. }
  40584. } else {
  40585. fragTo.start = Math.max(fragFrom.start - fragTo.duration, 0);
  40586. }
  40587. }
  40588. function updateFragPTSDTS(details, frag, startPTS, endPTS, startDTS, endDTS) {
  40589. var parsedMediaDuration = endPTS - startPTS;
  40590. if (parsedMediaDuration <= 0) {
  40591. _utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('Fragment should have a positive duration', frag);
  40592. endPTS = startPTS + frag.duration;
  40593. endDTS = startDTS + frag.duration;
  40594. }
  40595. var maxStartPTS = startPTS;
  40596. var minEndPTS = endPTS;
  40597. var fragStartPts = frag.startPTS;
  40598. var fragEndPts = frag.endPTS;
  40599. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(fragStartPts)) {
  40600. // delta PTS between audio and video
  40601. var deltaPTS = Math.abs(fragStartPts - startPTS);
  40602. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.deltaPTS)) {
  40603. frag.deltaPTS = deltaPTS;
  40604. } else {
  40605. frag.deltaPTS = Math.max(deltaPTS, frag.deltaPTS);
  40606. }
  40607. maxStartPTS = Math.max(startPTS, fragStartPts);
  40608. startPTS = Math.min(startPTS, fragStartPts);
  40609. startDTS = Math.min(startDTS, frag.startDTS);
  40610. minEndPTS = Math.min(endPTS, fragEndPts);
  40611. endPTS = Math.max(endPTS, fragEndPts);
  40612. endDTS = Math.max(endDTS, frag.endDTS);
  40613. }
  40614. frag.duration = endPTS - startPTS;
  40615. var drift = startPTS - frag.start;
  40616. frag.start = frag.startPTS = startPTS;
  40617. frag.maxStartPTS = maxStartPTS;
  40618. frag.startDTS = startDTS;
  40619. frag.endPTS = endPTS;
  40620. frag.minEndPTS = minEndPTS;
  40621. frag.endDTS = endDTS;
  40622. var sn = frag.sn; // 'initSegment'
  40623. // exit if sn out of range
  40624. if (!details || sn < details.startSN || sn > details.endSN) {
  40625. return 0;
  40626. }
  40627. var i;
  40628. var fragIdx = sn - details.startSN;
  40629. var fragments = details.fragments;
  40630. // update frag reference in fragments array
  40631. // rationale is that fragments array might not contain this frag object.
  40632. // this will happen if playlist has been refreshed between frag loading and call to updateFragPTSDTS()
  40633. // if we don't update frag, we won't be able to propagate PTS info on the playlist
  40634. // resulting in invalid sliding computation
  40635. fragments[fragIdx] = frag;
  40636. // adjust fragment PTS/duration from seqnum-1 to frag 0
  40637. for (i = fragIdx; i > 0; i--) {
  40638. updateFromToPTS(fragments[i], fragments[i - 1]);
  40639. }
  40640. // adjust fragment PTS/duration from seqnum to last frag
  40641. for (i = fragIdx; i < fragments.length - 1; i++) {
  40642. updateFromToPTS(fragments[i], fragments[i + 1]);
  40643. }
  40644. if (details.fragmentHint) {
  40645. updateFromToPTS(fragments[fragments.length - 1], details.fragmentHint);
  40646. }
  40647. details.PTSKnown = details.alignedSliding = true;
  40648. return drift;
  40649. }
  40650. function mergeDetails(oldDetails, newDetails) {
  40651. // Track the last initSegment processed. Initialize it to the last one on the timeline.
  40652. var currentInitSegment = null;
  40653. var oldFragments = oldDetails.fragments;
  40654. for (var i = oldFragments.length - 1; i >= 0; i--) {
  40655. var oldInit = oldFragments[i].initSegment;
  40656. if (oldInit) {
  40657. currentInitSegment = oldInit;
  40658. break;
  40659. }
  40660. }
  40661. if (oldDetails.fragmentHint) {
  40662. // prevent PTS and duration from being adjusted on the next hint
  40663. delete oldDetails.fragmentHint.endPTS;
  40664. }
  40665. // check if old/new playlists have fragments in common
  40666. // loop through overlapping SN and update startPTS , cc, and duration if any found
  40667. var ccOffset = 0;
  40668. var PTSFrag;
  40669. mapFragmentIntersection(oldDetails, newDetails, function (oldFrag, newFrag) {
  40670. if (oldFrag.relurl) {
  40671. // Do not compare CC if the old fragment has no url. This is a level.fragmentHint used by LL-HLS parts.
  40672. // It maybe be off by 1 if it was created before any parts or discontinuity tags were appended to the end
  40673. // of the playlist.
  40674. ccOffset = oldFrag.cc - newFrag.cc;
  40675. }
  40676. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(oldFrag.startPTS) && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(oldFrag.endPTS)) {
  40677. newFrag.start = newFrag.startPTS = oldFrag.startPTS;
  40678. newFrag.startDTS = oldFrag.startDTS;
  40679. newFrag.appendedPTS = oldFrag.appendedPTS;
  40680. newFrag.maxStartPTS = oldFrag.maxStartPTS;
  40681. newFrag.endPTS = oldFrag.endPTS;
  40682. newFrag.endDTS = oldFrag.endDTS;
  40683. newFrag.minEndPTS = oldFrag.minEndPTS;
  40684. newFrag.duration = oldFrag.endPTS - oldFrag.startPTS;
  40685. if (newFrag.duration) {
  40686. PTSFrag = newFrag;
  40687. }
  40688. // PTS is known when any segment has startPTS and endPTS
  40689. newDetails.PTSKnown = newDetails.alignedSliding = true;
  40690. }
  40691. newFrag.elementaryStreams = oldFrag.elementaryStreams;
  40692. newFrag.loader = oldFrag.loader;
  40693. newFrag.stats = oldFrag.stats;
  40694. newFrag.urlId = oldFrag.urlId;
  40695. if (oldFrag.initSegment) {
  40696. newFrag.initSegment = oldFrag.initSegment;
  40697. currentInitSegment = oldFrag.initSegment;
  40698. }
  40699. });
  40700. if (currentInitSegment) {
  40701. var fragmentsToCheck = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments;
  40702. fragmentsToCheck.forEach(function (frag) {
  40703. var _currentInitSegment;
  40704. if (!frag.initSegment || frag.initSegment.relurl === ((_currentInitSegment = currentInitSegment) === null || _currentInitSegment === void 0 ? void 0 : _currentInitSegment.relurl)) {
  40705. frag.initSegment = currentInitSegment;
  40706. }
  40707. });
  40708. }
  40709. if (newDetails.skippedSegments) {
  40710. newDetails.deltaUpdateFailed = newDetails.fragments.some(function (frag) {
  40711. return !frag;
  40712. });
  40713. if (newDetails.deltaUpdateFailed) {
  40714. _utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('[level-helper] Previous playlist missing segments skipped in delta playlist');
  40715. for (var _i = newDetails.skippedSegments; _i--;) {
  40716. newDetails.fragments.shift();
  40717. }
  40718. newDetails.startSN = newDetails.fragments[0].sn;
  40719. newDetails.startCC = newDetails.fragments[0].cc;
  40720. } else if (newDetails.canSkipDateRanges) {
  40721. newDetails.dateRanges = mergeDateRanges(oldDetails.dateRanges, newDetails.dateRanges, newDetails.recentlyRemovedDateranges);
  40722. }
  40723. }
  40724. var newFragments = newDetails.fragments;
  40725. if (ccOffset) {
  40726. _utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn('discontinuity sliding from playlist, take drift into account');
  40727. for (var _i2 = 0; _i2 < newFragments.length; _i2++) {
  40728. newFragments[_i2].cc += ccOffset;
  40729. }
  40730. }
  40731. if (newDetails.skippedSegments) {
  40732. newDetails.startCC = newDetails.fragments[0].cc;
  40733. }
  40734. // Merge parts
  40735. mapPartIntersection(oldDetails.partList, newDetails.partList, function (oldPart, newPart) {
  40736. newPart.elementaryStreams = oldPart.elementaryStreams;
  40737. newPart.stats = oldPart.stats;
  40738. });
  40739. // if at least one fragment contains PTS info, recompute PTS information for all fragments
  40740. if (PTSFrag) {
  40741. updateFragPTSDTS(newDetails, PTSFrag, PTSFrag.startPTS, PTSFrag.endPTS, PTSFrag.startDTS, PTSFrag.endDTS);
  40742. } else {
  40743. // ensure that delta is within oldFragments range
  40744. // also adjust sliding in case delta is 0 (we could have old=[50-60] and new=old=[50-61])
  40745. // in that case we also need to adjust start offset of all fragments
  40746. adjustSliding(oldDetails, newDetails);
  40747. }
  40748. if (newFragments.length) {
  40749. newDetails.totalduration = newDetails.edge - newFragments[0].start;
  40750. }
  40751. newDetails.driftStartTime = oldDetails.driftStartTime;
  40752. newDetails.driftStart = oldDetails.driftStart;
  40753. var advancedDateTime = newDetails.advancedDateTime;
  40754. if (newDetails.advanced && advancedDateTime) {
  40755. var edge = newDetails.edge;
  40756. if (!newDetails.driftStart) {
  40757. newDetails.driftStartTime = advancedDateTime;
  40758. newDetails.driftStart = edge;
  40759. }
  40760. newDetails.driftEndTime = advancedDateTime;
  40761. newDetails.driftEnd = edge;
  40762. } else {
  40763. newDetails.driftEndTime = oldDetails.driftEndTime;
  40764. newDetails.driftEnd = oldDetails.driftEnd;
  40765. newDetails.advancedDateTime = oldDetails.advancedDateTime;
  40766. }
  40767. }
  40768. function mergeDateRanges(oldDateRanges, deltaDateRanges, recentlyRemovedDateranges) {
  40769. var dateRanges = _extends({}, oldDateRanges);
  40770. if (recentlyRemovedDateranges) {
  40771. recentlyRemovedDateranges.forEach(function (id) {
  40772. delete dateRanges[id];
  40773. });
  40774. }
  40775. Object.keys(deltaDateRanges).forEach(function (id) {
  40776. var dateRange = new _loader_date_range__WEBPACK_IMPORTED_MODULE_2__.DateRange(deltaDateRanges[id].attr, dateRanges[id]);
  40777. if (dateRange.isValid) {
  40778. dateRanges[id] = dateRange;
  40779. } else {
  40780. _utils_logger__WEBPACK_IMPORTED_MODULE_1__.logger.warn("Ignoring invalid Playlist Delta Update DATERANGE tag: \"" + JSON.stringify(deltaDateRanges[id].attr) + "\"");
  40781. }
  40782. });
  40783. return dateRanges;
  40784. }
  40785. function mapPartIntersection(oldParts, newParts, intersectionFn) {
  40786. if (oldParts && newParts) {
  40787. var delta = 0;
  40788. for (var i = 0, len = oldParts.length; i <= len; i++) {
  40789. var _oldPart = oldParts[i];
  40790. var _newPart = newParts[i + delta];
  40791. if (_oldPart && _newPart && _oldPart.index === _newPart.index && _oldPart.fragment.sn === _newPart.fragment.sn) {
  40792. intersectionFn(_oldPart, _newPart);
  40793. } else {
  40794. delta--;
  40795. }
  40796. }
  40797. }
  40798. }
  40799. function mapFragmentIntersection(oldDetails, newDetails, intersectionFn) {
  40800. var skippedSegments = newDetails.skippedSegments;
  40801. var start = Math.max(oldDetails.startSN, newDetails.startSN) - newDetails.startSN;
  40802. var end = (oldDetails.fragmentHint ? 1 : 0) + (skippedSegments ? newDetails.endSN : Math.min(oldDetails.endSN, newDetails.endSN)) - newDetails.startSN;
  40803. var delta = newDetails.startSN - oldDetails.startSN;
  40804. var newFrags = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments;
  40805. var oldFrags = oldDetails.fragmentHint ? oldDetails.fragments.concat(oldDetails.fragmentHint) : oldDetails.fragments;
  40806. for (var i = start; i <= end; i++) {
  40807. var _oldFrag = oldFrags[delta + i];
  40808. var _newFrag = newFrags[i];
  40809. if (skippedSegments && !_newFrag && i < skippedSegments) {
  40810. // Fill in skipped segments in delta playlist
  40811. _newFrag = newDetails.fragments[i] = _oldFrag;
  40812. }
  40813. if (_oldFrag && _newFrag) {
  40814. intersectionFn(_oldFrag, _newFrag);
  40815. }
  40816. }
  40817. }
  40818. function adjustSliding(oldDetails, newDetails) {
  40819. var delta = newDetails.startSN + newDetails.skippedSegments - oldDetails.startSN;
  40820. var oldFragments = oldDetails.fragments;
  40821. if (delta < 0 || delta >= oldFragments.length) {
  40822. return;
  40823. }
  40824. addSliding(newDetails, oldFragments[delta].start);
  40825. }
  40826. function addSliding(details, start) {
  40827. if (start) {
  40828. var fragments = details.fragments;
  40829. for (var i = details.skippedSegments; i < fragments.length; i++) {
  40830. fragments[i].start += start;
  40831. }
  40832. if (details.fragmentHint) {
  40833. details.fragmentHint.start += start;
  40834. }
  40835. }
  40836. }
  40837. function computeReloadInterval(newDetails, distanceToLiveEdgeMs) {
  40838. if (distanceToLiveEdgeMs === void 0) {
  40839. distanceToLiveEdgeMs = Infinity;
  40840. }
  40841. var reloadInterval = 1000 * newDetails.targetduration;
  40842. if (newDetails.updated) {
  40843. // Use last segment duration when shorter than target duration and near live edge
  40844. var fragments = newDetails.fragments;
  40845. var liveEdgeMaxTargetDurations = 4;
  40846. if (fragments.length && reloadInterval * liveEdgeMaxTargetDurations > distanceToLiveEdgeMs) {
  40847. var lastSegmentDuration = fragments[fragments.length - 1].duration * 1000;
  40848. if (lastSegmentDuration < reloadInterval) {
  40849. reloadInterval = lastSegmentDuration;
  40850. }
  40851. }
  40852. } else {
  40853. // estimate = 'miss half average';
  40854. // follow HLS Spec, If the client reloads a Playlist file and finds that it has not
  40855. // changed then it MUST wait for a period of one-half the target
  40856. // duration before retrying.
  40857. reloadInterval /= 2;
  40858. }
  40859. return Math.round(reloadInterval);
  40860. }
  40861. function getFragmentWithSN(level, sn, fragCurrent) {
  40862. if (!level || !level.details) {
  40863. return null;
  40864. }
  40865. var levelDetails = level.details;
  40866. var fragment = levelDetails.fragments[sn - levelDetails.startSN];
  40867. if (fragment) {
  40868. return fragment;
  40869. }
  40870. fragment = levelDetails.fragmentHint;
  40871. if (fragment && fragment.sn === sn) {
  40872. return fragment;
  40873. }
  40874. if (sn < levelDetails.startSN && fragCurrent && fragCurrent.sn === sn) {
  40875. return fragCurrent;
  40876. }
  40877. return null;
  40878. }
  40879. function getPartWith(level, sn, partIndex) {
  40880. if (!level || !level.details) {
  40881. return null;
  40882. }
  40883. var partList = level.details.partList;
  40884. if (partList) {
  40885. for (var i = partList.length; i--;) {
  40886. var part = partList[i];
  40887. if (part.index === partIndex && part.fragment.sn === sn) {
  40888. return part;
  40889. }
  40890. }
  40891. }
  40892. return null;
  40893. }
  40894. /***/ }),
  40895. /***/ "./src/controller/stream-controller.ts":
  40896. /*!*********************************************!*\
  40897. !*** ./src/controller/stream-controller.ts ***!
  40898. \*********************************************/
  40899. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  40900. "use strict";
  40901. __webpack_require__.r(__webpack_exports__);
  40902. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  40903. /* harmony export */ "default": () => (/* binding */ StreamController)
  40904. /* harmony export */ });
  40905. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  40906. /* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts");
  40907. /* harmony import */ var _is_supported__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../is-supported */ "./src/is-supported.ts");
  40908. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  40909. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  40910. /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts");
  40911. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  40912. /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts");
  40913. /* harmony import */ var _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../demux/transmuxer-interface */ "./src/demux/transmuxer-interface.ts");
  40914. /* harmony import */ var _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../types/transmuxer */ "./src/types/transmuxer.ts");
  40915. /* harmony import */ var _gap_controller__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./gap-controller */ "./src/controller/gap-controller.ts");
  40916. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  40917. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  40918. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  40919. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  40920. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  40921. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  40922. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  40923. var TICK_INTERVAL = 100; // how often to tick in ms
  40924. var StreamController = /*#__PURE__*/function (_BaseStreamController) {
  40925. _inheritsLoose(StreamController, _BaseStreamController);
  40926. function StreamController(hls, fragmentTracker, keyLoader) {
  40927. var _this;
  40928. _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[stream-controller]') || this;
  40929. _this.audioCodecSwap = false;
  40930. _this.gapController = null;
  40931. _this.level = -1;
  40932. _this._forceStartLoad = false;
  40933. _this.altAudio = false;
  40934. _this.audioOnly = false;
  40935. _this.fragPlaying = null;
  40936. _this.onvplaying = null;
  40937. _this.onvseeked = null;
  40938. _this.fragLastKbps = 0;
  40939. _this.couldBacktrack = false;
  40940. _this.backtrackFragment = null;
  40941. _this.audioCodecSwitch = false;
  40942. _this.videoBuffer = null;
  40943. _this._registerListeners();
  40944. return _this;
  40945. }
  40946. var _proto = StreamController.prototype;
  40947. _proto._registerListeners = function _registerListeners() {
  40948. var hls = this.hls;
  40949. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  40950. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  40951. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  40952. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  40953. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  40954. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  40955. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
  40956. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR, this.onError, this);
  40957. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
  40958. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
  40959. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_CREATED, this.onBufferCreated, this);
  40960. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_FLUSHED, this.onBufferFlushed, this);
  40961. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
  40962. hls.on(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  40963. };
  40964. _proto._unregisterListeners = function _unregisterListeners() {
  40965. var hls = this.hls;
  40966. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  40967. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  40968. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  40969. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  40970. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  40971. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_LOAD_EMERGENCY_ABORTED, this.onFragLoadEmergencyAborted, this);
  40972. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR, this.onError, this);
  40973. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHING, this.onAudioTrackSwitching, this);
  40974. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHED, this.onAudioTrackSwitched, this);
  40975. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_CREATED, this.onBufferCreated, this);
  40976. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_FLUSHED, this.onBufferFlushed, this);
  40977. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVELS_UPDATED, this.onLevelsUpdated, this);
  40978. hls.off(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  40979. };
  40980. _proto.onHandlerDestroying = function onHandlerDestroying() {
  40981. this._unregisterListeners();
  40982. this.onMediaDetaching();
  40983. };
  40984. _proto.startLoad = function startLoad(startPosition) {
  40985. if (this.levels) {
  40986. var lastCurrentTime = this.lastCurrentTime,
  40987. hls = this.hls;
  40988. this.stopLoad();
  40989. this.setInterval(TICK_INTERVAL);
  40990. this.level = -1;
  40991. this.fragLoadError = 0;
  40992. if (!this.startFragRequested) {
  40993. // determine load level
  40994. var startLevel = hls.startLevel;
  40995. if (startLevel === -1) {
  40996. if (hls.config.testBandwidth && this.levels.length > 1) {
  40997. // -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level
  40998. startLevel = 0;
  40999. this.bitrateTest = true;
  41000. } else {
  41001. startLevel = hls.nextAutoLevel;
  41002. }
  41003. }
  41004. // set new level to playlist loader : this will trigger start level load
  41005. // hls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded
  41006. this.level = hls.nextLoadLevel = startLevel;
  41007. this.loadedmetadata = false;
  41008. }
  41009. // if startPosition undefined but lastCurrentTime set, set startPosition to last currentTime
  41010. if (lastCurrentTime > 0 && startPosition === -1) {
  41011. this.log("Override startPosition with lastCurrentTime @" + lastCurrentTime.toFixed(3));
  41012. startPosition = lastCurrentTime;
  41013. }
  41014. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41015. this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition;
  41016. this.tick();
  41017. } else {
  41018. this._forceStartLoad = true;
  41019. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.STOPPED;
  41020. }
  41021. };
  41022. _proto.stopLoad = function stopLoad() {
  41023. this._forceStartLoad = false;
  41024. _BaseStreamController.prototype.stopLoad.call(this);
  41025. };
  41026. _proto.doTick = function doTick() {
  41027. switch (this.state) {
  41028. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE:
  41029. this.doTickIdle();
  41030. break;
  41031. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL:
  41032. {
  41033. var _levels$level;
  41034. var levels = this.levels,
  41035. level = this.level;
  41036. var details = levels === null || levels === void 0 ? void 0 : (_levels$level = levels[level]) === null || _levels$level === void 0 ? void 0 : _levels$level.details;
  41037. if (details && (!details.live || this.levelLastLoaded === this.level)) {
  41038. if (this.waitForCdnTuneIn(details)) {
  41039. break;
  41040. }
  41041. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41042. break;
  41043. }
  41044. break;
  41045. }
  41046. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY:
  41047. {
  41048. var _this$media;
  41049. var now = self.performance.now();
  41050. var retryDate = this.retryDate;
  41051. // if current time is gt than retryDate, or if media seeking let's switch to IDLE state to retry loading
  41052. if (!retryDate || now >= retryDate || (_this$media = this.media) !== null && _this$media !== void 0 && _this$media.seeking) {
  41053. this.log('retryDate reached, switch back to IDLE state');
  41054. this.resetStartWhenNotLoaded(this.level);
  41055. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41056. }
  41057. }
  41058. break;
  41059. default:
  41060. break;
  41061. }
  41062. // check buffer
  41063. // check/update current fragment
  41064. this.onTickEnd();
  41065. };
  41066. _proto.onTickEnd = function onTickEnd() {
  41067. _BaseStreamController.prototype.onTickEnd.call(this);
  41068. this.checkBuffer();
  41069. this.checkFragmentChanged();
  41070. };
  41071. _proto.doTickIdle = function doTickIdle() {
  41072. var hls = this.hls,
  41073. levelLastLoaded = this.levelLastLoaded,
  41074. levels = this.levels,
  41075. media = this.media;
  41076. var config = hls.config,
  41077. level = hls.nextLoadLevel;
  41078. // if start level not parsed yet OR
  41079. // if video not attached AND start fragment already requested OR start frag prefetch not enabled
  41080. // exit loop, as we either need more info (level not parsed) or we need media to be attached to load new fragment
  41081. if (levelLastLoaded === null || !media && (this.startFragRequested || !config.startFragPrefetch)) {
  41082. return;
  41083. }
  41084. // If the "main" level is audio-only but we are loading an alternate track in the same group, do not load anything
  41085. if (this.altAudio && this.audioOnly) {
  41086. return;
  41087. }
  41088. if (!levels || !levels[level]) {
  41089. return;
  41090. }
  41091. var levelInfo = levels[level];
  41092. // if buffer length is less than maxBufLen try to load a new fragment
  41093. var bufferInfo = this.getMainFwdBufferInfo();
  41094. if (bufferInfo === null) {
  41095. return;
  41096. }
  41097. var lastDetails = this.getLevelDetails();
  41098. if (lastDetails && this._streamEnded(bufferInfo, lastDetails)) {
  41099. var data = {};
  41100. if (this.altAudio) {
  41101. data.type = 'video';
  41102. }
  41103. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_EOS, data);
  41104. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ENDED;
  41105. return;
  41106. }
  41107. // set next load level : this will trigger a playlist load if needed
  41108. this.level = hls.nextLoadLevel = level;
  41109. var levelDetails = levelInfo.details;
  41110. // if level info not retrieved yet, switch state and wait for level retrieval
  41111. // if live playlist, ensure that new playlist has been refreshed to avoid loading/try to load
  41112. // a useless and outdated fragment (that might even introduce load error if it is already out of the live playlist)
  41113. if (!levelDetails || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL || levelDetails.live && this.levelLastLoaded !== level) {
  41114. this.level = level;
  41115. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL;
  41116. return;
  41117. }
  41118. var bufferLen = bufferInfo.len;
  41119. // compute max Buffer Length that we could get from this load level, based on level bitrate. don't buffer more than 60 MB and more than 30s
  41120. var maxBufLen = this.getMaxBufferLength(levelInfo.maxBitrate);
  41121. // Stay idle if we are still with buffer margins
  41122. if (bufferLen >= maxBufLen) {
  41123. return;
  41124. }
  41125. if (this.backtrackFragment && this.backtrackFragment.start > bufferInfo.end) {
  41126. this.backtrackFragment = null;
  41127. }
  41128. var targetBufferTime = this.backtrackFragment ? this.backtrackFragment.start : bufferInfo.end;
  41129. var frag = this.getNextFragment(targetBufferTime, levelDetails);
  41130. // Avoid backtracking by loading an earlier segment in streams with segments that do not start with a key frame (flagged by `couldBacktrack`)
  41131. if (this.couldBacktrack && !this.fragPrevious && frag && frag.sn !== 'initSegment' && this.fragmentTracker.getState(frag) !== _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.OK) {
  41132. var _this$backtrackFragme;
  41133. var backtrackSn = ((_this$backtrackFragme = this.backtrackFragment) != null ? _this$backtrackFragme : frag).sn;
  41134. var fragIdx = backtrackSn - levelDetails.startSN;
  41135. var backtrackFrag = levelDetails.fragments[fragIdx - 1];
  41136. if (backtrackFrag && frag.cc === backtrackFrag.cc) {
  41137. frag = backtrackFrag;
  41138. this.fragmentTracker.removeFragment(backtrackFrag);
  41139. }
  41140. } else if (this.backtrackFragment && bufferInfo.len) {
  41141. this.backtrackFragment = null;
  41142. }
  41143. // Avoid loop loading by using nextLoadPosition set for backtracking
  41144. if (frag && this.fragmentTracker.getState(frag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.OK && this.nextLoadPosition > targetBufferTime) {
  41145. // Cleanup the fragment tracker before trying to find the next unbuffered fragment
  41146. var type = this.audioOnly && !this.altAudio ? _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO : _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.VIDEO;
  41147. var mediaBuffer = (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.VIDEO ? this.videoBuffer : this.mediaBuffer) || this.media;
  41148. if (mediaBuffer) {
  41149. this.afterBufferFlushed(mediaBuffer, type, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  41150. }
  41151. frag = this.getNextFragment(this.nextLoadPosition, levelDetails);
  41152. }
  41153. if (!frag) {
  41154. return;
  41155. }
  41156. if (frag.initSegment && !frag.initSegment.data && !this.bitrateTest) {
  41157. frag = frag.initSegment;
  41158. }
  41159. this.loadFragment(frag, levelDetails, targetBufferTime);
  41160. };
  41161. _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) {
  41162. var _this$media2;
  41163. // Check if fragment is not loaded
  41164. var fragState = this.fragmentTracker.getState(frag);
  41165. this.fragCurrent = frag;
  41166. if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.NOT_LOADED) {
  41167. if (frag.sn === 'initSegment') {
  41168. this._loadInitSegment(frag, levelDetails);
  41169. } else if (this.bitrateTest) {
  41170. this.log("Fragment " + frag.sn + " of level " + frag.level + " is being downloaded to test bitrate and will not be buffered");
  41171. this._loadBitrateTestFrag(frag, levelDetails);
  41172. } else {
  41173. this.startFragRequested = true;
  41174. _BaseStreamController.prototype.loadFragment.call(this, frag, levelDetails, targetBufferTime);
  41175. }
  41176. } else if (fragState === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.APPENDING) {
  41177. // Lower the buffer size and try again
  41178. if (this.reduceMaxBufferLength(frag.duration)) {
  41179. this.fragmentTracker.removeFragment(frag);
  41180. }
  41181. } else if (((_this$media2 = this.media) === null || _this$media2 === void 0 ? void 0 : _this$media2.buffered.length) === 0) {
  41182. // Stop gap for bad tracker / buffer flush behavior
  41183. this.fragmentTracker.removeAllFragments();
  41184. }
  41185. };
  41186. _proto.getAppendedFrag = function getAppendedFrag(position) {
  41187. var fragOrPart = this.fragmentTracker.getAppendedFrag(position, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  41188. if (fragOrPart && 'fragment' in fragOrPart) {
  41189. return fragOrPart.fragment;
  41190. }
  41191. return fragOrPart;
  41192. };
  41193. _proto.getBufferedFrag = function getBufferedFrag(position) {
  41194. return this.fragmentTracker.getBufferedFrag(position, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  41195. };
  41196. _proto.followingBufferedFrag = function followingBufferedFrag(frag) {
  41197. if (frag) {
  41198. // try to get range of next fragment (500ms after this range)
  41199. return this.getBufferedFrag(frag.end + 0.5);
  41200. }
  41201. return null;
  41202. }
  41203. /*
  41204. on immediate level switch :
  41205. - pause playback if playing
  41206. - cancel any pending load request
  41207. - and trigger a buffer flush
  41208. */;
  41209. _proto.immediateLevelSwitch = function immediateLevelSwitch() {
  41210. this.abortCurrentFrag();
  41211. this.flushMainBuffer(0, Number.POSITIVE_INFINITY);
  41212. }
  41213. /**
  41214. * try to switch ASAP without breaking video playback:
  41215. * in order to ensure smooth but quick level switching,
  41216. * we need to find the next flushable buffer range
  41217. * we should take into account new segment fetch time
  41218. */;
  41219. _proto.nextLevelSwitch = function nextLevelSwitch() {
  41220. var levels = this.levels,
  41221. media = this.media;
  41222. // ensure that media is defined and that metadata are available (to retrieve currentTime)
  41223. if (media !== null && media !== void 0 && media.readyState) {
  41224. var fetchdelay;
  41225. var fragPlayingCurrent = this.getAppendedFrag(media.currentTime);
  41226. if (fragPlayingCurrent && fragPlayingCurrent.start > 1) {
  41227. // flush buffer preceding current fragment (flush until current fragment start offset)
  41228. // minus 1s to avoid video freezing, that could happen if we flush keyframe of current video ...
  41229. this.flushMainBuffer(0, fragPlayingCurrent.start - 1);
  41230. }
  41231. if (!media.paused && levels) {
  41232. // add a safety delay of 1s
  41233. var nextLevelId = this.hls.nextLoadLevel;
  41234. var nextLevel = levels[nextLevelId];
  41235. var fragLastKbps = this.fragLastKbps;
  41236. if (fragLastKbps && this.fragCurrent) {
  41237. fetchdelay = this.fragCurrent.duration * nextLevel.maxBitrate / (1000 * fragLastKbps) + 1;
  41238. } else {
  41239. fetchdelay = 0;
  41240. }
  41241. } else {
  41242. fetchdelay = 0;
  41243. }
  41244. // this.log('fetchdelay:'+fetchdelay);
  41245. // find buffer range that will be reached once new fragment will be fetched
  41246. var bufferedFrag = this.getBufferedFrag(media.currentTime + fetchdelay);
  41247. if (bufferedFrag) {
  41248. // we can flush buffer range following this one without stalling playback
  41249. var nextBufferedFrag = this.followingBufferedFrag(bufferedFrag);
  41250. if (nextBufferedFrag) {
  41251. // if we are here, we can also cancel any loading/demuxing in progress, as they are useless
  41252. this.abortCurrentFrag();
  41253. // start flush position is in next buffered frag. Leave some padding for non-independent segments and smoother playback.
  41254. var maxStart = nextBufferedFrag.maxStartPTS ? nextBufferedFrag.maxStartPTS : nextBufferedFrag.start;
  41255. var fragDuration = nextBufferedFrag.duration;
  41256. var startPts = Math.max(bufferedFrag.end, maxStart + Math.min(Math.max(fragDuration - this.config.maxFragLookUpTolerance, fragDuration * 0.5), fragDuration * 0.75));
  41257. this.flushMainBuffer(startPts, Number.POSITIVE_INFINITY);
  41258. }
  41259. }
  41260. }
  41261. };
  41262. _proto.abortCurrentFrag = function abortCurrentFrag() {
  41263. var fragCurrent = this.fragCurrent;
  41264. this.fragCurrent = null;
  41265. this.backtrackFragment = null;
  41266. if (fragCurrent) {
  41267. fragCurrent.abortRequests();
  41268. }
  41269. switch (this.state) {
  41270. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.KEY_LOADING:
  41271. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING:
  41272. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY:
  41273. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING:
  41274. case _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED:
  41275. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41276. break;
  41277. }
  41278. this.nextLoadPosition = this.getLoadPosition();
  41279. };
  41280. _proto.flushMainBuffer = function flushMainBuffer(startOffset, endOffset) {
  41281. _BaseStreamController.prototype.flushMainBuffer.call(this, startOffset, endOffset, this.altAudio ? 'video' : null);
  41282. };
  41283. _proto.onMediaAttached = function onMediaAttached(event, data) {
  41284. _BaseStreamController.prototype.onMediaAttached.call(this, event, data);
  41285. var media = data.media;
  41286. this.onvplaying = this.onMediaPlaying.bind(this);
  41287. this.onvseeked = this.onMediaSeeked.bind(this);
  41288. media.addEventListener('playing', this.onvplaying);
  41289. media.addEventListener('seeked', this.onvseeked);
  41290. this.gapController = new _gap_controller__WEBPACK_IMPORTED_MODULE_10__["default"](this.config, media, this.fragmentTracker, this.hls);
  41291. };
  41292. _proto.onMediaDetaching = function onMediaDetaching() {
  41293. var media = this.media;
  41294. if (media && this.onvplaying && this.onvseeked) {
  41295. media.removeEventListener('playing', this.onvplaying);
  41296. media.removeEventListener('seeked', this.onvseeked);
  41297. this.onvplaying = this.onvseeked = null;
  41298. this.videoBuffer = null;
  41299. }
  41300. this.fragPlaying = null;
  41301. if (this.gapController) {
  41302. this.gapController.destroy();
  41303. this.gapController = null;
  41304. }
  41305. _BaseStreamController.prototype.onMediaDetaching.call(this);
  41306. };
  41307. _proto.onMediaPlaying = function onMediaPlaying() {
  41308. // tick to speed up FRAG_CHANGED triggering
  41309. this.tick();
  41310. };
  41311. _proto.onMediaSeeked = function onMediaSeeked() {
  41312. var media = this.media;
  41313. var currentTime = media ? media.currentTime : null;
  41314. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(currentTime)) {
  41315. this.log("Media seeked to " + currentTime.toFixed(3));
  41316. }
  41317. // tick to speed up FRAG_CHANGED triggering
  41318. this.tick();
  41319. };
  41320. _proto.onManifestLoading = function onManifestLoading() {
  41321. // reset buffer on manifest loading
  41322. this.log('Trigger BUFFER_RESET');
  41323. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_RESET, undefined);
  41324. this.fragmentTracker.removeAllFragments();
  41325. this.couldBacktrack = false;
  41326. this.startPosition = this.lastCurrentTime = 0;
  41327. this.fragPlaying = null;
  41328. this.backtrackFragment = null;
  41329. };
  41330. _proto.onManifestParsed = function onManifestParsed(event, data) {
  41331. var aac = false;
  41332. var heaac = false;
  41333. var codec;
  41334. data.levels.forEach(function (level) {
  41335. // detect if we have different kind of audio codecs used amongst playlists
  41336. codec = level.audioCodec;
  41337. if (codec) {
  41338. if (codec.indexOf('mp4a.40.2') !== -1) {
  41339. aac = true;
  41340. }
  41341. if (codec.indexOf('mp4a.40.5') !== -1) {
  41342. heaac = true;
  41343. }
  41344. }
  41345. });
  41346. this.audioCodecSwitch = aac && heaac && !(0,_is_supported__WEBPACK_IMPORTED_MODULE_2__.changeTypeSupported)();
  41347. if (this.audioCodecSwitch) {
  41348. this.log('Both AAC/HE-AAC audio found in levels; declaring level codec as HE-AAC');
  41349. }
  41350. this.levels = data.levels;
  41351. this.startFragRequested = false;
  41352. };
  41353. _proto.onLevelLoading = function onLevelLoading(event, data) {
  41354. var levels = this.levels;
  41355. if (!levels || this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE) {
  41356. return;
  41357. }
  41358. var level = levels[data.level];
  41359. if (!level.details || level.details.live && this.levelLastLoaded !== data.level || this.waitForCdnTuneIn(level.details)) {
  41360. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL;
  41361. }
  41362. };
  41363. _proto.onLevelLoaded = function onLevelLoaded(event, data) {
  41364. var _curLevel$details;
  41365. var levels = this.levels;
  41366. var newLevelId = data.level;
  41367. var newDetails = data.details;
  41368. var duration = newDetails.totalduration;
  41369. if (!levels) {
  41370. this.warn("Levels were reset while loading level " + newLevelId);
  41371. return;
  41372. }
  41373. this.log("Level " + newLevelId + " loaded [" + newDetails.startSN + "," + newDetails.endSN + "], cc [" + newDetails.startCC + ", " + newDetails.endCC + "] duration:" + duration);
  41374. var fragCurrent = this.fragCurrent;
  41375. if (fragCurrent && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.FRAG_LOADING_WAITING_RETRY)) {
  41376. if (fragCurrent.level !== data.level && fragCurrent.loader) {
  41377. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41378. this.backtrackFragment = null;
  41379. fragCurrent.abortRequests();
  41380. }
  41381. }
  41382. var curLevel = levels[newLevelId];
  41383. var sliding = 0;
  41384. if (newDetails.live || (_curLevel$details = curLevel.details) !== null && _curLevel$details !== void 0 && _curLevel$details.live) {
  41385. if (!newDetails.fragments[0]) {
  41386. newDetails.deltaUpdateFailed = true;
  41387. }
  41388. if (newDetails.deltaUpdateFailed) {
  41389. return;
  41390. }
  41391. sliding = this.alignPlaylists(newDetails, curLevel.details);
  41392. }
  41393. // override level info
  41394. curLevel.details = newDetails;
  41395. this.levelLastLoaded = newLevelId;
  41396. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_UPDATED, {
  41397. details: newDetails,
  41398. level: newLevelId
  41399. });
  41400. // only switch back to IDLE state if we were waiting for level to start downloading a new fragment
  41401. if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL) {
  41402. if (this.waitForCdnTuneIn(newDetails)) {
  41403. // Wait for Low-Latency CDN Tune-in
  41404. return;
  41405. }
  41406. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41407. }
  41408. if (!this.startFragRequested) {
  41409. this.setStartPosition(newDetails, sliding);
  41410. } else if (newDetails.live) {
  41411. this.synchronizeToLiveEdge(newDetails);
  41412. }
  41413. // trigger handler right now
  41414. this.tick();
  41415. };
  41416. _proto._handleFragmentLoadProgress = function _handleFragmentLoadProgress(data) {
  41417. var _frag$initSegment;
  41418. var frag = data.frag,
  41419. part = data.part,
  41420. payload = data.payload;
  41421. var levels = this.levels;
  41422. if (!levels) {
  41423. this.warn("Levels were reset while fragment load was in progress. Fragment " + frag.sn + " of level " + frag.level + " will not be buffered");
  41424. return;
  41425. }
  41426. var currentLevel = levels[frag.level];
  41427. var details = currentLevel.details;
  41428. if (!details) {
  41429. this.warn("Dropping fragment " + frag.sn + " of level " + frag.level + " after level details were reset");
  41430. return;
  41431. }
  41432. var videoCodec = currentLevel.videoCodec;
  41433. // time Offset is accurate if level PTS is known, or if playlist is not sliding (not live)
  41434. var accurateTimeOffset = details.PTSKnown || !details.live;
  41435. var initSegmentData = (_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.data;
  41436. var audioCodec = this._getAudioCodec(currentLevel);
  41437. // transmux the MPEG-TS data to ISO-BMFF segments
  41438. // this.log(`Transmuxing ${frag.sn} of [${details.startSN} ,${details.endSN}],level ${frag.level}, cc ${frag.cc}`);
  41439. var transmuxer = this.transmuxer = this.transmuxer || new _demux_transmuxer_interface__WEBPACK_IMPORTED_MODULE_8__["default"](this.hls, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN, this._handleTransmuxComplete.bind(this), this._handleTransmuxerFlush.bind(this));
  41440. var partIndex = part ? part.index : -1;
  41441. var partial = partIndex !== -1;
  41442. var chunkMeta = new _types_transmuxer__WEBPACK_IMPORTED_MODULE_9__.ChunkMetadata(frag.level, frag.sn, frag.stats.chunkCount, payload.byteLength, partIndex, partial);
  41443. var initPTS = this.initPTS[frag.cc];
  41444. transmuxer.push(payload, initSegmentData, audioCodec, videoCodec, frag, part, details.totalduration, accurateTimeOffset, chunkMeta, initPTS);
  41445. };
  41446. _proto.onAudioTrackSwitching = function onAudioTrackSwitching(event, data) {
  41447. // if any URL found on new audio track, it is an alternate audio track
  41448. var fromAltAudio = this.altAudio;
  41449. var altAudio = !!data.url;
  41450. var trackId = data.id;
  41451. // if we switch on main audio, ensure that main fragment scheduling is synced with media.buffered
  41452. // don't do anything if we switch to alt audio: audio stream controller is handling it.
  41453. // we will just have to change buffer scheduling on audioTrackSwitched
  41454. if (!altAudio) {
  41455. if (this.mediaBuffer !== this.media) {
  41456. this.log('Switching on main audio, use media.buffered to schedule main fragment loading');
  41457. this.mediaBuffer = this.media;
  41458. var fragCurrent = this.fragCurrent;
  41459. // we need to refill audio buffer from main: cancel any frag loading to speed up audio switch
  41460. if (fragCurrent) {
  41461. this.log('Switching to main audio track, cancel main fragment load');
  41462. fragCurrent.abortRequests();
  41463. }
  41464. // destroy transmuxer to force init segment generation (following audio switch)
  41465. this.resetTransmuxer();
  41466. // switch to IDLE state to load new fragment
  41467. this.resetLoadingState();
  41468. } else if (this.audioOnly) {
  41469. // Reset audio transmuxer so when switching back to main audio we're not still appending where we left off
  41470. this.resetTransmuxer();
  41471. }
  41472. var hls = this.hls;
  41473. // If switching from alt to main audio, flush all audio and trigger track switched
  41474. if (fromAltAudio) {
  41475. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_FLUSHING, {
  41476. startOffset: 0,
  41477. endOffset: Number.POSITIVE_INFINITY,
  41478. type: 'audio'
  41479. });
  41480. }
  41481. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.AUDIO_TRACK_SWITCHED, {
  41482. id: trackId
  41483. });
  41484. }
  41485. };
  41486. _proto.onAudioTrackSwitched = function onAudioTrackSwitched(event, data) {
  41487. var trackId = data.id;
  41488. var altAudio = !!this.hls.audioTracks[trackId].url;
  41489. if (altAudio) {
  41490. var videoBuffer = this.videoBuffer;
  41491. // if we switched on alternate audio, ensure that main fragment scheduling is synced with video sourcebuffer buffered
  41492. if (videoBuffer && this.mediaBuffer !== videoBuffer) {
  41493. this.log('Switching on alternate audio, use video.buffered to schedule main fragment loading');
  41494. this.mediaBuffer = videoBuffer;
  41495. }
  41496. }
  41497. this.altAudio = altAudio;
  41498. this.tick();
  41499. };
  41500. _proto.onBufferCreated = function onBufferCreated(event, data) {
  41501. var tracks = data.tracks;
  41502. var mediaTrack;
  41503. var name;
  41504. var alternate = false;
  41505. for (var type in tracks) {
  41506. var track = tracks[type];
  41507. if (track.id === 'main') {
  41508. name = type;
  41509. mediaTrack = track;
  41510. // keep video source buffer reference
  41511. if (type === 'video') {
  41512. var videoTrack = tracks[type];
  41513. if (videoTrack) {
  41514. this.videoBuffer = videoTrack.buffer;
  41515. }
  41516. }
  41517. } else {
  41518. alternate = true;
  41519. }
  41520. }
  41521. if (alternate && mediaTrack) {
  41522. this.log("Alternate track found, use " + name + ".buffered to schedule main fragment loading");
  41523. this.mediaBuffer = mediaTrack.buffer;
  41524. } else {
  41525. this.mediaBuffer = this.media;
  41526. }
  41527. };
  41528. _proto.onFragBuffered = function onFragBuffered(event, data) {
  41529. var frag = data.frag,
  41530. part = data.part;
  41531. if (frag && frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN) {
  41532. return;
  41533. }
  41534. if (this.fragContextChanged(frag)) {
  41535. // If a level switch was requested while a fragment was buffering, it will emit the FRAG_BUFFERED event upon completion
  41536. // Avoid setting state back to IDLE, since that will interfere with a level switch
  41537. this.warn("Fragment " + frag.sn + (part ? ' p: ' + part.index : '') + " of level " + frag.level + " finished buffering, but was aborted. state: " + this.state);
  41538. if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED) {
  41539. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41540. }
  41541. return;
  41542. }
  41543. var stats = part ? part.stats : frag.stats;
  41544. this.fragLastKbps = Math.round(8 * stats.total / (stats.buffering.end - stats.loading.first));
  41545. if (frag.sn !== 'initSegment') {
  41546. this.fragPrevious = frag;
  41547. }
  41548. this.fragBufferedComplete(frag, part);
  41549. };
  41550. _proto.onError = function onError(event, data) {
  41551. if (data.type === _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorTypes.KEY_SYSTEM_ERROR) {
  41552. this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN, data);
  41553. return;
  41554. }
  41555. switch (data.details) {
  41556. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.FRAG_LOAD_ERROR:
  41557. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.FRAG_LOAD_TIMEOUT:
  41558. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.FRAG_PARSING_ERROR:
  41559. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.KEY_LOAD_ERROR:
  41560. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.KEY_LOAD_TIMEOUT:
  41561. this.onFragmentOrKeyLoadError(_types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN, data);
  41562. break;
  41563. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.LEVEL_LOAD_ERROR:
  41564. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.LEVEL_LOAD_TIMEOUT:
  41565. if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR) {
  41566. if (data.fatal) {
  41567. // if fatal error, stop processing
  41568. this.warn("" + data.details);
  41569. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.ERROR;
  41570. } else {
  41571. // in case of non fatal error while loading level, if level controller is not retrying to load level , switch back to IDLE
  41572. if (!data.levelRetry && this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.WAITING_LEVEL) {
  41573. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41574. }
  41575. }
  41576. }
  41577. break;
  41578. case _errors__WEBPACK_IMPORTED_MODULE_11__.ErrorDetails.BUFFER_FULL_ERROR:
  41579. // if in appending state
  41580. if (data.parent === 'main' && (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING || this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSED)) {
  41581. var flushBuffer = true;
  41582. var bufferedInfo = this.getFwdBufferInfo(this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  41583. // 0.5 : tolerance needed as some browsers stalls playback before reaching buffered end
  41584. // reduce max buf len if current position is buffered
  41585. if (bufferedInfo && bufferedInfo.len > 0.5) {
  41586. flushBuffer = !this.reduceMaxBufferLength(bufferedInfo.len);
  41587. }
  41588. if (flushBuffer) {
  41589. // current position is not buffered, but browser is still complaining about buffer full error
  41590. // this happens on IE/Edge, refer to https://github.com/video-dev/hls.js/pull/708
  41591. // in that case flush the whole buffer to recover
  41592. this.warn('buffer full error also media.currentTime is not buffered, flush main');
  41593. // flush main buffer
  41594. this.immediateLevelSwitch();
  41595. }
  41596. this.resetLoadingState();
  41597. }
  41598. break;
  41599. default:
  41600. break;
  41601. }
  41602. }
  41603. // Checks the health of the buffer and attempts to resolve playback stalls.
  41604. ;
  41605. _proto.checkBuffer = function checkBuffer() {
  41606. var media = this.media,
  41607. gapController = this.gapController;
  41608. if (!media || !gapController || !media.readyState) {
  41609. // Exit early if we don't have media or if the media hasn't buffered anything yet (readyState 0)
  41610. return;
  41611. }
  41612. if (this.loadedmetadata || !_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(media).length) {
  41613. // Resolve gaps using the main buffer, whose ranges are the intersections of the A/V sourcebuffers
  41614. var activeFrag = this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE ? this.fragCurrent : null;
  41615. gapController.poll(this.lastCurrentTime, activeFrag);
  41616. }
  41617. this.lastCurrentTime = media.currentTime;
  41618. };
  41619. _proto.onFragLoadEmergencyAborted = function onFragLoadEmergencyAborted() {
  41620. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41621. // if loadedmetadata is not set, it means that we are emergency switch down on first frag
  41622. // in that case, reset startFragRequested flag
  41623. if (!this.loadedmetadata) {
  41624. this.startFragRequested = false;
  41625. this.nextLoadPosition = this.startPosition;
  41626. }
  41627. this.tickImmediate();
  41628. };
  41629. _proto.onBufferFlushed = function onBufferFlushed(event, _ref) {
  41630. var type = _ref.type;
  41631. if (type !== _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO || this.audioOnly && !this.altAudio) {
  41632. var mediaBuffer = (type === _loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.VIDEO ? this.videoBuffer : this.mediaBuffer) || this.media;
  41633. this.afterBufferFlushed(mediaBuffer, type, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  41634. }
  41635. };
  41636. _proto.onLevelsUpdated = function onLevelsUpdated(event, data) {
  41637. this.levels = data.levels;
  41638. };
  41639. _proto.swapAudioCodec = function swapAudioCodec() {
  41640. this.audioCodecSwap = !this.audioCodecSwap;
  41641. }
  41642. /**
  41643. * Seeks to the set startPosition if not equal to the mediaElement's current time.
  41644. */;
  41645. _proto.seekToStartPos = function seekToStartPos() {
  41646. var media = this.media;
  41647. if (!media) {
  41648. return;
  41649. }
  41650. var currentTime = media.currentTime;
  41651. var startPosition = this.startPosition;
  41652. // only adjust currentTime if different from startPosition or if startPosition not buffered
  41653. // at that stage, there should be only one buffered range, as we reach that code after first fragment has been buffered
  41654. if (startPosition >= 0 && currentTime < startPosition) {
  41655. if (media.seeking) {
  41656. this.log("could not seek to " + startPosition + ", already seeking at " + currentTime);
  41657. return;
  41658. }
  41659. var buffered = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.getBuffered(media);
  41660. var bufferStart = buffered.length ? buffered.start(0) : 0;
  41661. var delta = bufferStart - startPosition;
  41662. if (delta > 0 && (delta < this.config.maxBufferHole || delta < this.config.maxFragLookUpTolerance)) {
  41663. this.log("adjusting start position by " + delta + " to match buffer start");
  41664. startPosition += delta;
  41665. this.startPosition = startPosition;
  41666. }
  41667. this.log("seek to target start position " + startPosition + " from current time " + currentTime);
  41668. media.currentTime = startPosition;
  41669. }
  41670. };
  41671. _proto._getAudioCodec = function _getAudioCodec(currentLevel) {
  41672. var audioCodec = this.config.defaultAudioCodec || currentLevel.audioCodec;
  41673. if (this.audioCodecSwap && audioCodec) {
  41674. this.log('Swapping audio codec');
  41675. if (audioCodec.indexOf('mp4a.40.5') !== -1) {
  41676. audioCodec = 'mp4a.40.2';
  41677. } else {
  41678. audioCodec = 'mp4a.40.5';
  41679. }
  41680. }
  41681. return audioCodec;
  41682. };
  41683. _proto._loadBitrateTestFrag = function _loadBitrateTestFrag(frag, levelDetails) {
  41684. var _this2 = this;
  41685. frag.bitrateTest = true;
  41686. this._doFragLoad(frag, levelDetails).then(function (data) {
  41687. var hls = _this2.hls;
  41688. if (!data || _this2.fragContextChanged(frag)) {
  41689. return;
  41690. }
  41691. _this2.fragLoadError = 0;
  41692. _this2.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41693. _this2.startFragRequested = false;
  41694. _this2.bitrateTest = false;
  41695. var stats = frag.stats;
  41696. // Bitrate tests fragments are neither parsed nor buffered
  41697. stats.parsing.start = stats.parsing.end = stats.buffering.start = stats.buffering.end = self.performance.now();
  41698. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_LOADED, data);
  41699. frag.bitrateTest = false;
  41700. });
  41701. };
  41702. _proto._handleTransmuxComplete = function _handleTransmuxComplete(transmuxResult) {
  41703. var _id3$samples;
  41704. var id = 'main';
  41705. var hls = this.hls;
  41706. var remuxResult = transmuxResult.remuxResult,
  41707. chunkMeta = transmuxResult.chunkMeta;
  41708. var context = this.getCurrentContext(chunkMeta);
  41709. if (!context) {
  41710. this.warn("The loading context changed while buffering fragment " + chunkMeta.sn + " of level " + chunkMeta.level + ". This chunk will not be buffered.");
  41711. this.resetStartWhenNotLoaded(chunkMeta.level);
  41712. return;
  41713. }
  41714. var frag = context.frag,
  41715. part = context.part,
  41716. level = context.level;
  41717. var video = remuxResult.video,
  41718. text = remuxResult.text,
  41719. id3 = remuxResult.id3,
  41720. initSegment = remuxResult.initSegment;
  41721. var details = level.details;
  41722. // The audio-stream-controller handles audio buffering if Hls.js is playing an alternate audio track
  41723. var audio = this.altAudio ? undefined : remuxResult.audio;
  41724. // Check if the current fragment has been aborted. We check this by first seeing if we're still playing the current level.
  41725. // If we are, subsequently check if the currently loading fragment (fragCurrent) has changed.
  41726. if (this.fragContextChanged(frag)) {
  41727. return;
  41728. }
  41729. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING;
  41730. if (initSegment) {
  41731. if (initSegment.tracks) {
  41732. this._bufferInitSegment(level, initSegment.tracks, frag, chunkMeta);
  41733. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_PARSING_INIT_SEGMENT, {
  41734. frag: frag,
  41735. id: id,
  41736. tracks: initSegment.tracks
  41737. });
  41738. }
  41739. // This would be nice if Number.isFinite acted as a typeguard, but it doesn't. See: https://github.com/Microsoft/TypeScript/issues/10038
  41740. var initPTS = initSegment.initPTS;
  41741. var timescale = initSegment.timescale;
  41742. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(initPTS)) {
  41743. this.initPTS[frag.cc] = initPTS;
  41744. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.INIT_PTS_FOUND, {
  41745. frag: frag,
  41746. id: id,
  41747. initPTS: initPTS,
  41748. timescale: timescale
  41749. });
  41750. }
  41751. }
  41752. // Avoid buffering if backtracking this fragment
  41753. if (video && remuxResult.independent !== false) {
  41754. if (details) {
  41755. var startPTS = video.startPTS,
  41756. endPTS = video.endPTS,
  41757. startDTS = video.startDTS,
  41758. endDTS = video.endDTS;
  41759. if (part) {
  41760. part.elementaryStreams[video.type] = {
  41761. startPTS: startPTS,
  41762. endPTS: endPTS,
  41763. startDTS: startDTS,
  41764. endDTS: endDTS
  41765. };
  41766. } else {
  41767. if (video.firstKeyFrame && video.independent && chunkMeta.id === 1) {
  41768. this.couldBacktrack = true;
  41769. }
  41770. if (video.dropped && video.independent) {
  41771. // Backtrack if dropped frames create a gap after currentTime
  41772. var bufferInfo = this.getMainFwdBufferInfo();
  41773. var targetBufferTime = (bufferInfo ? bufferInfo.end : this.getLoadPosition()) + this.config.maxBufferHole;
  41774. var startTime = video.firstKeyFramePTS ? video.firstKeyFramePTS : startPTS;
  41775. if (targetBufferTime < startTime - this.config.maxBufferHole) {
  41776. this.backtrack(frag);
  41777. return;
  41778. }
  41779. // Set video stream start to fragment start so that truncated samples do not distort the timeline, and mark it partial
  41780. frag.setElementaryStreamInfo(video.type, frag.start, endPTS, frag.start, endDTS, true);
  41781. }
  41782. }
  41783. frag.setElementaryStreamInfo(video.type, startPTS, endPTS, startDTS, endDTS);
  41784. if (this.backtrackFragment) {
  41785. this.backtrackFragment = frag;
  41786. }
  41787. this.bufferFragmentData(video, frag, part, chunkMeta);
  41788. }
  41789. } else if (remuxResult.independent === false) {
  41790. this.backtrack(frag);
  41791. return;
  41792. }
  41793. if (audio) {
  41794. var _startPTS = audio.startPTS,
  41795. _endPTS = audio.endPTS,
  41796. _startDTS = audio.startDTS,
  41797. _endDTS = audio.endDTS;
  41798. if (part) {
  41799. part.elementaryStreams[_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO] = {
  41800. startPTS: _startPTS,
  41801. endPTS: _endPTS,
  41802. startDTS: _startDTS,
  41803. endDTS: _endDTS
  41804. };
  41805. }
  41806. frag.setElementaryStreamInfo(_loader_fragment__WEBPACK_IMPORTED_MODULE_7__.ElementaryStreamTypes.AUDIO, _startPTS, _endPTS, _startDTS, _endDTS);
  41807. this.bufferFragmentData(audio, frag, part, chunkMeta);
  41808. }
  41809. if (details && id3 !== null && id3 !== void 0 && (_id3$samples = id3.samples) !== null && _id3$samples !== void 0 && _id3$samples.length) {
  41810. var emittedID3 = {
  41811. id: id,
  41812. frag: frag,
  41813. details: details,
  41814. samples: id3.samples
  41815. };
  41816. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_PARSING_METADATA, emittedID3);
  41817. }
  41818. if (details && text) {
  41819. var emittedText = {
  41820. id: id,
  41821. frag: frag,
  41822. details: details,
  41823. samples: text.samples
  41824. };
  41825. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_PARSING_USERDATA, emittedText);
  41826. }
  41827. };
  41828. _proto._bufferInitSegment = function _bufferInitSegment(currentLevel, tracks, frag, chunkMeta) {
  41829. var _this3 = this;
  41830. if (this.state !== _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.PARSING) {
  41831. return;
  41832. }
  41833. this.audioOnly = !!tracks.audio && !tracks.video;
  41834. // if audio track is expected to come from audio stream controller, discard any coming from main
  41835. if (this.altAudio && !this.audioOnly) {
  41836. delete tracks.audio;
  41837. }
  41838. // include levelCodec in audio and video tracks
  41839. var audio = tracks.audio,
  41840. video = tracks.video,
  41841. audiovideo = tracks.audiovideo;
  41842. if (audio) {
  41843. var audioCodec = currentLevel.audioCodec;
  41844. var ua = navigator.userAgent.toLowerCase();
  41845. if (this.audioCodecSwitch) {
  41846. if (audioCodec) {
  41847. if (audioCodec.indexOf('mp4a.40.5') !== -1) {
  41848. audioCodec = 'mp4a.40.2';
  41849. } else {
  41850. audioCodec = 'mp4a.40.5';
  41851. }
  41852. }
  41853. // In the case that AAC and HE-AAC audio codecs are signalled in manifest,
  41854. // force HE-AAC, as it seems that most browsers prefers it.
  41855. // don't force HE-AAC if mono stream, or in Firefox
  41856. if (audio.metadata.channelCount !== 1 && ua.indexOf('firefox') === -1) {
  41857. audioCodec = 'mp4a.40.5';
  41858. }
  41859. }
  41860. // HE-AAC is broken on Android, always signal audio codec as AAC even if variant manifest states otherwise
  41861. if (ua.indexOf('android') !== -1 && audio.container !== 'audio/mpeg') {
  41862. // Exclude mpeg audio
  41863. audioCodec = 'mp4a.40.2';
  41864. this.log("Android: force audio codec to " + audioCodec);
  41865. }
  41866. if (currentLevel.audioCodec && currentLevel.audioCodec !== audioCodec) {
  41867. this.log("Swapping manifest audio codec \"" + currentLevel.audioCodec + "\" for \"" + audioCodec + "\"");
  41868. }
  41869. audio.levelCodec = audioCodec;
  41870. audio.id = 'main';
  41871. this.log("Init audio buffer, container:" + audio.container + ", codecs[selected/level/parsed]=[" + (audioCodec || '') + "/" + (currentLevel.audioCodec || '') + "/" + audio.codec + "]");
  41872. }
  41873. if (video) {
  41874. video.levelCodec = currentLevel.videoCodec;
  41875. video.id = 'main';
  41876. this.log("Init video buffer, container:" + video.container + ", codecs[level/parsed]=[" + (currentLevel.videoCodec || '') + "/" + video.codec + "]");
  41877. }
  41878. if (audiovideo) {
  41879. this.log("Init audiovideo buffer, container:" + audiovideo.container + ", codecs[level/parsed]=[" + (currentLevel.attrs.CODECS || '') + "/" + audiovideo.codec + "]");
  41880. }
  41881. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_CODECS, tracks);
  41882. // loop through tracks that are going to be provided to bufferController
  41883. Object.keys(tracks).forEach(function (trackName) {
  41884. var track = tracks[trackName];
  41885. var initSegment = track.initSegment;
  41886. if (initSegment !== null && initSegment !== void 0 && initSegment.byteLength) {
  41887. _this3.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.BUFFER_APPENDING, {
  41888. type: trackName,
  41889. data: initSegment,
  41890. frag: frag,
  41891. part: null,
  41892. chunkMeta: chunkMeta,
  41893. parent: frag.type
  41894. });
  41895. }
  41896. });
  41897. // trigger handler right now
  41898. this.tick();
  41899. };
  41900. _proto.getMainFwdBufferInfo = function getMainFwdBufferInfo() {
  41901. return this.getFwdBufferInfo(this.mediaBuffer ? this.mediaBuffer : this.media, _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.MAIN);
  41902. };
  41903. _proto.backtrack = function backtrack(frag) {
  41904. this.couldBacktrack = true;
  41905. // Causes findFragments to backtrack through fragments to find the keyframe
  41906. this.backtrackFragment = frag;
  41907. this.resetTransmuxer();
  41908. this.flushBufferGap(frag);
  41909. this.fragmentTracker.removeFragment(frag);
  41910. this.fragPrevious = null;
  41911. this.nextLoadPosition = frag.start;
  41912. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_1__.State.IDLE;
  41913. };
  41914. _proto.checkFragmentChanged = function checkFragmentChanged() {
  41915. var video = this.media;
  41916. var fragPlayingCurrent = null;
  41917. if (video && video.readyState > 1 && video.seeking === false) {
  41918. var currentTime = video.currentTime;
  41919. /* if video element is in seeked state, currentTime can only increase.
  41920. (assuming that playback rate is positive ...)
  41921. As sometimes currentTime jumps back to zero after a
  41922. media decode error, check this, to avoid seeking back to
  41923. wrong position after a media decode error
  41924. */
  41925. if (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.isBuffered(video, currentTime)) {
  41926. fragPlayingCurrent = this.getAppendedFrag(currentTime);
  41927. } else if (_utils_buffer_helper__WEBPACK_IMPORTED_MODULE_4__.BufferHelper.isBuffered(video, currentTime + 0.1)) {
  41928. /* ensure that FRAG_CHANGED event is triggered at startup,
  41929. when first video frame is displayed and playback is paused.
  41930. add a tolerance of 100ms, in case current position is not buffered,
  41931. check if current pos+100ms is buffered and use that buffer range
  41932. for FRAG_CHANGED event reporting */
  41933. fragPlayingCurrent = this.getAppendedFrag(currentTime + 0.1);
  41934. }
  41935. if (fragPlayingCurrent) {
  41936. this.backtrackFragment = null;
  41937. var fragPlaying = this.fragPlaying;
  41938. var fragCurrentLevel = fragPlayingCurrent.level;
  41939. if (!fragPlaying || fragPlayingCurrent.sn !== fragPlaying.sn || fragPlaying.level !== fragCurrentLevel || fragPlayingCurrent.urlId !== fragPlaying.urlId) {
  41940. this.fragPlaying = fragPlayingCurrent;
  41941. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.FRAG_CHANGED, {
  41942. frag: fragPlayingCurrent
  41943. });
  41944. if (!fragPlaying || fragPlaying.level !== fragCurrentLevel) {
  41945. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_3__.Events.LEVEL_SWITCHED, {
  41946. level: fragCurrentLevel
  41947. });
  41948. }
  41949. }
  41950. }
  41951. }
  41952. };
  41953. _createClass(StreamController, [{
  41954. key: "nextLevel",
  41955. get: function get() {
  41956. var frag = this.nextBufferedFrag;
  41957. if (frag) {
  41958. return frag.level;
  41959. }
  41960. return -1;
  41961. }
  41962. }, {
  41963. key: "currentFrag",
  41964. get: function get() {
  41965. var media = this.media;
  41966. if (media) {
  41967. return this.fragPlaying || this.getAppendedFrag(media.currentTime);
  41968. }
  41969. return null;
  41970. }
  41971. }, {
  41972. key: "currentProgramDateTime",
  41973. get: function get() {
  41974. var media = this.media;
  41975. if (media) {
  41976. var currentTime = media.currentTime;
  41977. var frag = this.currentFrag;
  41978. if (frag && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(currentTime) && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.programDateTime)) {
  41979. var epocMs = frag.programDateTime + (currentTime - frag.start) * 1000;
  41980. return new Date(epocMs);
  41981. }
  41982. }
  41983. return null;
  41984. }
  41985. }, {
  41986. key: "currentLevel",
  41987. get: function get() {
  41988. var frag = this.currentFrag;
  41989. if (frag) {
  41990. return frag.level;
  41991. }
  41992. return -1;
  41993. }
  41994. }, {
  41995. key: "nextBufferedFrag",
  41996. get: function get() {
  41997. var frag = this.currentFrag;
  41998. if (frag) {
  41999. return this.followingBufferedFrag(frag);
  42000. }
  42001. return null;
  42002. }
  42003. }, {
  42004. key: "forceStartLoad",
  42005. get: function get() {
  42006. return this._forceStartLoad;
  42007. }
  42008. }]);
  42009. return StreamController;
  42010. }(_base_stream_controller__WEBPACK_IMPORTED_MODULE_1__["default"]);
  42011. /***/ }),
  42012. /***/ "./src/controller/subtitle-stream-controller.ts":
  42013. /*!******************************************************!*\
  42014. !*** ./src/controller/subtitle-stream-controller.ts ***!
  42015. \******************************************************/
  42016. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  42017. "use strict";
  42018. __webpack_require__.r(__webpack_exports__);
  42019. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  42020. /* harmony export */ "SubtitleStreamController": () => (/* binding */ SubtitleStreamController)
  42021. /* harmony export */ });
  42022. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  42023. /* harmony import */ var _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/buffer-helper */ "./src/utils/buffer-helper.ts");
  42024. /* harmony import */ var _fragment_finders__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./fragment-finders */ "./src/controller/fragment-finders.ts");
  42025. /* harmony import */ var _utils_discontinuities__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/discontinuities */ "./src/utils/discontinuities.ts");
  42026. /* harmony import */ var _level_helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-helper */ "./src/controller/level-helper.ts");
  42027. /* harmony import */ var _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./fragment-tracker */ "./src/controller/fragment-tracker.ts");
  42028. /* harmony import */ var _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./base-stream-controller */ "./src/controller/base-stream-controller.ts");
  42029. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  42030. /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../types/level */ "./src/types/level.ts");
  42031. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  42032. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  42033. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  42034. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  42035. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  42036. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  42037. var TICK_INTERVAL = 500; // how often to tick in ms
  42038. var SubtitleStreamController = /*#__PURE__*/function (_BaseStreamController) {
  42039. _inheritsLoose(SubtitleStreamController, _BaseStreamController);
  42040. function SubtitleStreamController(hls, fragmentTracker, keyLoader) {
  42041. var _this;
  42042. _this = _BaseStreamController.call(this, hls, fragmentTracker, keyLoader, '[subtitle-stream-controller]') || this;
  42043. _this.levels = [];
  42044. _this.currentTrackId = -1;
  42045. _this.tracksBuffered = [];
  42046. _this.mainDetails = null;
  42047. _this._registerListeners();
  42048. return _this;
  42049. }
  42050. var _proto = SubtitleStreamController.prototype;
  42051. _proto.onHandlerDestroying = function onHandlerDestroying() {
  42052. this._unregisterListeners();
  42053. this.mainDetails = null;
  42054. };
  42055. _proto._registerListeners = function _registerListeners() {
  42056. var hls = this.hls;
  42057. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  42058. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  42059. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  42060. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  42061. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, this.onError, this);
  42062. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
  42063. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
  42064. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
  42065. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this);
  42066. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  42067. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  42068. };
  42069. _proto._unregisterListeners = function _unregisterListeners() {
  42070. var hls = this.hls;
  42071. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  42072. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  42073. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  42074. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADED, this.onLevelLoaded, this);
  42075. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, this.onError, this);
  42076. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
  42077. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH, this.onSubtitleTrackSwitch, this);
  42078. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
  42079. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_FRAG_PROCESSED, this.onSubtitleFragProcessed, this);
  42080. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  42081. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_BUFFERED, this.onFragBuffered, this);
  42082. };
  42083. _proto.startLoad = function startLoad(startPosition) {
  42084. this.stopLoad();
  42085. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;
  42086. this.setInterval(TICK_INTERVAL);
  42087. this.nextLoadPosition = this.startPosition = this.lastCurrentTime = startPosition;
  42088. this.tick();
  42089. };
  42090. _proto.onManifestLoading = function onManifestLoading() {
  42091. this.mainDetails = null;
  42092. this.fragmentTracker.removeAllFragments();
  42093. };
  42094. _proto.onLevelLoaded = function onLevelLoaded(event, data) {
  42095. this.mainDetails = data.details;
  42096. };
  42097. _proto.onSubtitleFragProcessed = function onSubtitleFragProcessed(event, data) {
  42098. var frag = data.frag,
  42099. success = data.success;
  42100. this.fragPrevious = frag;
  42101. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;
  42102. if (!success) {
  42103. return;
  42104. }
  42105. var buffered = this.tracksBuffered[this.currentTrackId];
  42106. if (!buffered) {
  42107. return;
  42108. }
  42109. // Create/update a buffered array matching the interface used by BufferHelper.bufferedInfo
  42110. // so we can re-use the logic used to detect how much has been buffered
  42111. var timeRange;
  42112. var fragStart = frag.start;
  42113. for (var i = 0; i < buffered.length; i++) {
  42114. if (fragStart >= buffered[i].start && fragStart <= buffered[i].end) {
  42115. timeRange = buffered[i];
  42116. break;
  42117. }
  42118. }
  42119. var fragEnd = frag.start + frag.duration;
  42120. if (timeRange) {
  42121. timeRange.end = fragEnd;
  42122. } else {
  42123. timeRange = {
  42124. start: fragStart,
  42125. end: fragEnd
  42126. };
  42127. buffered.push(timeRange);
  42128. }
  42129. this.fragmentTracker.fragBuffered(frag);
  42130. };
  42131. _proto.onBufferFlushing = function onBufferFlushing(event, data) {
  42132. var startOffset = data.startOffset,
  42133. endOffset = data.endOffset;
  42134. if (startOffset === 0 && endOffset !== Number.POSITIVE_INFINITY) {
  42135. var currentTrackId = this.currentTrackId,
  42136. levels = this.levels;
  42137. if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) {
  42138. return;
  42139. }
  42140. var trackDetails = levels[currentTrackId].details;
  42141. var targetDuration = trackDetails.targetduration;
  42142. var endOffsetSubtitles = endOffset - targetDuration;
  42143. if (endOffsetSubtitles <= 0) {
  42144. return;
  42145. }
  42146. data.endOffsetSubtitles = Math.max(0, endOffsetSubtitles);
  42147. this.tracksBuffered.forEach(function (buffered) {
  42148. for (var i = 0; i < buffered.length;) {
  42149. if (buffered[i].end <= endOffsetSubtitles) {
  42150. buffered.shift();
  42151. continue;
  42152. } else if (buffered[i].start < endOffsetSubtitles) {
  42153. buffered[i].start = endOffsetSubtitles;
  42154. } else {
  42155. break;
  42156. }
  42157. i++;
  42158. }
  42159. });
  42160. this.fragmentTracker.removeFragmentsInRange(startOffset, endOffsetSubtitles, _types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.SUBTITLE);
  42161. }
  42162. };
  42163. _proto.onFragBuffered = function onFragBuffered(event, data) {
  42164. if (!this.loadedmetadata && data.frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.MAIN) {
  42165. var _this$media;
  42166. if ((_this$media = this.media) !== null && _this$media !== void 0 && _this$media.buffered.length) {
  42167. this.loadedmetadata = true;
  42168. }
  42169. }
  42170. }
  42171. // If something goes wrong, proceed to next frag, if we were processing one.
  42172. ;
  42173. _proto.onError = function onError(event, data) {
  42174. var frag = data.frag;
  42175. // don't handle error not related to subtitle fragment
  42176. if (!frag || frag.type !== _types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.SUBTITLE) {
  42177. return;
  42178. }
  42179. if (this.fragCurrent) {
  42180. this.fragCurrent.abortRequests();
  42181. }
  42182. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;
  42183. }
  42184. // Got all new subtitle levels.
  42185. ;
  42186. _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(event, _ref) {
  42187. var _this2 = this;
  42188. var subtitleTracks = _ref.subtitleTracks;
  42189. this.tracksBuffered = [];
  42190. this.levels = subtitleTracks.map(function (mediaPlaylist) {
  42191. return new _types_level__WEBPACK_IMPORTED_MODULE_8__.Level(mediaPlaylist);
  42192. });
  42193. this.fragmentTracker.removeAllFragments();
  42194. this.fragPrevious = null;
  42195. this.levels.forEach(function (level) {
  42196. _this2.tracksBuffered[level.id] = [];
  42197. });
  42198. this.mediaBuffer = null;
  42199. };
  42200. _proto.onSubtitleTrackSwitch = function onSubtitleTrackSwitch(event, data) {
  42201. this.currentTrackId = data.id;
  42202. if (!this.levels.length || this.currentTrackId === -1) {
  42203. this.clearInterval();
  42204. return;
  42205. }
  42206. // Check if track has the necessary details to load fragments
  42207. var currentTrack = this.levels[this.currentTrackId];
  42208. if (currentTrack !== null && currentTrack !== void 0 && currentTrack.details) {
  42209. this.mediaBuffer = this.mediaBufferTimeRanges;
  42210. } else {
  42211. this.mediaBuffer = null;
  42212. }
  42213. if (currentTrack) {
  42214. this.setInterval(TICK_INTERVAL);
  42215. }
  42216. }
  42217. // Got a new set of subtitle fragments.
  42218. ;
  42219. _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(event, data) {
  42220. var _track$details;
  42221. var newDetails = data.details,
  42222. trackId = data.id;
  42223. var currentTrackId = this.currentTrackId,
  42224. levels = this.levels;
  42225. if (!levels.length) {
  42226. return;
  42227. }
  42228. var track = levels[currentTrackId];
  42229. if (trackId >= levels.length || trackId !== currentTrackId || !track) {
  42230. return;
  42231. }
  42232. this.mediaBuffer = this.mediaBufferTimeRanges;
  42233. var sliding = 0;
  42234. if (newDetails.live || (_track$details = track.details) !== null && _track$details !== void 0 && _track$details.live) {
  42235. var mainDetails = this.mainDetails;
  42236. if (newDetails.deltaUpdateFailed || !mainDetails) {
  42237. return;
  42238. }
  42239. var mainSlidingStartFragment = mainDetails.fragments[0];
  42240. if (!track.details) {
  42241. if (newDetails.hasProgramDateTime && mainDetails.hasProgramDateTime) {
  42242. (0,_utils_discontinuities__WEBPACK_IMPORTED_MODULE_3__.alignMediaPlaylistByPDT)(newDetails, mainDetails);
  42243. sliding = newDetails.fragments[0].start;
  42244. } else if (mainSlidingStartFragment) {
  42245. // line up live playlist with main so that fragments in range are loaded
  42246. sliding = mainSlidingStartFragment.start;
  42247. (0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addSliding)(newDetails, sliding);
  42248. }
  42249. } else {
  42250. sliding = this.alignPlaylists(newDetails, track.details);
  42251. if (sliding === 0 && mainSlidingStartFragment) {
  42252. // realign with main when there is no overlap with last refresh
  42253. sliding = mainSlidingStartFragment.start;
  42254. (0,_level_helper__WEBPACK_IMPORTED_MODULE_4__.addSliding)(newDetails, sliding);
  42255. }
  42256. }
  42257. }
  42258. track.details = newDetails;
  42259. this.levelLastLoaded = trackId;
  42260. if (!this.startFragRequested && (this.mainDetails || !newDetails.live)) {
  42261. this.setStartPosition(track.details, sliding);
  42262. }
  42263. // trigger handler right now
  42264. this.tick();
  42265. // If playlist is misaligned because of bad PDT or drift, delete details to resync with main on reload
  42266. if (newDetails.live && !this.fragCurrent && this.media && this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE) {
  42267. var foundFrag = (0,_fragment_finders__WEBPACK_IMPORTED_MODULE_2__.findFragmentByPTS)(null, newDetails.fragments, this.media.currentTime, 0);
  42268. if (!foundFrag) {
  42269. this.warn('Subtitle playlist not aligned with playback');
  42270. track.details = undefined;
  42271. }
  42272. }
  42273. };
  42274. _proto._handleFragmentLoadComplete = function _handleFragmentLoadComplete(fragLoadedData) {
  42275. var _this3 = this;
  42276. var frag = fragLoadedData.frag,
  42277. payload = fragLoadedData.payload;
  42278. var decryptData = frag.decryptdata;
  42279. var hls = this.hls;
  42280. if (this.fragContextChanged(frag)) {
  42281. return;
  42282. }
  42283. // check to see if the payload needs to be decrypted
  42284. if (payload && payload.byteLength > 0 && decryptData && decryptData.key && decryptData.iv && decryptData.method === 'AES-128') {
  42285. var startTime = performance.now();
  42286. // decrypt the subtitles
  42287. this.decrypter.decrypt(new Uint8Array(payload), decryptData.key.buffer, decryptData.iv.buffer).then(function (decryptedData) {
  42288. var endTime = performance.now();
  42289. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.FRAG_DECRYPTED, {
  42290. frag: frag,
  42291. payload: decryptedData,
  42292. stats: {
  42293. tstart: startTime,
  42294. tdecrypt: endTime
  42295. }
  42296. });
  42297. }).catch(function (err) {
  42298. _this3.warn(err.name + ": " + err.message);
  42299. _this3.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;
  42300. });
  42301. }
  42302. };
  42303. _proto.doTick = function doTick() {
  42304. if (!this.media) {
  42305. this.state = _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE;
  42306. return;
  42307. }
  42308. if (this.state === _base_stream_controller__WEBPACK_IMPORTED_MODULE_6__.State.IDLE) {
  42309. var currentTrackId = this.currentTrackId,
  42310. levels = this.levels;
  42311. if (!levels.length || !levels[currentTrackId] || !levels[currentTrackId].details) {
  42312. return;
  42313. }
  42314. // Expand range of subs loaded by one target-duration in either direction to make up for misaligned playlists
  42315. var trackDetails = levels[currentTrackId].details;
  42316. var targetDuration = trackDetails.targetduration;
  42317. var config = this.config;
  42318. var currentTime = this.getLoadPosition();
  42319. var bufferedInfo = _utils_buffer_helper__WEBPACK_IMPORTED_MODULE_1__.BufferHelper.bufferedInfo(this.tracksBuffered[this.currentTrackId] || [], currentTime - targetDuration, config.maxBufferHole);
  42320. var targetBufferTime = bufferedInfo.end,
  42321. bufferLen = bufferedInfo.len;
  42322. var mainBufferInfo = this.getFwdBufferInfo(this.media, _types_loader__WEBPACK_IMPORTED_MODULE_7__.PlaylistLevelType.MAIN);
  42323. var maxBufLen = this.getMaxBufferLength(mainBufferInfo === null || mainBufferInfo === void 0 ? void 0 : mainBufferInfo.len) + targetDuration;
  42324. if (bufferLen > maxBufLen) {
  42325. return;
  42326. }
  42327. console.assert(trackDetails, 'Subtitle track details are defined on idle subtitle stream controller tick');
  42328. var fragments = trackDetails.fragments;
  42329. var fragLen = fragments.length;
  42330. var end = trackDetails.edge;
  42331. var foundFrag = null;
  42332. var fragPrevious = this.fragPrevious;
  42333. if (targetBufferTime < end) {
  42334. var maxFragLookUpTolerance = config.maxFragLookUpTolerance;
  42335. foundFrag = (0,_fragment_finders__WEBPACK_IMPORTED_MODULE_2__.findFragmentByPTS)(fragPrevious, fragments, Math.max(fragments[0].start, targetBufferTime), maxFragLookUpTolerance);
  42336. if (!foundFrag && fragPrevious && fragPrevious.start < fragments[0].start) {
  42337. foundFrag = fragments[0];
  42338. }
  42339. } else {
  42340. foundFrag = fragments[fragLen - 1];
  42341. }
  42342. if (!foundFrag) {
  42343. return;
  42344. }
  42345. foundFrag = this.mapToInitFragWhenRequired(foundFrag);
  42346. if (this.fragmentTracker.getState(foundFrag) === _fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentState.NOT_LOADED) {
  42347. // only load if fragment is not loaded
  42348. this.loadFragment(foundFrag, trackDetails, targetBufferTime);
  42349. }
  42350. }
  42351. };
  42352. _proto.getMaxBufferLength = function getMaxBufferLength(mainBufferLength) {
  42353. var maxConfigBuffer = _BaseStreamController.prototype.getMaxBufferLength.call(this);
  42354. if (!mainBufferLength) {
  42355. return maxConfigBuffer;
  42356. }
  42357. return Math.max(maxConfigBuffer, mainBufferLength);
  42358. };
  42359. _proto.loadFragment = function loadFragment(frag, levelDetails, targetBufferTime) {
  42360. this.fragCurrent = frag;
  42361. if (frag.sn === 'initSegment') {
  42362. this._loadInitSegment(frag, levelDetails);
  42363. } else {
  42364. this.startFragRequested = true;
  42365. _BaseStreamController.prototype.loadFragment.call(this, frag, levelDetails, targetBufferTime);
  42366. }
  42367. };
  42368. _createClass(SubtitleStreamController, [{
  42369. key: "mediaBufferTimeRanges",
  42370. get: function get() {
  42371. return new BufferableInstance(this.tracksBuffered[this.currentTrackId] || []);
  42372. }
  42373. }]);
  42374. return SubtitleStreamController;
  42375. }(_base_stream_controller__WEBPACK_IMPORTED_MODULE_6__["default"]);
  42376. var BufferableInstance = function BufferableInstance(timeranges) {
  42377. this.buffered = void 0;
  42378. var getRange = function getRange(name, index, length) {
  42379. index = index >>> 0;
  42380. if (index > length - 1) {
  42381. throw new DOMException("Failed to execute '" + name + "' on 'TimeRanges': The index provided (" + index + ") is greater than the maximum bound (" + length + ")");
  42382. }
  42383. return timeranges[index][name];
  42384. };
  42385. this.buffered = {
  42386. get length() {
  42387. return timeranges.length;
  42388. },
  42389. end: function end(index) {
  42390. return getRange('end', index, timeranges.length);
  42391. },
  42392. start: function start(index) {
  42393. return getRange('start', index, timeranges.length);
  42394. }
  42395. };
  42396. };
  42397. /***/ }),
  42398. /***/ "./src/controller/subtitle-track-controller.ts":
  42399. /*!*****************************************************!*\
  42400. !*** ./src/controller/subtitle-track-controller.ts ***!
  42401. \*****************************************************/
  42402. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  42403. "use strict";
  42404. __webpack_require__.r(__webpack_exports__);
  42405. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  42406. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  42407. /* harmony export */ });
  42408. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  42409. /* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts");
  42410. /* harmony import */ var _base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./base-playlist-controller */ "./src/controller/base-playlist-controller.ts");
  42411. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  42412. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  42413. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  42414. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  42415. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  42416. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  42417. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  42418. var SubtitleTrackController = /*#__PURE__*/function (_BasePlaylistControll) {
  42419. _inheritsLoose(SubtitleTrackController, _BasePlaylistControll);
  42420. function SubtitleTrackController(hls) {
  42421. var _this;
  42422. _this = _BasePlaylistControll.call(this, hls, '[subtitle-track-controller]') || this;
  42423. _this.media = null;
  42424. _this.tracks = [];
  42425. _this.groupId = null;
  42426. _this.tracksInGroup = [];
  42427. _this.trackId = -1;
  42428. _this.selectDefaultTrack = true;
  42429. _this.queuedDefaultTrack = -1;
  42430. _this.trackChangeListener = function () {
  42431. return _this.onTextTracksChanged();
  42432. };
  42433. _this.asyncPollTrackChange = function () {
  42434. return _this.pollTrackChange(0);
  42435. };
  42436. _this.useTextTrackPolling = false;
  42437. _this.subtitlePollingInterval = -1;
  42438. _this._subtitleDisplay = true;
  42439. _this.registerListeners();
  42440. return _this;
  42441. }
  42442. var _proto = SubtitleTrackController.prototype;
  42443. _proto.destroy = function destroy() {
  42444. this.unregisterListeners();
  42445. this.tracks.length = 0;
  42446. this.tracksInGroup.length = 0;
  42447. this.trackChangeListener = this.asyncPollTrackChange = null;
  42448. _BasePlaylistControll.prototype.destroy.call(this);
  42449. };
  42450. _proto.registerListeners = function registerListeners() {
  42451. var hls = this.hls;
  42452. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  42453. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  42454. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  42455. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  42456. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  42457. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING, this.onLevelSwitching, this);
  42458. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
  42459. hls.on(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, this.onError, this);
  42460. };
  42461. _proto.unregisterListeners = function unregisterListeners() {
  42462. var hls = this.hls;
  42463. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_ATTACHED, this.onMediaAttached, this);
  42464. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  42465. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  42466. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.MANIFEST_PARSED, this.onManifestParsed, this);
  42467. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  42468. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.LEVEL_SWITCHING, this.onLevelSwitching, this);
  42469. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADED, this.onSubtitleTrackLoaded, this);
  42470. hls.off(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, this.onError, this);
  42471. }
  42472. // Listen for subtitle track change, then extract the current track ID.
  42473. ;
  42474. _proto.onMediaAttached = function onMediaAttached(event, data) {
  42475. this.media = data.media;
  42476. if (!this.media) {
  42477. return;
  42478. }
  42479. if (this.queuedDefaultTrack > -1) {
  42480. this.subtitleTrack = this.queuedDefaultTrack;
  42481. this.queuedDefaultTrack = -1;
  42482. }
  42483. this.useTextTrackPolling = !(this.media.textTracks && 'onchange' in this.media.textTracks);
  42484. if (this.useTextTrackPolling) {
  42485. this.pollTrackChange(500);
  42486. } else {
  42487. this.media.textTracks.addEventListener('change', this.asyncPollTrackChange);
  42488. }
  42489. };
  42490. _proto.pollTrackChange = function pollTrackChange(timeout) {
  42491. self.clearInterval(this.subtitlePollingInterval);
  42492. this.subtitlePollingInterval = self.setInterval(this.trackChangeListener, timeout);
  42493. };
  42494. _proto.onMediaDetaching = function onMediaDetaching() {
  42495. if (!this.media) {
  42496. return;
  42497. }
  42498. self.clearInterval(this.subtitlePollingInterval);
  42499. if (!this.useTextTrackPolling) {
  42500. this.media.textTracks.removeEventListener('change', this.asyncPollTrackChange);
  42501. }
  42502. if (this.trackId > -1) {
  42503. this.queuedDefaultTrack = this.trackId;
  42504. }
  42505. var textTracks = filterSubtitleTracks(this.media.textTracks);
  42506. // Clear loaded cues on media detachment from tracks
  42507. textTracks.forEach(function (track) {
  42508. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_1__.clearCurrentCues)(track);
  42509. });
  42510. // Disable all subtitle tracks before detachment so when reattached only tracks in that content are enabled.
  42511. this.subtitleTrack = -1;
  42512. this.media = null;
  42513. };
  42514. _proto.onManifestLoading = function onManifestLoading() {
  42515. this.tracks = [];
  42516. this.groupId = null;
  42517. this.tracksInGroup = [];
  42518. this.trackId = -1;
  42519. this.selectDefaultTrack = true;
  42520. }
  42521. // Fired whenever a new manifest is loaded.
  42522. ;
  42523. _proto.onManifestParsed = function onManifestParsed(event, data) {
  42524. this.tracks = data.subtitleTracks;
  42525. };
  42526. _proto.onSubtitleTrackLoaded = function onSubtitleTrackLoaded(event, data) {
  42527. var id = data.id,
  42528. details = data.details;
  42529. var trackId = this.trackId;
  42530. var currentTrack = this.tracksInGroup[trackId];
  42531. if (!currentTrack) {
  42532. this.warn("Invalid subtitle track id " + id);
  42533. return;
  42534. }
  42535. var curDetails = currentTrack.details;
  42536. currentTrack.details = data.details;
  42537. this.log("subtitle track " + id + " loaded [" + details.startSN + "-" + details.endSN + "]");
  42538. if (id === this.trackId) {
  42539. this.retryCount = 0;
  42540. this.playlistLoaded(id, data, curDetails);
  42541. }
  42542. };
  42543. _proto.onLevelLoading = function onLevelLoading(event, data) {
  42544. this.switchLevel(data.level);
  42545. };
  42546. _proto.onLevelSwitching = function onLevelSwitching(event, data) {
  42547. this.switchLevel(data.level);
  42548. };
  42549. _proto.switchLevel = function switchLevel(levelIndex) {
  42550. var levelInfo = this.hls.levels[levelIndex];
  42551. if (!(levelInfo !== null && levelInfo !== void 0 && levelInfo.textGroupIds)) {
  42552. return;
  42553. }
  42554. var textGroupId = levelInfo.textGroupIds[levelInfo.urlId];
  42555. if (this.groupId !== textGroupId) {
  42556. var lastTrack = this.tracksInGroup ? this.tracksInGroup[this.trackId] : undefined;
  42557. var subtitleTracks = this.tracks.filter(function (track) {
  42558. return !textGroupId || track.groupId === textGroupId;
  42559. });
  42560. this.tracksInGroup = subtitleTracks;
  42561. var initialTrackId = this.findTrackId(lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.name) || this.findTrackId();
  42562. this.groupId = textGroupId;
  42563. var subtitleTracksUpdated = {
  42564. subtitleTracks: subtitleTracks
  42565. };
  42566. this.log("Updating subtitle tracks, " + subtitleTracks.length + " track(s) found in \"" + textGroupId + "\" group-id");
  42567. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACKS_UPDATED, subtitleTracksUpdated);
  42568. if (initialTrackId !== -1) {
  42569. this.setSubtitleTrack(initialTrackId, lastTrack);
  42570. }
  42571. }
  42572. };
  42573. _proto.findTrackId = function findTrackId(name) {
  42574. var textTracks = this.tracksInGroup;
  42575. for (var i = 0; i < textTracks.length; i++) {
  42576. var track = textTracks[i];
  42577. if (!this.selectDefaultTrack || track.default) {
  42578. if (!name || name === track.name) {
  42579. return track.id;
  42580. }
  42581. }
  42582. }
  42583. return -1;
  42584. };
  42585. _proto.onError = function onError(event, data) {
  42586. _BasePlaylistControll.prototype.onError.call(this, event, data);
  42587. if (data.fatal || !data.context) {
  42588. return;
  42589. }
  42590. if (data.context.type === _types_loader__WEBPACK_IMPORTED_MODULE_3__.PlaylistContextType.SUBTITLE_TRACK && data.context.id === this.trackId && data.context.groupId === this.groupId) {
  42591. this.retryLoadingOrFail(data);
  42592. }
  42593. }
  42594. /** get alternate subtitle tracks list from playlist **/;
  42595. _proto.loadPlaylist = function loadPlaylist(hlsUrlParameters) {
  42596. _BasePlaylistControll.prototype.loadPlaylist.call(this);
  42597. var currentTrack = this.tracksInGroup[this.trackId];
  42598. if (this.shouldLoadTrack(currentTrack)) {
  42599. var id = currentTrack.id;
  42600. var groupId = currentTrack.groupId;
  42601. var url = currentTrack.url;
  42602. if (hlsUrlParameters) {
  42603. try {
  42604. url = hlsUrlParameters.addDirectives(url);
  42605. } catch (error) {
  42606. this.warn("Could not construct new URL with HLS Delivery Directives: " + error);
  42607. }
  42608. }
  42609. this.log("Loading subtitle playlist for id " + id);
  42610. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_LOADING, {
  42611. url: url,
  42612. id: id,
  42613. groupId: groupId,
  42614. deliveryDirectives: hlsUrlParameters || null
  42615. });
  42616. }
  42617. }
  42618. /**
  42619. * Disables the old subtitleTrack and sets current mode on the next subtitleTrack.
  42620. * This operates on the DOM textTracks.
  42621. * A value of -1 will disable all subtitle tracks.
  42622. */;
  42623. _proto.toggleTrackModes = function toggleTrackModes(newId) {
  42624. var _this2 = this;
  42625. var media = this.media,
  42626. trackId = this.trackId;
  42627. if (!media) {
  42628. return;
  42629. }
  42630. var textTracks = filterSubtitleTracks(media.textTracks);
  42631. var groupTracks = textTracks.filter(function (track) {
  42632. return track.groupId === _this2.groupId;
  42633. });
  42634. if (newId === -1) {
  42635. [].slice.call(textTracks).forEach(function (track) {
  42636. track.mode = 'disabled';
  42637. });
  42638. } else {
  42639. var oldTrack = groupTracks[trackId];
  42640. if (oldTrack) {
  42641. oldTrack.mode = 'disabled';
  42642. }
  42643. }
  42644. var nextTrack = groupTracks[newId];
  42645. if (nextTrack) {
  42646. nextTrack.mode = this.subtitleDisplay ? 'showing' : 'hidden';
  42647. }
  42648. }
  42649. /**
  42650. * This method is responsible for validating the subtitle index and periodically reloading if live.
  42651. * Dispatches the SUBTITLE_TRACK_SWITCH event, which instructs the subtitle-stream-controller to load the selected track.
  42652. */;
  42653. _proto.setSubtitleTrack = function setSubtitleTrack(newId, lastTrack) {
  42654. var _tracks$newId;
  42655. var tracks = this.tracksInGroup;
  42656. // setting this.subtitleTrack will trigger internal logic
  42657. // if media has not been attached yet, it will fail
  42658. // we keep a reference to the default track id
  42659. // and we'll set subtitleTrack when onMediaAttached is triggered
  42660. if (!this.media) {
  42661. this.queuedDefaultTrack = newId;
  42662. return;
  42663. }
  42664. if (this.trackId !== newId) {
  42665. this.toggleTrackModes(newId);
  42666. }
  42667. // exit if track id as already set or invalid
  42668. if (this.trackId === newId && (newId === -1 || (_tracks$newId = tracks[newId]) !== null && _tracks$newId !== void 0 && _tracks$newId.details) || newId < -1 || newId >= tracks.length) {
  42669. return;
  42670. }
  42671. // stopping live reloading timer if any
  42672. this.clearTimer();
  42673. var track = tracks[newId];
  42674. this.log("Switching to subtitle track " + newId);
  42675. this.trackId = newId;
  42676. if (track) {
  42677. var id = track.id,
  42678. _track$groupId = track.groupId,
  42679. groupId = _track$groupId === void 0 ? '' : _track$groupId,
  42680. name = track.name,
  42681. type = track.type,
  42682. url = track.url;
  42683. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH, {
  42684. id: id,
  42685. groupId: groupId,
  42686. name: name,
  42687. type: type,
  42688. url: url
  42689. });
  42690. var hlsUrlParameters = this.switchParams(track.url, lastTrack === null || lastTrack === void 0 ? void 0 : lastTrack.details);
  42691. this.loadPlaylist(hlsUrlParameters);
  42692. } else {
  42693. // switch to -1
  42694. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_0__.Events.SUBTITLE_TRACK_SWITCH, {
  42695. id: newId
  42696. });
  42697. }
  42698. };
  42699. _proto.onTextTracksChanged = function onTextTracksChanged() {
  42700. if (!this.useTextTrackPolling) {
  42701. self.clearInterval(this.subtitlePollingInterval);
  42702. }
  42703. // Media is undefined when switching streams via loadSource()
  42704. if (!this.media || !this.hls.config.renderTextTracksNatively) {
  42705. return;
  42706. }
  42707. var trackId = -1;
  42708. var tracks = filterSubtitleTracks(this.media.textTracks);
  42709. for (var id = 0; id < tracks.length; id++) {
  42710. if (tracks[id].mode === 'hidden') {
  42711. // Do not break in case there is a following track with showing.
  42712. trackId = id;
  42713. } else if (tracks[id].mode === 'showing') {
  42714. trackId = id;
  42715. break;
  42716. }
  42717. }
  42718. // Setting current subtitleTrack will invoke code.
  42719. if (this.subtitleTrack !== trackId) {
  42720. this.subtitleTrack = trackId;
  42721. }
  42722. };
  42723. _createClass(SubtitleTrackController, [{
  42724. key: "subtitleDisplay",
  42725. get: function get() {
  42726. return this._subtitleDisplay;
  42727. },
  42728. set: function set(value) {
  42729. this._subtitleDisplay = value;
  42730. if (this.trackId > -1) {
  42731. this.toggleTrackModes(this.trackId);
  42732. }
  42733. }
  42734. }, {
  42735. key: "subtitleTracks",
  42736. get: function get() {
  42737. return this.tracksInGroup;
  42738. }
  42739. /** get/set index of the selected subtitle track (based on index in subtitle track lists) **/
  42740. }, {
  42741. key: "subtitleTrack",
  42742. get: function get() {
  42743. return this.trackId;
  42744. },
  42745. set: function set(newId) {
  42746. this.selectDefaultTrack = false;
  42747. var lastTrack = this.tracksInGroup ? this.tracksInGroup[this.trackId] : undefined;
  42748. this.setSubtitleTrack(newId, lastTrack);
  42749. }
  42750. }]);
  42751. return SubtitleTrackController;
  42752. }(_base_playlist_controller__WEBPACK_IMPORTED_MODULE_2__["default"]);
  42753. function filterSubtitleTracks(textTrackList) {
  42754. var tracks = [];
  42755. for (var i = 0; i < textTrackList.length; i++) {
  42756. var track = textTrackList[i];
  42757. // Edge adds a track without a label; we don't want to use it
  42758. if (track.kind === 'subtitles' && track.label) {
  42759. tracks.push(textTrackList[i]);
  42760. }
  42761. }
  42762. return tracks;
  42763. }
  42764. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SubtitleTrackController);
  42765. /***/ }),
  42766. /***/ "./src/controller/timeline-controller.ts":
  42767. /*!***********************************************!*\
  42768. !*** ./src/controller/timeline-controller.ts ***!
  42769. \***********************************************/
  42770. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  42771. "use strict";
  42772. __webpack_require__.r(__webpack_exports__);
  42773. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  42774. /* harmony export */ "TimelineController": () => (/* binding */ TimelineController)
  42775. /* harmony export */ });
  42776. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  42777. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  42778. /* harmony import */ var _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/cea-608-parser */ "./src/utils/cea-608-parser.ts");
  42779. /* harmony import */ var _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/output-filter */ "./src/utils/output-filter.ts");
  42780. /* harmony import */ var _utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/webvtt-parser */ "./src/utils/webvtt-parser.ts");
  42781. /* harmony import */ var _utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/texttrack-utils */ "./src/utils/texttrack-utils.ts");
  42782. /* harmony import */ var _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/imsc1-ttml-parser */ "./src/utils/imsc1-ttml-parser.ts");
  42783. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  42784. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  42785. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  42786. var TimelineController = /*#__PURE__*/function () {
  42787. function TimelineController(hls) {
  42788. this.hls = void 0;
  42789. this.media = null;
  42790. this.config = void 0;
  42791. this.enabled = true;
  42792. this.Cues = void 0;
  42793. this.textTracks = [];
  42794. this.tracks = [];
  42795. this.initPTS = [];
  42796. this.timescale = [];
  42797. this.unparsedVttFrags = [];
  42798. this.captionsTracks = {};
  42799. this.nonNativeCaptionsTracks = {};
  42800. this.cea608Parser1 = void 0;
  42801. this.cea608Parser2 = void 0;
  42802. this.lastSn = -1;
  42803. this.lastPartIndex = -1;
  42804. this.prevCC = -1;
  42805. this.vttCCs = newVTTCCs();
  42806. this.captionsProperties = void 0;
  42807. this.hls = hls;
  42808. this.config = hls.config;
  42809. this.Cues = hls.config.cueHandler;
  42810. this.captionsProperties = {
  42811. textTrack1: {
  42812. label: this.config.captionsTextTrack1Label,
  42813. languageCode: this.config.captionsTextTrack1LanguageCode
  42814. },
  42815. textTrack2: {
  42816. label: this.config.captionsTextTrack2Label,
  42817. languageCode: this.config.captionsTextTrack2LanguageCode
  42818. },
  42819. textTrack3: {
  42820. label: this.config.captionsTextTrack3Label,
  42821. languageCode: this.config.captionsTextTrack3LanguageCode
  42822. },
  42823. textTrack4: {
  42824. label: this.config.captionsTextTrack4Label,
  42825. languageCode: this.config.captionsTextTrack4LanguageCode
  42826. }
  42827. };
  42828. if (this.config.enableCEA708Captions) {
  42829. var channel1 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack1');
  42830. var channel2 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack2');
  42831. var channel3 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack3');
  42832. var channel4 = new _utils_output_filter__WEBPACK_IMPORTED_MODULE_3__["default"](this, 'textTrack4');
  42833. this.cea608Parser1 = new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](1, channel1, channel2);
  42834. this.cea608Parser2 = new _utils_cea_608_parser__WEBPACK_IMPORTED_MODULE_2__["default"](3, channel3, channel4);
  42835. }
  42836. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  42837. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  42838. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  42839. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED, this.onManifestLoaded, this);
  42840. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
  42841. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADING, this.onFragLoading, this);
  42842. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED, this.onFragLoaded, this);
  42843. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this);
  42844. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED, this.onFragDecrypted, this);
  42845. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
  42846. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this);
  42847. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  42848. }
  42849. var _proto = TimelineController.prototype;
  42850. _proto.destroy = function destroy() {
  42851. var hls = this.hls;
  42852. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_ATTACHING, this.onMediaAttaching, this);
  42853. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MEDIA_DETACHING, this.onMediaDetaching, this);
  42854. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  42855. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED, this.onManifestLoaded, this);
  42856. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_UPDATED, this.onSubtitleTracksUpdated, this);
  42857. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADING, this.onFragLoading, this);
  42858. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED, this.onFragLoaded, this);
  42859. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_PARSING_USERDATA, this.onFragParsingUserdata, this);
  42860. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED, this.onFragDecrypted, this);
  42861. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.INIT_PTS_FOUND, this.onInitPtsFound, this);
  42862. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACKS_CLEARED, this.onSubtitleTracksCleared, this);
  42863. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.BUFFER_FLUSHING, this.onBufferFlushing, this);
  42864. // @ts-ignore
  42865. this.hls = this.config = this.cea608Parser1 = this.cea608Parser2 = null;
  42866. };
  42867. _proto.addCues = function addCues(trackName, startTime, endTime, screen, cueRanges) {
  42868. // skip cues which overlap more than 50% with previously parsed time ranges
  42869. var merged = false;
  42870. for (var i = cueRanges.length; i--;) {
  42871. var cueRange = cueRanges[i];
  42872. var overlap = intersection(cueRange[0], cueRange[1], startTime, endTime);
  42873. if (overlap >= 0) {
  42874. cueRange[0] = Math.min(cueRange[0], startTime);
  42875. cueRange[1] = Math.max(cueRange[1], endTime);
  42876. merged = true;
  42877. if (overlap / (endTime - startTime) > 0.5) {
  42878. return;
  42879. }
  42880. }
  42881. }
  42882. if (!merged) {
  42883. cueRanges.push([startTime, endTime]);
  42884. }
  42885. if (this.config.renderTextTracksNatively) {
  42886. var track = this.captionsTracks[trackName];
  42887. this.Cues.newCue(track, startTime, endTime, screen);
  42888. } else {
  42889. var cues = this.Cues.newCue(null, startTime, endTime, screen);
  42890. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.CUES_PARSED, {
  42891. type: 'captions',
  42892. cues: cues,
  42893. track: trackName
  42894. });
  42895. }
  42896. }
  42897. // Triggered when an initial PTS is found; used for synchronisation of WebVTT.
  42898. ;
  42899. _proto.onInitPtsFound = function onInitPtsFound(event, _ref) {
  42900. var _this = this;
  42901. var frag = _ref.frag,
  42902. id = _ref.id,
  42903. initPTS = _ref.initPTS,
  42904. timescale = _ref.timescale;
  42905. var unparsedVttFrags = this.unparsedVttFrags;
  42906. if (id === 'main') {
  42907. this.initPTS[frag.cc] = initPTS;
  42908. this.timescale[frag.cc] = timescale;
  42909. }
  42910. // Due to asynchronous processing, initial PTS may arrive later than the first VTT fragments are loaded.
  42911. // Parse any unparsed fragments upon receiving the initial PTS.
  42912. if (unparsedVttFrags.length) {
  42913. this.unparsedVttFrags = [];
  42914. unparsedVttFrags.forEach(function (frag) {
  42915. _this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED, frag);
  42916. });
  42917. }
  42918. };
  42919. _proto.getExistingTrack = function getExistingTrack(trackName) {
  42920. var media = this.media;
  42921. if (media) {
  42922. for (var i = 0; i < media.textTracks.length; i++) {
  42923. var textTrack = media.textTracks[i];
  42924. if (textTrack[trackName]) {
  42925. return textTrack;
  42926. }
  42927. }
  42928. }
  42929. return null;
  42930. };
  42931. _proto.createCaptionsTrack = function createCaptionsTrack(trackName) {
  42932. if (this.config.renderTextTracksNatively) {
  42933. this.createNativeTrack(trackName);
  42934. } else {
  42935. this.createNonNativeTrack(trackName);
  42936. }
  42937. };
  42938. _proto.createNativeTrack = function createNativeTrack(trackName) {
  42939. if (this.captionsTracks[trackName]) {
  42940. return;
  42941. }
  42942. var captionsProperties = this.captionsProperties,
  42943. captionsTracks = this.captionsTracks,
  42944. media = this.media;
  42945. var _captionsProperties$t = captionsProperties[trackName],
  42946. label = _captionsProperties$t.label,
  42947. languageCode = _captionsProperties$t.languageCode;
  42948. // Enable reuse of existing text track.
  42949. var existingTrack = this.getExistingTrack(trackName);
  42950. if (!existingTrack) {
  42951. var textTrack = this.createTextTrack('captions', label, languageCode);
  42952. if (textTrack) {
  42953. // Set a special property on the track so we know it's managed by Hls.js
  42954. textTrack[trackName] = true;
  42955. captionsTracks[trackName] = textTrack;
  42956. }
  42957. } else {
  42958. captionsTracks[trackName] = existingTrack;
  42959. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(captionsTracks[trackName]);
  42960. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.sendAddTrackEvent)(captionsTracks[trackName], media);
  42961. }
  42962. };
  42963. _proto.createNonNativeTrack = function createNonNativeTrack(trackName) {
  42964. if (this.nonNativeCaptionsTracks[trackName]) {
  42965. return;
  42966. }
  42967. // Create a list of a single track for the provider to consume
  42968. var trackProperties = this.captionsProperties[trackName];
  42969. if (!trackProperties) {
  42970. return;
  42971. }
  42972. var label = trackProperties.label;
  42973. var track = {
  42974. _id: trackName,
  42975. label: label,
  42976. kind: 'captions',
  42977. default: trackProperties.media ? !!trackProperties.media.default : false,
  42978. closedCaptions: trackProperties.media
  42979. };
  42980. this.nonNativeCaptionsTracks[trackName] = track;
  42981. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.NON_NATIVE_TEXT_TRACKS_FOUND, {
  42982. tracks: [track]
  42983. });
  42984. };
  42985. _proto.createTextTrack = function createTextTrack(kind, label, lang) {
  42986. var media = this.media;
  42987. if (!media) {
  42988. return;
  42989. }
  42990. return media.addTextTrack(kind, label, lang);
  42991. };
  42992. _proto.onMediaAttaching = function onMediaAttaching(event, data) {
  42993. this.media = data.media;
  42994. this._cleanTracks();
  42995. };
  42996. _proto.onMediaDetaching = function onMediaDetaching() {
  42997. var captionsTracks = this.captionsTracks;
  42998. Object.keys(captionsTracks).forEach(function (trackName) {
  42999. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(captionsTracks[trackName]);
  43000. delete captionsTracks[trackName];
  43001. });
  43002. this.nonNativeCaptionsTracks = {};
  43003. };
  43004. _proto.onManifestLoading = function onManifestLoading() {
  43005. this.lastSn = -1; // Detect discontinuity in fragment parsing
  43006. this.lastPartIndex = -1;
  43007. this.prevCC = -1;
  43008. this.vttCCs = newVTTCCs(); // Detect discontinuity in subtitle manifests
  43009. this._cleanTracks();
  43010. this.tracks = [];
  43011. this.captionsTracks = {};
  43012. this.nonNativeCaptionsTracks = {};
  43013. this.textTracks = [];
  43014. this.unparsedVttFrags = this.unparsedVttFrags || [];
  43015. this.initPTS = [];
  43016. this.timescale = [];
  43017. if (this.cea608Parser1 && this.cea608Parser2) {
  43018. this.cea608Parser1.reset();
  43019. this.cea608Parser2.reset();
  43020. }
  43021. };
  43022. _proto._cleanTracks = function _cleanTracks() {
  43023. // clear outdated subtitles
  43024. var media = this.media;
  43025. if (!media) {
  43026. return;
  43027. }
  43028. var textTracks = media.textTracks;
  43029. if (textTracks) {
  43030. for (var i = 0; i < textTracks.length; i++) {
  43031. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(textTracks[i]);
  43032. }
  43033. }
  43034. };
  43035. _proto.onSubtitleTracksUpdated = function onSubtitleTracksUpdated(event, data) {
  43036. var _this2 = this;
  43037. this.textTracks = [];
  43038. var tracks = data.subtitleTracks || [];
  43039. var hasIMSC1 = tracks.some(function (track) {
  43040. return track.textCodec === _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.IMSC1_CODEC;
  43041. });
  43042. if (this.config.enableWebVTT || hasIMSC1 && this.config.enableIMSC1) {
  43043. var sameTracks = this.tracks && tracks && this.tracks.length === tracks.length;
  43044. this.tracks = tracks || [];
  43045. if (this.config.renderTextTracksNatively) {
  43046. var inUseTracks = this.media ? this.media.textTracks : [];
  43047. this.tracks.forEach(function (track, index) {
  43048. var textTrack;
  43049. if (index < inUseTracks.length) {
  43050. var inUseTrack = null;
  43051. for (var i = 0; i < inUseTracks.length; i++) {
  43052. if (canReuseVttTextTrack(inUseTracks[i], track)) {
  43053. inUseTrack = inUseTracks[i];
  43054. break;
  43055. }
  43056. }
  43057. // Reuse tracks with the same label, but do not reuse 608/708 tracks
  43058. if (inUseTrack) {
  43059. textTrack = inUseTrack;
  43060. }
  43061. }
  43062. if (textTrack) {
  43063. (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.clearCurrentCues)(textTrack);
  43064. } else {
  43065. var textTrackKind = _this2._captionsOrSubtitlesFromCharacteristics(track);
  43066. textTrack = _this2.createTextTrack(textTrackKind, track.name, track.lang);
  43067. if (textTrack) {
  43068. textTrack.mode = 'disabled';
  43069. }
  43070. }
  43071. if (textTrack) {
  43072. textTrack.groupId = track.groupId;
  43073. _this2.textTracks.push(textTrack);
  43074. }
  43075. });
  43076. } else if (!sameTracks && this.tracks && this.tracks.length) {
  43077. // Create a list of tracks for the provider to consume
  43078. var tracksList = this.tracks.map(function (track) {
  43079. return {
  43080. label: track.name,
  43081. kind: track.type.toLowerCase(),
  43082. default: track.default,
  43083. subtitleTrack: track
  43084. };
  43085. });
  43086. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.NON_NATIVE_TEXT_TRACKS_FOUND, {
  43087. tracks: tracksList
  43088. });
  43089. }
  43090. }
  43091. };
  43092. _proto._captionsOrSubtitlesFromCharacteristics = function _captionsOrSubtitlesFromCharacteristics(track) {
  43093. var _track$attrs;
  43094. if ((_track$attrs = track.attrs) !== null && _track$attrs !== void 0 && _track$attrs.CHARACTERISTICS) {
  43095. var transcribesSpokenDialog = /transcribes-spoken-dialog/gi.test(track.attrs.CHARACTERISTICS);
  43096. var describesMusicAndSound = /describes-music-and-sound/gi.test(track.attrs.CHARACTERISTICS);
  43097. if (transcribesSpokenDialog && describesMusicAndSound) {
  43098. return 'captions';
  43099. }
  43100. }
  43101. return 'subtitles';
  43102. };
  43103. _proto.onManifestLoaded = function onManifestLoaded(event, data) {
  43104. var _this3 = this;
  43105. if (this.config.enableCEA708Captions && data.captions) {
  43106. data.captions.forEach(function (captionsTrack) {
  43107. var instreamIdMatch = /(?:CC|SERVICE)([1-4])/.exec(captionsTrack.instreamId);
  43108. if (!instreamIdMatch) {
  43109. return;
  43110. }
  43111. var trackName = "textTrack" + instreamIdMatch[1];
  43112. var trackProperties = _this3.captionsProperties[trackName];
  43113. if (!trackProperties) {
  43114. return;
  43115. }
  43116. trackProperties.label = captionsTrack.name;
  43117. if (captionsTrack.lang) {
  43118. // optional attribute
  43119. trackProperties.languageCode = captionsTrack.lang;
  43120. }
  43121. trackProperties.media = captionsTrack;
  43122. });
  43123. }
  43124. };
  43125. _proto.closedCaptionsForLevel = function closedCaptionsForLevel(frag) {
  43126. var level = this.hls.levels[frag.level];
  43127. return level === null || level === void 0 ? void 0 : level.attrs['CLOSED-CAPTIONS'];
  43128. };
  43129. _proto.onFragLoading = function onFragLoading(event, data) {
  43130. var cea608Parser1 = this.cea608Parser1,
  43131. cea608Parser2 = this.cea608Parser2,
  43132. lastSn = this.lastSn,
  43133. lastPartIndex = this.lastPartIndex;
  43134. if (!this.enabled || !(cea608Parser1 && cea608Parser2)) {
  43135. return;
  43136. }
  43137. // if this frag isn't contiguous, clear the parser so cues with bad start/end times aren't added to the textTrack
  43138. if (data.frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.MAIN) {
  43139. var _data$part$index, _data$part;
  43140. var sn = data.frag.sn;
  43141. var partIndex = (_data$part$index = data === null || data === void 0 ? void 0 : (_data$part = data.part) === null || _data$part === void 0 ? void 0 : _data$part.index) != null ? _data$part$index : -1;
  43142. if (!(sn === lastSn + 1 || sn === lastSn && partIndex === lastPartIndex + 1)) {
  43143. cea608Parser1.reset();
  43144. cea608Parser2.reset();
  43145. }
  43146. this.lastSn = sn;
  43147. this.lastPartIndex = partIndex;
  43148. }
  43149. };
  43150. _proto.onFragLoaded = function onFragLoaded(event, data) {
  43151. var frag = data.frag,
  43152. payload = data.payload;
  43153. var initPTS = this.initPTS,
  43154. unparsedVttFrags = this.unparsedVttFrags;
  43155. if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.SUBTITLE) {
  43156. // If fragment is subtitle type, parse as WebVTT.
  43157. if (payload.byteLength) {
  43158. // We need an initial synchronisation PTS. Store fragments as long as none has arrived.
  43159. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(initPTS[frag.cc])) {
  43160. unparsedVttFrags.push(data);
  43161. if (initPTS.length) {
  43162. // finish unsuccessfully, otherwise the subtitle-stream-controller could be blocked from loading new frags.
  43163. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED, {
  43164. success: false,
  43165. frag: frag,
  43166. error: new Error('Missing initial subtitle PTS')
  43167. });
  43168. }
  43169. return;
  43170. }
  43171. var decryptData = frag.decryptdata;
  43172. // fragment after decryption has a stats object
  43173. var decrypted = ('stats' in data);
  43174. // If the subtitles are not encrypted, parse VTTs now. Otherwise, we need to wait.
  43175. if (decryptData == null || !decryptData.encrypted || decrypted) {
  43176. var trackPlaylistMedia = this.tracks[frag.level];
  43177. var vttCCs = this.vttCCs;
  43178. if (!vttCCs[frag.cc]) {
  43179. vttCCs[frag.cc] = {
  43180. start: frag.start,
  43181. prevCC: this.prevCC,
  43182. new: true
  43183. };
  43184. this.prevCC = frag.cc;
  43185. }
  43186. if (trackPlaylistMedia && trackPlaylistMedia.textCodec === _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.IMSC1_CODEC) {
  43187. this._parseIMSC1(frag, payload);
  43188. } else {
  43189. this._parseVTTs(frag, payload, vttCCs);
  43190. }
  43191. }
  43192. } else {
  43193. // In case there is no payload, finish unsuccessfully.
  43194. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED, {
  43195. success: false,
  43196. frag: frag,
  43197. error: new Error('Empty subtitle payload')
  43198. });
  43199. }
  43200. }
  43201. };
  43202. _proto._parseIMSC1 = function _parseIMSC1(frag, payload) {
  43203. var _this4 = this;
  43204. var hls = this.hls;
  43205. (0,_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.parseIMSC1)(payload, this.initPTS[frag.cc], this.timescale[frag.cc], function (cues) {
  43206. _this4._appendCues(cues, frag.level);
  43207. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED, {
  43208. success: true,
  43209. frag: frag
  43210. });
  43211. }, function (error) {
  43212. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("Failed to parse IMSC1: " + error);
  43213. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED, {
  43214. success: false,
  43215. frag: frag,
  43216. error: error
  43217. });
  43218. });
  43219. };
  43220. _proto._parseVTTs = function _parseVTTs(frag, payload, vttCCs) {
  43221. var _frag$initSegment,
  43222. _this5 = this;
  43223. var hls = this.hls;
  43224. // Parse the WebVTT file contents.
  43225. var payloadWebVTT = (_frag$initSegment = frag.initSegment) !== null && _frag$initSegment !== void 0 && _frag$initSegment.data ? (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_7__.appendUint8Array)(frag.initSegment.data, new Uint8Array(payload)) : payload;
  43226. (0,_utils_webvtt_parser__WEBPACK_IMPORTED_MODULE_4__.parseWebVTT)(payloadWebVTT, this.initPTS[frag.cc], this.timescale[frag.cc], vttCCs, frag.cc, frag.start, function (cues) {
  43227. _this5._appendCues(cues, frag.level);
  43228. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED, {
  43229. success: true,
  43230. frag: frag
  43231. });
  43232. }, function (error) {
  43233. _this5._fallbackToIMSC1(frag, payload);
  43234. // Something went wrong while parsing. Trigger event with success false.
  43235. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("Failed to parse VTT cue: " + error);
  43236. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_FRAG_PROCESSED, {
  43237. success: false,
  43238. frag: frag,
  43239. error: error
  43240. });
  43241. });
  43242. };
  43243. _proto._fallbackToIMSC1 = function _fallbackToIMSC1(frag, payload) {
  43244. var _this6 = this;
  43245. // If textCodec is unknown, try parsing as IMSC1. Set textCodec based on the result
  43246. var trackPlaylistMedia = this.tracks[frag.level];
  43247. if (!trackPlaylistMedia.textCodec) {
  43248. (0,_utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.parseIMSC1)(payload, this.initPTS[frag.cc], this.timescale[frag.cc], function () {
  43249. trackPlaylistMedia.textCodec = _utils_imsc1_ttml_parser__WEBPACK_IMPORTED_MODULE_6__.IMSC1_CODEC;
  43250. _this6._parseIMSC1(frag, payload);
  43251. }, function () {
  43252. trackPlaylistMedia.textCodec = 'wvtt';
  43253. });
  43254. }
  43255. };
  43256. _proto._appendCues = function _appendCues(cues, fragLevel) {
  43257. var hls = this.hls;
  43258. if (this.config.renderTextTracksNatively) {
  43259. var textTrack = this.textTracks[fragLevel];
  43260. // WebVTTParser.parse is an async method and if the currently selected text track mode is set to "disabled"
  43261. // before parsing is done then don't try to access currentTrack.cues.getCueById as cues will be null
  43262. // and trying to access getCueById method of cues will throw an exception
  43263. // Because we check if the mode is disabled, we can force check `cues` below. They can't be null.
  43264. if (!textTrack || textTrack.mode === 'disabled') {
  43265. return;
  43266. }
  43267. cues.forEach(function (cue) {
  43268. return (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.addCueToTrack)(textTrack, cue);
  43269. });
  43270. } else {
  43271. var currentTrack = this.tracks[fragLevel];
  43272. if (!currentTrack) {
  43273. return;
  43274. }
  43275. var track = currentTrack.default ? 'default' : 'subtitles' + fragLevel;
  43276. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.CUES_PARSED, {
  43277. type: 'subtitles',
  43278. cues: cues,
  43279. track: track
  43280. });
  43281. }
  43282. };
  43283. _proto.onFragDecrypted = function onFragDecrypted(event, data) {
  43284. var frag = data.frag;
  43285. if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.SUBTITLE) {
  43286. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.initPTS[frag.cc])) {
  43287. this.unparsedVttFrags.push(data);
  43288. return;
  43289. }
  43290. this.onFragLoaded(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_LOADED, data);
  43291. }
  43292. };
  43293. _proto.onSubtitleTracksCleared = function onSubtitleTracksCleared() {
  43294. this.tracks = [];
  43295. this.captionsTracks = {};
  43296. };
  43297. _proto.onFragParsingUserdata = function onFragParsingUserdata(event, data) {
  43298. var cea608Parser1 = this.cea608Parser1,
  43299. cea608Parser2 = this.cea608Parser2;
  43300. if (!this.enabled || !(cea608Parser1 && cea608Parser2)) {
  43301. return;
  43302. }
  43303. var frag = data.frag,
  43304. samples = data.samples;
  43305. if (frag.type === _types_loader__WEBPACK_IMPORTED_MODULE_8__.PlaylistLevelType.MAIN && this.closedCaptionsForLevel(frag) === 'NONE') {
  43306. return;
  43307. }
  43308. // If the event contains captions (found in the bytes property), push all bytes into the parser immediately
  43309. // It will create the proper timestamps based on the PTS value
  43310. for (var i = 0; i < samples.length; i++) {
  43311. var ccBytes = samples[i].bytes;
  43312. if (ccBytes) {
  43313. var ccdatas = this.extractCea608Data(ccBytes);
  43314. cea608Parser1.addData(samples[i].pts, ccdatas[0]);
  43315. cea608Parser2.addData(samples[i].pts, ccdatas[1]);
  43316. }
  43317. }
  43318. };
  43319. _proto.onBufferFlushing = function onBufferFlushing(event, _ref2) {
  43320. var startOffset = _ref2.startOffset,
  43321. endOffset = _ref2.endOffset,
  43322. endOffsetSubtitles = _ref2.endOffsetSubtitles,
  43323. type = _ref2.type;
  43324. var media = this.media;
  43325. if (!media || media.currentTime < endOffset) {
  43326. return;
  43327. }
  43328. // Clear 608 caption cues from the captions TextTracks when the video back buffer is flushed
  43329. // Forward cues are never removed because we can loose streamed 608 content from recent fragments
  43330. if (!type || type === 'video') {
  43331. var captionsTracks = this.captionsTracks;
  43332. Object.keys(captionsTracks).forEach(function (trackName) {
  43333. return (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.removeCuesInRange)(captionsTracks[trackName], startOffset, endOffset);
  43334. });
  43335. }
  43336. if (this.config.renderTextTracksNatively) {
  43337. // Clear VTT/IMSC1 subtitle cues from the subtitle TextTracks when the back buffer is flushed
  43338. if (startOffset === 0 && endOffsetSubtitles !== undefined) {
  43339. var textTracks = this.textTracks;
  43340. Object.keys(textTracks).forEach(function (trackName) {
  43341. return (0,_utils_texttrack_utils__WEBPACK_IMPORTED_MODULE_5__.removeCuesInRange)(textTracks[trackName], startOffset, endOffsetSubtitles);
  43342. });
  43343. }
  43344. }
  43345. };
  43346. _proto.extractCea608Data = function extractCea608Data(byteArray) {
  43347. var actualCCBytes = [[], []];
  43348. var count = byteArray[0] & 0x1f;
  43349. var position = 2;
  43350. for (var j = 0; j < count; j++) {
  43351. var tmpByte = byteArray[position++];
  43352. var ccbyte1 = 0x7f & byteArray[position++];
  43353. var ccbyte2 = 0x7f & byteArray[position++];
  43354. if (ccbyte1 === 0 && ccbyte2 === 0) {
  43355. continue;
  43356. }
  43357. var ccValid = (0x04 & tmpByte) !== 0; // Support all four channels
  43358. if (ccValid) {
  43359. var ccType = 0x03 & tmpByte;
  43360. if (0x00 /* CEA608 field1*/ === ccType || 0x01 /* CEA608 field2*/ === ccType) {
  43361. // Exclude CEA708 CC data.
  43362. actualCCBytes[ccType].push(ccbyte1);
  43363. actualCCBytes[ccType].push(ccbyte2);
  43364. }
  43365. }
  43366. }
  43367. return actualCCBytes;
  43368. };
  43369. return TimelineController;
  43370. }();
  43371. function canReuseVttTextTrack(inUseTrack, manifestTrack) {
  43372. return inUseTrack && inUseTrack.label === manifestTrack.name && !(inUseTrack.textTrack1 || inUseTrack.textTrack2);
  43373. }
  43374. function intersection(x1, x2, y1, y2) {
  43375. return Math.min(x2, y2) - Math.max(x1, y1);
  43376. }
  43377. function newVTTCCs() {
  43378. return {
  43379. ccOffset: 0,
  43380. presentationOffset: 0,
  43381. 0: {
  43382. start: 0,
  43383. prevCC: -1,
  43384. new: true
  43385. }
  43386. };
  43387. }
  43388. /***/ }),
  43389. /***/ "./src/crypt/aes-crypto.ts":
  43390. /*!*********************************!*\
  43391. !*** ./src/crypt/aes-crypto.ts ***!
  43392. \*********************************/
  43393. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  43394. "use strict";
  43395. __webpack_require__.r(__webpack_exports__);
  43396. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  43397. /* harmony export */ "default": () => (/* binding */ AESCrypto)
  43398. /* harmony export */ });
  43399. var AESCrypto = /*#__PURE__*/function () {
  43400. function AESCrypto(subtle, iv) {
  43401. this.subtle = void 0;
  43402. this.aesIV = void 0;
  43403. this.subtle = subtle;
  43404. this.aesIV = iv;
  43405. }
  43406. var _proto = AESCrypto.prototype;
  43407. _proto.decrypt = function decrypt(data, key) {
  43408. return this.subtle.decrypt({
  43409. name: 'AES-CBC',
  43410. iv: this.aesIV
  43411. }, key, data);
  43412. };
  43413. return AESCrypto;
  43414. }();
  43415. /***/ }),
  43416. /***/ "./src/crypt/aes-decryptor.ts":
  43417. /*!************************************!*\
  43418. !*** ./src/crypt/aes-decryptor.ts ***!
  43419. \************************************/
  43420. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  43421. "use strict";
  43422. __webpack_require__.r(__webpack_exports__);
  43423. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  43424. /* harmony export */ "default": () => (/* binding */ AESDecryptor),
  43425. /* harmony export */ "removePadding": () => (/* binding */ removePadding)
  43426. /* harmony export */ });
  43427. /* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts");
  43428. // PKCS7
  43429. function removePadding(array) {
  43430. var outputBytes = array.byteLength;
  43431. var paddingBytes = outputBytes && new DataView(array.buffer).getUint8(outputBytes - 1);
  43432. if (paddingBytes) {
  43433. return (0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_0__.sliceUint8)(array, 0, outputBytes - paddingBytes);
  43434. }
  43435. return array;
  43436. }
  43437. var AESDecryptor = /*#__PURE__*/function () {
  43438. function AESDecryptor() {
  43439. this.rcon = [0x0, 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36];
  43440. this.subMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)];
  43441. this.invSubMix = [new Uint32Array(256), new Uint32Array(256), new Uint32Array(256), new Uint32Array(256)];
  43442. this.sBox = new Uint32Array(256);
  43443. this.invSBox = new Uint32Array(256);
  43444. this.key = new Uint32Array(0);
  43445. this.ksRows = 0;
  43446. this.keySize = 0;
  43447. this.keySchedule = void 0;
  43448. this.invKeySchedule = void 0;
  43449. this.initTable();
  43450. }
  43451. // Using view.getUint32() also swaps the byte order.
  43452. var _proto = AESDecryptor.prototype;
  43453. _proto.uint8ArrayToUint32Array_ = function uint8ArrayToUint32Array_(arrayBuffer) {
  43454. var view = new DataView(arrayBuffer);
  43455. var newArray = new Uint32Array(4);
  43456. for (var i = 0; i < 4; i++) {
  43457. newArray[i] = view.getUint32(i * 4);
  43458. }
  43459. return newArray;
  43460. };
  43461. _proto.initTable = function initTable() {
  43462. var sBox = this.sBox;
  43463. var invSBox = this.invSBox;
  43464. var subMix = this.subMix;
  43465. var subMix0 = subMix[0];
  43466. var subMix1 = subMix[1];
  43467. var subMix2 = subMix[2];
  43468. var subMix3 = subMix[3];
  43469. var invSubMix = this.invSubMix;
  43470. var invSubMix0 = invSubMix[0];
  43471. var invSubMix1 = invSubMix[1];
  43472. var invSubMix2 = invSubMix[2];
  43473. var invSubMix3 = invSubMix[3];
  43474. var d = new Uint32Array(256);
  43475. var x = 0;
  43476. var xi = 0;
  43477. var i = 0;
  43478. for (i = 0; i < 256; i++) {
  43479. if (i < 128) {
  43480. d[i] = i << 1;
  43481. } else {
  43482. d[i] = i << 1 ^ 0x11b;
  43483. }
  43484. }
  43485. for (i = 0; i < 256; i++) {
  43486. var sx = xi ^ xi << 1 ^ xi << 2 ^ xi << 3 ^ xi << 4;
  43487. sx = sx >>> 8 ^ sx & 0xff ^ 0x63;
  43488. sBox[x] = sx;
  43489. invSBox[sx] = x;
  43490. // Compute multiplication
  43491. var x2 = d[x];
  43492. var x4 = d[x2];
  43493. var x8 = d[x4];
  43494. // Compute sub/invSub bytes, mix columns tables
  43495. var t = d[sx] * 0x101 ^ sx * 0x1010100;
  43496. subMix0[x] = t << 24 | t >>> 8;
  43497. subMix1[x] = t << 16 | t >>> 16;
  43498. subMix2[x] = t << 8 | t >>> 24;
  43499. subMix3[x] = t;
  43500. // Compute inv sub bytes, inv mix columns tables
  43501. t = x8 * 0x1010101 ^ x4 * 0x10001 ^ x2 * 0x101 ^ x * 0x1010100;
  43502. invSubMix0[sx] = t << 24 | t >>> 8;
  43503. invSubMix1[sx] = t << 16 | t >>> 16;
  43504. invSubMix2[sx] = t << 8 | t >>> 24;
  43505. invSubMix3[sx] = t;
  43506. // Compute next counter
  43507. if (!x) {
  43508. x = xi = 1;
  43509. } else {
  43510. x = x2 ^ d[d[d[x8 ^ x2]]];
  43511. xi ^= d[d[xi]];
  43512. }
  43513. }
  43514. };
  43515. _proto.expandKey = function expandKey(keyBuffer) {
  43516. // convert keyBuffer to Uint32Array
  43517. var key = this.uint8ArrayToUint32Array_(keyBuffer);
  43518. var sameKey = true;
  43519. var offset = 0;
  43520. while (offset < key.length && sameKey) {
  43521. sameKey = key[offset] === this.key[offset];
  43522. offset++;
  43523. }
  43524. if (sameKey) {
  43525. return;
  43526. }
  43527. this.key = key;
  43528. var keySize = this.keySize = key.length;
  43529. if (keySize !== 4 && keySize !== 6 && keySize !== 8) {
  43530. throw new Error('Invalid aes key size=' + keySize);
  43531. }
  43532. var ksRows = this.ksRows = (keySize + 6 + 1) * 4;
  43533. var ksRow;
  43534. var invKsRow;
  43535. var keySchedule = this.keySchedule = new Uint32Array(ksRows);
  43536. var invKeySchedule = this.invKeySchedule = new Uint32Array(ksRows);
  43537. var sbox = this.sBox;
  43538. var rcon = this.rcon;
  43539. var invSubMix = this.invSubMix;
  43540. var invSubMix0 = invSubMix[0];
  43541. var invSubMix1 = invSubMix[1];
  43542. var invSubMix2 = invSubMix[2];
  43543. var invSubMix3 = invSubMix[3];
  43544. var prev;
  43545. var t;
  43546. for (ksRow = 0; ksRow < ksRows; ksRow++) {
  43547. if (ksRow < keySize) {
  43548. prev = keySchedule[ksRow] = key[ksRow];
  43549. continue;
  43550. }
  43551. t = prev;
  43552. if (ksRow % keySize === 0) {
  43553. // Rot word
  43554. t = t << 8 | t >>> 24;
  43555. // Sub word
  43556. t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 0xff] << 16 | sbox[t >>> 8 & 0xff] << 8 | sbox[t & 0xff];
  43557. // Mix Rcon
  43558. t ^= rcon[ksRow / keySize | 0] << 24;
  43559. } else if (keySize > 6 && ksRow % keySize === 4) {
  43560. // Sub word
  43561. t = sbox[t >>> 24] << 24 | sbox[t >>> 16 & 0xff] << 16 | sbox[t >>> 8 & 0xff] << 8 | sbox[t & 0xff];
  43562. }
  43563. keySchedule[ksRow] = prev = (keySchedule[ksRow - keySize] ^ t) >>> 0;
  43564. }
  43565. for (invKsRow = 0; invKsRow < ksRows; invKsRow++) {
  43566. ksRow = ksRows - invKsRow;
  43567. if (invKsRow & 3) {
  43568. t = keySchedule[ksRow];
  43569. } else {
  43570. t = keySchedule[ksRow - 4];
  43571. }
  43572. if (invKsRow < 4 || ksRow <= 4) {
  43573. invKeySchedule[invKsRow] = t;
  43574. } else {
  43575. invKeySchedule[invKsRow] = invSubMix0[sbox[t >>> 24]] ^ invSubMix1[sbox[t >>> 16 & 0xff]] ^ invSubMix2[sbox[t >>> 8 & 0xff]] ^ invSubMix3[sbox[t & 0xff]];
  43576. }
  43577. invKeySchedule[invKsRow] = invKeySchedule[invKsRow] >>> 0;
  43578. }
  43579. }
  43580. // Adding this as a method greatly improves performance.
  43581. ;
  43582. _proto.networkToHostOrderSwap = function networkToHostOrderSwap(word) {
  43583. return word << 24 | (word & 0xff00) << 8 | (word & 0xff0000) >> 8 | word >>> 24;
  43584. };
  43585. _proto.decrypt = function decrypt(inputArrayBuffer, offset, aesIV) {
  43586. var nRounds = this.keySize + 6;
  43587. var invKeySchedule = this.invKeySchedule;
  43588. var invSBOX = this.invSBox;
  43589. var invSubMix = this.invSubMix;
  43590. var invSubMix0 = invSubMix[0];
  43591. var invSubMix1 = invSubMix[1];
  43592. var invSubMix2 = invSubMix[2];
  43593. var invSubMix3 = invSubMix[3];
  43594. var initVector = this.uint8ArrayToUint32Array_(aesIV);
  43595. var initVector0 = initVector[0];
  43596. var initVector1 = initVector[1];
  43597. var initVector2 = initVector[2];
  43598. var initVector3 = initVector[3];
  43599. var inputInt32 = new Int32Array(inputArrayBuffer);
  43600. var outputInt32 = new Int32Array(inputInt32.length);
  43601. var t0, t1, t2, t3;
  43602. var s0, s1, s2, s3;
  43603. var inputWords0, inputWords1, inputWords2, inputWords3;
  43604. var ksRow, i;
  43605. var swapWord = this.networkToHostOrderSwap;
  43606. while (offset < inputInt32.length) {
  43607. inputWords0 = swapWord(inputInt32[offset]);
  43608. inputWords1 = swapWord(inputInt32[offset + 1]);
  43609. inputWords2 = swapWord(inputInt32[offset + 2]);
  43610. inputWords3 = swapWord(inputInt32[offset + 3]);
  43611. s0 = inputWords0 ^ invKeySchedule[0];
  43612. s1 = inputWords3 ^ invKeySchedule[1];
  43613. s2 = inputWords2 ^ invKeySchedule[2];
  43614. s3 = inputWords1 ^ invKeySchedule[3];
  43615. ksRow = 4;
  43616. // Iterate through the rounds of decryption
  43617. for (i = 1; i < nRounds; i++) {
  43618. t0 = invSubMix0[s0 >>> 24] ^ invSubMix1[s1 >> 16 & 0xff] ^ invSubMix2[s2 >> 8 & 0xff] ^ invSubMix3[s3 & 0xff] ^ invKeySchedule[ksRow];
  43619. t1 = invSubMix0[s1 >>> 24] ^ invSubMix1[s2 >> 16 & 0xff] ^ invSubMix2[s3 >> 8 & 0xff] ^ invSubMix3[s0 & 0xff] ^ invKeySchedule[ksRow + 1];
  43620. t2 = invSubMix0[s2 >>> 24] ^ invSubMix1[s3 >> 16 & 0xff] ^ invSubMix2[s0 >> 8 & 0xff] ^ invSubMix3[s1 & 0xff] ^ invKeySchedule[ksRow + 2];
  43621. t3 = invSubMix0[s3 >>> 24] ^ invSubMix1[s0 >> 16 & 0xff] ^ invSubMix2[s1 >> 8 & 0xff] ^ invSubMix3[s2 & 0xff] ^ invKeySchedule[ksRow + 3];
  43622. // Update state
  43623. s0 = t0;
  43624. s1 = t1;
  43625. s2 = t2;
  43626. s3 = t3;
  43627. ksRow = ksRow + 4;
  43628. }
  43629. // Shift rows, sub bytes, add round key
  43630. t0 = invSBOX[s0 >>> 24] << 24 ^ invSBOX[s1 >> 16 & 0xff] << 16 ^ invSBOX[s2 >> 8 & 0xff] << 8 ^ invSBOX[s3 & 0xff] ^ invKeySchedule[ksRow];
  43631. t1 = invSBOX[s1 >>> 24] << 24 ^ invSBOX[s2 >> 16 & 0xff] << 16 ^ invSBOX[s3 >> 8 & 0xff] << 8 ^ invSBOX[s0 & 0xff] ^ invKeySchedule[ksRow + 1];
  43632. t2 = invSBOX[s2 >>> 24] << 24 ^ invSBOX[s3 >> 16 & 0xff] << 16 ^ invSBOX[s0 >> 8 & 0xff] << 8 ^ invSBOX[s1 & 0xff] ^ invKeySchedule[ksRow + 2];
  43633. t3 = invSBOX[s3 >>> 24] << 24 ^ invSBOX[s0 >> 16 & 0xff] << 16 ^ invSBOX[s1 >> 8 & 0xff] << 8 ^ invSBOX[s2 & 0xff] ^ invKeySchedule[ksRow + 3];
  43634. // Write
  43635. outputInt32[offset] = swapWord(t0 ^ initVector0);
  43636. outputInt32[offset + 1] = swapWord(t3 ^ initVector1);
  43637. outputInt32[offset + 2] = swapWord(t2 ^ initVector2);
  43638. outputInt32[offset + 3] = swapWord(t1 ^ initVector3);
  43639. // reset initVector to last 4 unsigned int
  43640. initVector0 = inputWords0;
  43641. initVector1 = inputWords1;
  43642. initVector2 = inputWords2;
  43643. initVector3 = inputWords3;
  43644. offset = offset + 4;
  43645. }
  43646. return outputInt32.buffer;
  43647. };
  43648. return AESDecryptor;
  43649. }();
  43650. /***/ }),
  43651. /***/ "./src/crypt/decrypter.ts":
  43652. /*!********************************!*\
  43653. !*** ./src/crypt/decrypter.ts ***!
  43654. \********************************/
  43655. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  43656. "use strict";
  43657. __webpack_require__.r(__webpack_exports__);
  43658. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  43659. /* harmony export */ "default": () => (/* binding */ Decrypter)
  43660. /* harmony export */ });
  43661. /* harmony import */ var _aes_crypto__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./aes-crypto */ "./src/crypt/aes-crypto.ts");
  43662. /* harmony import */ var _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./fast-aes-key */ "./src/crypt/fast-aes-key.ts");
  43663. /* harmony import */ var _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./aes-decryptor */ "./src/crypt/aes-decryptor.ts");
  43664. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  43665. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  43666. /* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts");
  43667. var CHUNK_SIZE = 16; // 16 bytes, 128 bits
  43668. var Decrypter = /*#__PURE__*/function () {
  43669. function Decrypter(config, _temp) {
  43670. var _ref = _temp === void 0 ? {} : _temp,
  43671. _ref$removePKCS7Paddi = _ref.removePKCS7Padding,
  43672. removePKCS7Padding = _ref$removePKCS7Paddi === void 0 ? true : _ref$removePKCS7Paddi;
  43673. this.logEnabled = true;
  43674. this.removePKCS7Padding = void 0;
  43675. this.subtle = null;
  43676. this.softwareDecrypter = null;
  43677. this.key = null;
  43678. this.fastAesKey = null;
  43679. this.remainderData = null;
  43680. this.currentIV = null;
  43681. this.currentResult = null;
  43682. this.useSoftware = void 0;
  43683. this.useSoftware = config.enableSoftwareAES;
  43684. this.removePKCS7Padding = removePKCS7Padding;
  43685. // built in decryptor expects PKCS7 padding
  43686. if (removePKCS7Padding) {
  43687. try {
  43688. var browserCrypto = self.crypto;
  43689. if (browserCrypto) {
  43690. this.subtle = browserCrypto.subtle || browserCrypto.webkitSubtle;
  43691. }
  43692. } catch (e) {
  43693. /* no-op */
  43694. }
  43695. }
  43696. if (this.subtle === null) {
  43697. this.useSoftware = true;
  43698. }
  43699. }
  43700. var _proto = Decrypter.prototype;
  43701. _proto.destroy = function destroy() {
  43702. this.subtle = null;
  43703. this.softwareDecrypter = null;
  43704. this.key = null;
  43705. this.fastAesKey = null;
  43706. this.remainderData = null;
  43707. this.currentIV = null;
  43708. this.currentResult = null;
  43709. };
  43710. _proto.isSync = function isSync() {
  43711. return this.useSoftware;
  43712. };
  43713. _proto.flush = function flush() {
  43714. var currentResult = this.currentResult,
  43715. remainderData = this.remainderData;
  43716. if (!currentResult || remainderData) {
  43717. this.reset();
  43718. return null;
  43719. }
  43720. var data = new Uint8Array(currentResult);
  43721. this.reset();
  43722. if (this.removePKCS7Padding) {
  43723. return (0,_aes_decryptor__WEBPACK_IMPORTED_MODULE_2__.removePadding)(data);
  43724. }
  43725. return data;
  43726. };
  43727. _proto.reset = function reset() {
  43728. this.currentResult = null;
  43729. this.currentIV = null;
  43730. this.remainderData = null;
  43731. if (this.softwareDecrypter) {
  43732. this.softwareDecrypter = null;
  43733. }
  43734. };
  43735. _proto.decrypt = function decrypt(data, key, iv) {
  43736. var _this = this;
  43737. if (this.useSoftware) {
  43738. return new Promise(function (resolve, reject) {
  43739. _this.softwareDecrypt(new Uint8Array(data), key, iv);
  43740. var decryptResult = _this.flush();
  43741. if (decryptResult) {
  43742. resolve(decryptResult.buffer);
  43743. } else {
  43744. reject(new Error('[softwareDecrypt] Failed to decrypt data'));
  43745. }
  43746. });
  43747. }
  43748. return this.webCryptoDecrypt(new Uint8Array(data), key, iv);
  43749. }
  43750. // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
  43751. // data is handled in the flush() call
  43752. ;
  43753. _proto.softwareDecrypt = function softwareDecrypt(data, key, iv) {
  43754. var currentIV = this.currentIV,
  43755. currentResult = this.currentResult,
  43756. remainderData = this.remainderData;
  43757. this.logOnce('JS AES decrypt');
  43758. // The output is staggered during progressive parsing - the current result is cached, and emitted on the next call
  43759. // This is done in order to strip PKCS7 padding, which is found at the end of each segment. We only know we've reached
  43760. // the end on flush(), but by that time we have already received all bytes for the segment.
  43761. // Progressive decryption does not work with WebCrypto
  43762. if (remainderData) {
  43763. data = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__.appendUint8Array)(remainderData, data);
  43764. this.remainderData = null;
  43765. }
  43766. // Byte length must be a multiple of 16 (AES-128 = 128 bit blocks = 16 bytes)
  43767. var currentChunk = this.getValidChunk(data);
  43768. if (!currentChunk.length) {
  43769. return null;
  43770. }
  43771. if (currentIV) {
  43772. iv = currentIV;
  43773. }
  43774. var softwareDecrypter = this.softwareDecrypter;
  43775. if (!softwareDecrypter) {
  43776. softwareDecrypter = this.softwareDecrypter = new _aes_decryptor__WEBPACK_IMPORTED_MODULE_2__["default"]();
  43777. }
  43778. softwareDecrypter.expandKey(key);
  43779. var result = currentResult;
  43780. this.currentResult = softwareDecrypter.decrypt(currentChunk.buffer, 0, iv);
  43781. this.currentIV = (0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(currentChunk, -16).buffer;
  43782. if (!result) {
  43783. return null;
  43784. }
  43785. return result;
  43786. };
  43787. _proto.webCryptoDecrypt = function webCryptoDecrypt(data, key, iv) {
  43788. var _this2 = this;
  43789. var subtle = this.subtle;
  43790. if (this.key !== key || !this.fastAesKey) {
  43791. this.key = key;
  43792. this.fastAesKey = new _fast_aes_key__WEBPACK_IMPORTED_MODULE_1__["default"](subtle, key);
  43793. }
  43794. return this.fastAesKey.expandKey().then(function (aesKey) {
  43795. // decrypt using web crypto
  43796. if (!subtle) {
  43797. return Promise.reject(new Error('web crypto not initialized'));
  43798. }
  43799. _this2.logOnce('WebCrypto AES decrypt');
  43800. var crypto = new _aes_crypto__WEBPACK_IMPORTED_MODULE_0__["default"](subtle, new Uint8Array(iv));
  43801. return crypto.decrypt(data.buffer, aesKey);
  43802. }).catch(function (err) {
  43803. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("[decrypter]: WebCrypto Error, disable WebCrypto API, " + err.name + ": " + err.message);
  43804. return _this2.onWebCryptoError(data, key, iv);
  43805. });
  43806. };
  43807. _proto.onWebCryptoError = function onWebCryptoError(data, key, iv) {
  43808. this.useSoftware = true;
  43809. this.logEnabled = true;
  43810. this.softwareDecrypt(data, key, iv);
  43811. var decryptResult = this.flush();
  43812. if (decryptResult) {
  43813. return decryptResult.buffer;
  43814. }
  43815. throw new Error('WebCrypto and softwareDecrypt: failed to decrypt data');
  43816. };
  43817. _proto.getValidChunk = function getValidChunk(data) {
  43818. var currentChunk = data;
  43819. var splitPoint = data.length - data.length % CHUNK_SIZE;
  43820. if (splitPoint !== data.length) {
  43821. currentChunk = (0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(data, 0, splitPoint);
  43822. this.remainderData = (0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(data, splitPoint);
  43823. }
  43824. return currentChunk;
  43825. };
  43826. _proto.logOnce = function logOnce(msg) {
  43827. if (!this.logEnabled) {
  43828. return;
  43829. }
  43830. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[decrypter]: " + msg);
  43831. this.logEnabled = false;
  43832. };
  43833. return Decrypter;
  43834. }();
  43835. /***/ }),
  43836. /***/ "./src/crypt/fast-aes-key.ts":
  43837. /*!***********************************!*\
  43838. !*** ./src/crypt/fast-aes-key.ts ***!
  43839. \***********************************/
  43840. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  43841. "use strict";
  43842. __webpack_require__.r(__webpack_exports__);
  43843. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  43844. /* harmony export */ "default": () => (/* binding */ FastAESKey)
  43845. /* harmony export */ });
  43846. var FastAESKey = /*#__PURE__*/function () {
  43847. function FastAESKey(subtle, key) {
  43848. this.subtle = void 0;
  43849. this.key = void 0;
  43850. this.subtle = subtle;
  43851. this.key = key;
  43852. }
  43853. var _proto = FastAESKey.prototype;
  43854. _proto.expandKey = function expandKey() {
  43855. return this.subtle.importKey('raw', this.key, {
  43856. name: 'AES-CBC'
  43857. }, false, ['encrypt', 'decrypt']);
  43858. };
  43859. return FastAESKey;
  43860. }();
  43861. /***/ }),
  43862. /***/ "./src/demux/aacdemuxer.ts":
  43863. /*!*********************************!*\
  43864. !*** ./src/demux/aacdemuxer.ts ***!
  43865. \*********************************/
  43866. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  43867. "use strict";
  43868. __webpack_require__.r(__webpack_exports__);
  43869. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  43870. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  43871. /* harmony export */ });
  43872. /* harmony import */ var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-audio-demuxer */ "./src/demux/base-audio-demuxer.ts");
  43873. /* harmony import */ var _adts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./adts */ "./src/demux/adts.ts");
  43874. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  43875. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  43876. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  43877. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  43878. /**
  43879. * AAC demuxer
  43880. */
  43881. var AACDemuxer = /*#__PURE__*/function (_BaseAudioDemuxer) {
  43882. _inheritsLoose(AACDemuxer, _BaseAudioDemuxer);
  43883. function AACDemuxer(observer, config) {
  43884. var _this;
  43885. _this = _BaseAudioDemuxer.call(this) || this;
  43886. _this.observer = void 0;
  43887. _this.config = void 0;
  43888. _this.observer = observer;
  43889. _this.config = config;
  43890. return _this;
  43891. }
  43892. var _proto = AACDemuxer.prototype;
  43893. _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration) {
  43894. _BaseAudioDemuxer.prototype.resetInitSegment.call(this, initSegment, audioCodec, videoCodec, trackDuration);
  43895. this._audioTrack = {
  43896. container: 'audio/adts',
  43897. type: 'audio',
  43898. id: 2,
  43899. pid: -1,
  43900. sequenceNumber: 0,
  43901. segmentCodec: 'aac',
  43902. samples: [],
  43903. manifestCodec: audioCodec,
  43904. duration: trackDuration,
  43905. inputTimeScale: 90000,
  43906. dropped: 0
  43907. };
  43908. }
  43909. // Source for probe info - https://wiki.multimedia.cx/index.php?title=ADTS
  43910. ;
  43911. AACDemuxer.probe = function probe(data) {
  43912. if (!data) {
  43913. return false;
  43914. }
  43915. // Check for the ADTS sync word
  43916. // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
  43917. // Layer bits (position 14 and 15) in header should be always 0 for ADTS
  43918. // More info https://wiki.multimedia.cx/index.php?title=ADTS
  43919. var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_3__.getID3Data(data, 0) || [];
  43920. var offset = id3Data.length;
  43921. for (var length = data.length; offset < length; offset++) {
  43922. if (_adts__WEBPACK_IMPORTED_MODULE_1__.probe(data, offset)) {
  43923. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('ADTS sync word found !');
  43924. return true;
  43925. }
  43926. }
  43927. return false;
  43928. };
  43929. _proto.canParse = function canParse(data, offset) {
  43930. return _adts__WEBPACK_IMPORTED_MODULE_1__.canParse(data, offset);
  43931. };
  43932. _proto.appendFrame = function appendFrame(track, data, offset) {
  43933. _adts__WEBPACK_IMPORTED_MODULE_1__.initTrackConfig(track, this.observer, data, offset, track.manifestCodec);
  43934. var frame = _adts__WEBPACK_IMPORTED_MODULE_1__.appendFrame(track, data, offset, this.basePTS, this.frameIndex);
  43935. if (frame && frame.missing === 0) {
  43936. return frame;
  43937. }
  43938. };
  43939. return AACDemuxer;
  43940. }(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]);
  43941. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AACDemuxer);
  43942. /***/ }),
  43943. /***/ "./src/demux/adts.ts":
  43944. /*!***************************!*\
  43945. !*** ./src/demux/adts.ts ***!
  43946. \***************************/
  43947. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  43948. "use strict";
  43949. __webpack_require__.r(__webpack_exports__);
  43950. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  43951. /* harmony export */ "appendFrame": () => (/* binding */ appendFrame),
  43952. /* harmony export */ "canGetFrameLength": () => (/* binding */ canGetFrameLength),
  43953. /* harmony export */ "canParse": () => (/* binding */ canParse),
  43954. /* harmony export */ "getAudioConfig": () => (/* binding */ getAudioConfig),
  43955. /* harmony export */ "getFrameDuration": () => (/* binding */ getFrameDuration),
  43956. /* harmony export */ "getFullFrameLength": () => (/* binding */ getFullFrameLength),
  43957. /* harmony export */ "getHeaderLength": () => (/* binding */ getHeaderLength),
  43958. /* harmony export */ "initTrackConfig": () => (/* binding */ initTrackConfig),
  43959. /* harmony export */ "isHeader": () => (/* binding */ isHeader),
  43960. /* harmony export */ "isHeaderPattern": () => (/* binding */ isHeaderPattern),
  43961. /* harmony export */ "parseFrameHeader": () => (/* binding */ parseFrameHeader),
  43962. /* harmony export */ "probe": () => (/* binding */ probe)
  43963. /* harmony export */ });
  43964. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  43965. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  43966. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  43967. /**
  43968. * ADTS parser helper
  43969. * @link https://wiki.multimedia.cx/index.php?title=ADTS
  43970. */
  43971. function getAudioConfig(observer, data, offset, audioCodec) {
  43972. var adtsObjectType;
  43973. var adtsExtensionSamplingIndex;
  43974. var adtsChannelConfig;
  43975. var config;
  43976. var userAgent = navigator.userAgent.toLowerCase();
  43977. var manifestCodec = audioCodec;
  43978. var adtsSamplingRates = [96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350];
  43979. // byte 2
  43980. adtsObjectType = ((data[offset + 2] & 0xc0) >>> 6) + 1;
  43981. var adtsSamplingIndex = (data[offset + 2] & 0x3c) >>> 2;
  43982. if (adtsSamplingIndex > adtsSamplingRates.length - 1) {
  43983. observer.trigger(_events__WEBPACK_IMPORTED_MODULE_2__.Events.ERROR, {
  43984. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  43985. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_PARSING_ERROR,
  43986. fatal: true,
  43987. reason: "invalid ADTS sampling index:" + adtsSamplingIndex
  43988. });
  43989. return;
  43990. }
  43991. adtsChannelConfig = (data[offset + 2] & 0x01) << 2;
  43992. // byte 3
  43993. adtsChannelConfig |= (data[offset + 3] & 0xc0) >>> 6;
  43994. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log("manifest codec:" + audioCodec + ", ADTS type:" + adtsObjectType + ", samplingIndex:" + adtsSamplingIndex);
  43995. // firefox: freq less than 24kHz = AAC SBR (HE-AAC)
  43996. if (/firefox/i.test(userAgent)) {
  43997. if (adtsSamplingIndex >= 6) {
  43998. adtsObjectType = 5;
  43999. config = new Array(4);
  44000. // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
  44001. // there is a factor 2 between frame sample rate and output sample rate
  44002. // multiply frequency by 2 (see table below, equivalent to substract 3)
  44003. adtsExtensionSamplingIndex = adtsSamplingIndex - 3;
  44004. } else {
  44005. adtsObjectType = 2;
  44006. config = new Array(2);
  44007. adtsExtensionSamplingIndex = adtsSamplingIndex;
  44008. }
  44009. // Android : always use AAC
  44010. } else if (userAgent.indexOf('android') !== -1) {
  44011. adtsObjectType = 2;
  44012. config = new Array(2);
  44013. adtsExtensionSamplingIndex = adtsSamplingIndex;
  44014. } else {
  44015. /* for other browsers (Chrome/Vivaldi/Opera ...)
  44016. always force audio type to be HE-AAC SBR, as some browsers do not support audio codec switch properly (like Chrome ...)
  44017. */
  44018. adtsObjectType = 5;
  44019. config = new Array(4);
  44020. // if (manifest codec is HE-AAC or HE-AACv2) OR (manifest codec not specified AND frequency less than 24kHz)
  44021. if (audioCodec && (audioCodec.indexOf('mp4a.40.29') !== -1 || audioCodec.indexOf('mp4a.40.5') !== -1) || !audioCodec && adtsSamplingIndex >= 6) {
  44022. // HE-AAC uses SBR (Spectral Band Replication) , high frequencies are constructed from low frequencies
  44023. // there is a factor 2 between frame sample rate and output sample rate
  44024. // multiply frequency by 2 (see table below, equivalent to substract 3)
  44025. adtsExtensionSamplingIndex = adtsSamplingIndex - 3;
  44026. } else {
  44027. // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
  44028. // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo.
  44029. if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSamplingIndex >= 6 && adtsChannelConfig === 1 || /vivaldi/i.test(userAgent)) || !audioCodec && adtsChannelConfig === 1) {
  44030. adtsObjectType = 2;
  44031. config = new Array(2);
  44032. }
  44033. adtsExtensionSamplingIndex = adtsSamplingIndex;
  44034. }
  44035. }
  44036. /* refer to http://wiki.multimedia.cx/index.php?title=MPEG-4_Audio#Audio_Specific_Config
  44037. ISO 14496-3 (AAC).pdf - Table 1.13 — Syntax of AudioSpecificConfig()
  44038. Audio Profile / Audio Object Type
  44039. 0: Null
  44040. 1: AAC Main
  44041. 2: AAC LC (Low Complexity)
  44042. 3: AAC SSR (Scalable Sample Rate)
  44043. 4: AAC LTP (Long Term Prediction)
  44044. 5: SBR (Spectral Band Replication)
  44045. 6: AAC Scalable
  44046. sampling freq
  44047. 0: 96000 Hz
  44048. 1: 88200 Hz
  44049. 2: 64000 Hz
  44050. 3: 48000 Hz
  44051. 4: 44100 Hz
  44052. 5: 32000 Hz
  44053. 6: 24000 Hz
  44054. 7: 22050 Hz
  44055. 8: 16000 Hz
  44056. 9: 12000 Hz
  44057. 10: 11025 Hz
  44058. 11: 8000 Hz
  44059. 12: 7350 Hz
  44060. 13: Reserved
  44061. 14: Reserved
  44062. 15: frequency is written explictly
  44063. Channel Configurations
  44064. These are the channel configurations:
  44065. 0: Defined in AOT Specifc Config
  44066. 1: 1 channel: front-center
  44067. 2: 2 channels: front-left, front-right
  44068. */
  44069. // audioObjectType = profile => profile, the MPEG-4 Audio Object Type minus 1
  44070. config[0] = adtsObjectType << 3;
  44071. // samplingFrequencyIndex
  44072. config[0] |= (adtsSamplingIndex & 0x0e) >> 1;
  44073. config[1] |= (adtsSamplingIndex & 0x01) << 7;
  44074. // channelConfiguration
  44075. config[1] |= adtsChannelConfig << 3;
  44076. if (adtsObjectType === 5) {
  44077. // adtsExtensionSamplingIndex
  44078. config[1] |= (adtsExtensionSamplingIndex & 0x0e) >> 1;
  44079. config[2] = (adtsExtensionSamplingIndex & 0x01) << 7;
  44080. // adtsObjectType (force to 2, chrome is checking that object type is less than 5 ???
  44081. // https://chromium.googlesource.com/chromium/src.git/+/master/media/formats/mp4/aac.cc
  44082. config[2] |= 2 << 2;
  44083. config[3] = 0;
  44084. }
  44085. return {
  44086. config: config,
  44087. samplerate: adtsSamplingRates[adtsSamplingIndex],
  44088. channelCount: adtsChannelConfig,
  44089. codec: 'mp4a.40.' + adtsObjectType,
  44090. manifestCodec: manifestCodec
  44091. };
  44092. }
  44093. function isHeaderPattern(data, offset) {
  44094. return data[offset] === 0xff && (data[offset + 1] & 0xf6) === 0xf0;
  44095. }
  44096. function getHeaderLength(data, offset) {
  44097. return data[offset + 1] & 0x01 ? 7 : 9;
  44098. }
  44099. function getFullFrameLength(data, offset) {
  44100. return (data[offset + 3] & 0x03) << 11 | data[offset + 4] << 3 | (data[offset + 5] & 0xe0) >>> 5;
  44101. }
  44102. function canGetFrameLength(data, offset) {
  44103. return offset + 5 < data.length;
  44104. }
  44105. function isHeader(data, offset) {
  44106. // Look for ADTS header | 1111 1111 | 1111 X00X | where X can be either 0 or 1
  44107. // Layer bits (position 14 and 15) in header should be always 0 for ADTS
  44108. // More info https://wiki.multimedia.cx/index.php?title=ADTS
  44109. return offset + 1 < data.length && isHeaderPattern(data, offset);
  44110. }
  44111. function canParse(data, offset) {
  44112. return canGetFrameLength(data, offset) && isHeaderPattern(data, offset) && getFullFrameLength(data, offset) <= data.length - offset;
  44113. }
  44114. function probe(data, offset) {
  44115. // same as isHeader but we also check that ADTS frame follows last ADTS frame
  44116. // or end of data is reached
  44117. if (isHeader(data, offset)) {
  44118. // ADTS header Length
  44119. var headerLength = getHeaderLength(data, offset);
  44120. if (offset + headerLength >= data.length) {
  44121. return false;
  44122. }
  44123. // ADTS frame Length
  44124. var frameLength = getFullFrameLength(data, offset);
  44125. if (frameLength <= headerLength) {
  44126. return false;
  44127. }
  44128. var newOffset = offset + frameLength;
  44129. return newOffset === data.length || isHeader(data, newOffset);
  44130. }
  44131. return false;
  44132. }
  44133. function initTrackConfig(track, observer, data, offset, audioCodec) {
  44134. if (!track.samplerate) {
  44135. var config = getAudioConfig(observer, data, offset, audioCodec);
  44136. if (!config) {
  44137. return;
  44138. }
  44139. track.config = config.config;
  44140. track.samplerate = config.samplerate;
  44141. track.channelCount = config.channelCount;
  44142. track.codec = config.codec;
  44143. track.manifestCodec = config.manifestCodec;
  44144. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log("parsed codec:" + track.codec + ", rate:" + config.samplerate + ", channels:" + config.channelCount);
  44145. }
  44146. }
  44147. function getFrameDuration(samplerate) {
  44148. return 1024 * 90000 / samplerate;
  44149. }
  44150. function parseFrameHeader(data, offset) {
  44151. // The protection skip bit tells us if we have 2 bytes of CRC data at the end of the ADTS header
  44152. var headerLength = getHeaderLength(data, offset);
  44153. if (offset + headerLength <= data.length) {
  44154. // retrieve frame size
  44155. var frameLength = getFullFrameLength(data, offset) - headerLength;
  44156. if (frameLength > 0) {
  44157. // logger.log(`AAC frame, offset/length/total/pts:${offset+headerLength}/${frameLength}/${data.byteLength}`);
  44158. return {
  44159. headerLength: headerLength,
  44160. frameLength: frameLength
  44161. };
  44162. }
  44163. }
  44164. }
  44165. function appendFrame(track, data, offset, pts, frameIndex) {
  44166. var frameDuration = getFrameDuration(track.samplerate);
  44167. var stamp = pts + frameIndex * frameDuration;
  44168. var header = parseFrameHeader(data, offset);
  44169. var unit;
  44170. if (header) {
  44171. var frameLength = header.frameLength,
  44172. headerLength = header.headerLength;
  44173. var _length = headerLength + frameLength;
  44174. var missing = Math.max(0, offset + _length - data.length);
  44175. // logger.log(`AAC frame ${frameIndex}, pts:${stamp} length@offset/total: ${frameLength}@${offset+headerLength}/${data.byteLength} missing: ${missing}`);
  44176. if (missing) {
  44177. unit = new Uint8Array(_length - headerLength);
  44178. unit.set(data.subarray(offset + headerLength, data.length), 0);
  44179. } else {
  44180. unit = data.subarray(offset + headerLength, offset + _length);
  44181. }
  44182. var _sample = {
  44183. unit: unit,
  44184. pts: stamp
  44185. };
  44186. if (!missing) {
  44187. track.samples.push(_sample);
  44188. }
  44189. return {
  44190. sample: _sample,
  44191. length: _length,
  44192. missing: missing
  44193. };
  44194. }
  44195. // overflow incomplete header
  44196. var length = data.length - offset;
  44197. unit = new Uint8Array(length);
  44198. unit.set(data.subarray(offset, data.length), 0);
  44199. var sample = {
  44200. unit: unit,
  44201. pts: stamp
  44202. };
  44203. return {
  44204. sample: sample,
  44205. length: length,
  44206. missing: -1
  44207. };
  44208. }
  44209. /***/ }),
  44210. /***/ "./src/demux/base-audio-demuxer.ts":
  44211. /*!*****************************************!*\
  44212. !*** ./src/demux/base-audio-demuxer.ts ***!
  44213. \*****************************************/
  44214. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  44215. "use strict";
  44216. __webpack_require__.r(__webpack_exports__);
  44217. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  44218. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
  44219. /* harmony export */ "initPTSFn": () => (/* binding */ initPTSFn)
  44220. /* harmony export */ });
  44221. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  44222. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  44223. /* harmony import */ var _types_demuxer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../types/demuxer */ "./src/types/demuxer.ts");
  44224. /* harmony import */ var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./dummy-demuxed-track */ "./src/demux/dummy-demuxed-track.ts");
  44225. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  44226. /* harmony import */ var _utils_typed_array__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/typed-array */ "./src/utils/typed-array.ts");
  44227. var BaseAudioDemuxer = /*#__PURE__*/function () {
  44228. function BaseAudioDemuxer() {
  44229. this._audioTrack = void 0;
  44230. this._id3Track = void 0;
  44231. this.frameIndex = 0;
  44232. this.cachedData = null;
  44233. this.basePTS = null;
  44234. this.initPTS = null;
  44235. this.lastPTS = null;
  44236. }
  44237. var _proto = BaseAudioDemuxer.prototype;
  44238. _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration) {
  44239. this._id3Track = {
  44240. type: 'id3',
  44241. id: 3,
  44242. pid: -1,
  44243. inputTimeScale: 90000,
  44244. sequenceNumber: 0,
  44245. samples: [],
  44246. dropped: 0
  44247. };
  44248. };
  44249. _proto.resetTimeStamp = function resetTimeStamp(deaultTimestamp) {
  44250. this.initPTS = deaultTimestamp;
  44251. this.resetContiguity();
  44252. };
  44253. _proto.resetContiguity = function resetContiguity() {
  44254. this.basePTS = null;
  44255. this.lastPTS = null;
  44256. this.frameIndex = 0;
  44257. };
  44258. _proto.canParse = function canParse(data, offset) {
  44259. return false;
  44260. };
  44261. _proto.appendFrame = function appendFrame(track, data, offset) {}
  44262. // feed incoming data to the front of the parsing pipeline
  44263. ;
  44264. _proto.demux = function demux(data, timeOffset) {
  44265. if (this.cachedData) {
  44266. data = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__.appendUint8Array)(this.cachedData, data);
  44267. this.cachedData = null;
  44268. }
  44269. var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__.getID3Data(data, 0);
  44270. var offset = id3Data ? id3Data.length : 0;
  44271. var lastDataIndex;
  44272. var track = this._audioTrack;
  44273. var id3Track = this._id3Track;
  44274. var timestamp = id3Data ? _demux_id3__WEBPACK_IMPORTED_MODULE_1__.getTimeStamp(id3Data) : undefined;
  44275. var length = data.length;
  44276. if (this.basePTS === null || this.frameIndex === 0 && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(timestamp)) {
  44277. this.basePTS = initPTSFn(timestamp, timeOffset, this.initPTS);
  44278. this.lastPTS = this.basePTS;
  44279. }
  44280. if (this.lastPTS === null) {
  44281. this.lastPTS = this.basePTS;
  44282. }
  44283. // more expressive than alternative: id3Data?.length
  44284. if (id3Data && id3Data.length > 0) {
  44285. id3Track.samples.push({
  44286. pts: this.lastPTS,
  44287. dts: this.lastPTS,
  44288. data: id3Data,
  44289. type: _types_demuxer__WEBPACK_IMPORTED_MODULE_2__.MetadataSchema.audioId3,
  44290. duration: Number.POSITIVE_INFINITY
  44291. });
  44292. }
  44293. while (offset < length) {
  44294. if (this.canParse(data, offset)) {
  44295. var frame = this.appendFrame(track, data, offset);
  44296. if (frame) {
  44297. this.frameIndex++;
  44298. this.lastPTS = frame.sample.pts;
  44299. offset += frame.length;
  44300. lastDataIndex = offset;
  44301. } else {
  44302. offset = length;
  44303. }
  44304. } else if (_demux_id3__WEBPACK_IMPORTED_MODULE_1__.canParse(data, offset)) {
  44305. // after a ID3.canParse, a call to ID3.getID3Data *should* always returns some data
  44306. id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__.getID3Data(data, offset);
  44307. id3Track.samples.push({
  44308. pts: this.lastPTS,
  44309. dts: this.lastPTS,
  44310. data: id3Data,
  44311. type: _types_demuxer__WEBPACK_IMPORTED_MODULE_2__.MetadataSchema.audioId3,
  44312. duration: Number.POSITIVE_INFINITY
  44313. });
  44314. offset += id3Data.length;
  44315. lastDataIndex = offset;
  44316. } else {
  44317. offset++;
  44318. }
  44319. if (offset === length && lastDataIndex !== length) {
  44320. var partialData = (0,_utils_typed_array__WEBPACK_IMPORTED_MODULE_5__.sliceUint8)(data, lastDataIndex);
  44321. if (this.cachedData) {
  44322. this.cachedData = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_4__.appendUint8Array)(this.cachedData, partialData);
  44323. } else {
  44324. this.cachedData = partialData;
  44325. }
  44326. }
  44327. }
  44328. return {
  44329. audioTrack: track,
  44330. videoTrack: (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)(),
  44331. id3Track: id3Track,
  44332. textTrack: (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)()
  44333. };
  44334. };
  44335. _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) {
  44336. return Promise.reject(new Error("[" + this + "] This demuxer does not support Sample-AES decryption"));
  44337. };
  44338. _proto.flush = function flush(timeOffset) {
  44339. // Parse cache in case of remaining frames.
  44340. var cachedData = this.cachedData;
  44341. if (cachedData) {
  44342. this.cachedData = null;
  44343. this.demux(cachedData, 0);
  44344. }
  44345. return {
  44346. audioTrack: this._audioTrack,
  44347. videoTrack: (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)(),
  44348. id3Track: this._id3Track,
  44349. textTrack: (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)()
  44350. };
  44351. };
  44352. _proto.destroy = function destroy() {};
  44353. return BaseAudioDemuxer;
  44354. }();
  44355. /**
  44356. * Initialize PTS
  44357. * <p>
  44358. * use timestamp unless it is undefined, NaN or Infinity
  44359. * </p>
  44360. */
  44361. var initPTSFn = function initPTSFn(timestamp, timeOffset, initPTS) {
  44362. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(timestamp)) {
  44363. return timestamp * 90;
  44364. }
  44365. return timeOffset * 90000 + (initPTS || 0);
  44366. };
  44367. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BaseAudioDemuxer);
  44368. /***/ }),
  44369. /***/ "./src/demux/chunk-cache.ts":
  44370. /*!**********************************!*\
  44371. !*** ./src/demux/chunk-cache.ts ***!
  44372. \**********************************/
  44373. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  44374. "use strict";
  44375. __webpack_require__.r(__webpack_exports__);
  44376. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  44377. /* harmony export */ "default": () => (/* binding */ ChunkCache)
  44378. /* harmony export */ });
  44379. var ChunkCache = /*#__PURE__*/function () {
  44380. function ChunkCache() {
  44381. this.chunks = [];
  44382. this.dataLength = 0;
  44383. }
  44384. var _proto = ChunkCache.prototype;
  44385. _proto.push = function push(chunk) {
  44386. this.chunks.push(chunk);
  44387. this.dataLength += chunk.length;
  44388. };
  44389. _proto.flush = function flush() {
  44390. var chunks = this.chunks,
  44391. dataLength = this.dataLength;
  44392. var result;
  44393. if (!chunks.length) {
  44394. return new Uint8Array(0);
  44395. } else if (chunks.length === 1) {
  44396. result = chunks[0];
  44397. } else {
  44398. result = concatUint8Arrays(chunks, dataLength);
  44399. }
  44400. this.reset();
  44401. return result;
  44402. };
  44403. _proto.reset = function reset() {
  44404. this.chunks.length = 0;
  44405. this.dataLength = 0;
  44406. };
  44407. return ChunkCache;
  44408. }();
  44409. function concatUint8Arrays(chunks, dataLength) {
  44410. var result = new Uint8Array(dataLength);
  44411. var offset = 0;
  44412. for (var i = 0; i < chunks.length; i++) {
  44413. var chunk = chunks[i];
  44414. result.set(chunk, offset);
  44415. offset += chunk.length;
  44416. }
  44417. return result;
  44418. }
  44419. /***/ }),
  44420. /***/ "./src/demux/dummy-demuxed-track.ts":
  44421. /*!******************************************!*\
  44422. !*** ./src/demux/dummy-demuxed-track.ts ***!
  44423. \******************************************/
  44424. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  44425. "use strict";
  44426. __webpack_require__.r(__webpack_exports__);
  44427. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  44428. /* harmony export */ "dummyTrack": () => (/* binding */ dummyTrack)
  44429. /* harmony export */ });
  44430. function dummyTrack(type, inputTimeScale) {
  44431. if (type === void 0) {
  44432. type = '';
  44433. }
  44434. if (inputTimeScale === void 0) {
  44435. inputTimeScale = 90000;
  44436. }
  44437. return {
  44438. type: type,
  44439. id: -1,
  44440. pid: -1,
  44441. inputTimeScale: inputTimeScale,
  44442. sequenceNumber: -1,
  44443. samples: [],
  44444. dropped: 0
  44445. };
  44446. }
  44447. /***/ }),
  44448. /***/ "./src/demux/exp-golomb.ts":
  44449. /*!*********************************!*\
  44450. !*** ./src/demux/exp-golomb.ts ***!
  44451. \*********************************/
  44452. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  44453. "use strict";
  44454. __webpack_require__.r(__webpack_exports__);
  44455. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  44456. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  44457. /* harmony export */ });
  44458. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  44459. /**
  44460. * Parser for exponential Golomb codes, a variable-bitwidth number encoding scheme used by h264.
  44461. */
  44462. var ExpGolomb = /*#__PURE__*/function () {
  44463. function ExpGolomb(data) {
  44464. this.data = void 0;
  44465. this.bytesAvailable = void 0;
  44466. this.word = void 0;
  44467. this.bitsAvailable = void 0;
  44468. this.data = data;
  44469. // the number of bytes left to examine in this.data
  44470. this.bytesAvailable = data.byteLength;
  44471. // the current word being examined
  44472. this.word = 0; // :uint
  44473. // the number of bits left to examine in the current word
  44474. this.bitsAvailable = 0; // :uint
  44475. }
  44476. // ():void
  44477. var _proto = ExpGolomb.prototype;
  44478. _proto.loadWord = function loadWord() {
  44479. var data = this.data;
  44480. var bytesAvailable = this.bytesAvailable;
  44481. var position = data.byteLength - bytesAvailable;
  44482. var workingBytes = new Uint8Array(4);
  44483. var availableBytes = Math.min(4, bytesAvailable);
  44484. if (availableBytes === 0) {
  44485. throw new Error('no bytes available');
  44486. }
  44487. workingBytes.set(data.subarray(position, position + availableBytes));
  44488. this.word = new DataView(workingBytes.buffer).getUint32(0);
  44489. // track the amount of this.data that has been processed
  44490. this.bitsAvailable = availableBytes * 8;
  44491. this.bytesAvailable -= availableBytes;
  44492. }
  44493. // (count:int):void
  44494. ;
  44495. _proto.skipBits = function skipBits(count) {
  44496. var skipBytes; // :int
  44497. count = Math.min(count, this.bytesAvailable * 8 + this.bitsAvailable);
  44498. if (this.bitsAvailable > count) {
  44499. this.word <<= count;
  44500. this.bitsAvailable -= count;
  44501. } else {
  44502. count -= this.bitsAvailable;
  44503. skipBytes = count >> 3;
  44504. count -= skipBytes << 3;
  44505. this.bytesAvailable -= skipBytes;
  44506. this.loadWord();
  44507. this.word <<= count;
  44508. this.bitsAvailable -= count;
  44509. }
  44510. }
  44511. // (size:int):uint
  44512. ;
  44513. _proto.readBits = function readBits(size) {
  44514. var bits = Math.min(this.bitsAvailable, size); // :uint
  44515. var valu = this.word >>> 32 - bits; // :uint
  44516. if (size > 32) {
  44517. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.error('Cannot read more than 32 bits at a time');
  44518. }
  44519. this.bitsAvailable -= bits;
  44520. if (this.bitsAvailable > 0) {
  44521. this.word <<= bits;
  44522. } else if (this.bytesAvailable > 0) {
  44523. this.loadWord();
  44524. } else {
  44525. throw new Error('no bits available');
  44526. }
  44527. bits = size - bits;
  44528. if (bits > 0 && this.bitsAvailable) {
  44529. return valu << bits | this.readBits(bits);
  44530. } else {
  44531. return valu;
  44532. }
  44533. }
  44534. // ():uint
  44535. ;
  44536. _proto.skipLZ = function skipLZ() {
  44537. var leadingZeroCount; // :uint
  44538. for (leadingZeroCount = 0; leadingZeroCount < this.bitsAvailable; ++leadingZeroCount) {
  44539. if ((this.word & 0x80000000 >>> leadingZeroCount) !== 0) {
  44540. // the first bit of working word is 1
  44541. this.word <<= leadingZeroCount;
  44542. this.bitsAvailable -= leadingZeroCount;
  44543. return leadingZeroCount;
  44544. }
  44545. }
  44546. // we exhausted word and still have not found a 1
  44547. this.loadWord();
  44548. return leadingZeroCount + this.skipLZ();
  44549. }
  44550. // ():void
  44551. ;
  44552. _proto.skipUEG = function skipUEG() {
  44553. this.skipBits(1 + this.skipLZ());
  44554. }
  44555. // ():void
  44556. ;
  44557. _proto.skipEG = function skipEG() {
  44558. this.skipBits(1 + this.skipLZ());
  44559. }
  44560. // ():uint
  44561. ;
  44562. _proto.readUEG = function readUEG() {
  44563. var clz = this.skipLZ(); // :uint
  44564. return this.readBits(clz + 1) - 1;
  44565. }
  44566. // ():int
  44567. ;
  44568. _proto.readEG = function readEG() {
  44569. var valu = this.readUEG(); // :int
  44570. if (0x01 & valu) {
  44571. // the number is odd if the low order bit is set
  44572. return 1 + valu >>> 1; // add 1 to make it even, and divide by 2
  44573. } else {
  44574. return -1 * (valu >>> 1); // divide by two then make it negative
  44575. }
  44576. }
  44577. // Some convenience functions
  44578. // :Boolean
  44579. ;
  44580. _proto.readBoolean = function readBoolean() {
  44581. return this.readBits(1) === 1;
  44582. }
  44583. // ():int
  44584. ;
  44585. _proto.readUByte = function readUByte() {
  44586. return this.readBits(8);
  44587. }
  44588. // ():int
  44589. ;
  44590. _proto.readUShort = function readUShort() {
  44591. return this.readBits(16);
  44592. }
  44593. // ():int
  44594. ;
  44595. _proto.readUInt = function readUInt() {
  44596. return this.readBits(32);
  44597. }
  44598. /**
  44599. * Advance the ExpGolomb decoder past a scaling list. The scaling
  44600. * list is optionally transmitted as part of a sequence parameter
  44601. * set and is not relevant to transmuxing.
  44602. * @param count the number of entries in this scaling list
  44603. * @see Recommendation ITU-T H.264, Section 7.3.2.1.1.1
  44604. */;
  44605. _proto.skipScalingList = function skipScalingList(count) {
  44606. var lastScale = 8;
  44607. var nextScale = 8;
  44608. var deltaScale;
  44609. for (var j = 0; j < count; j++) {
  44610. if (nextScale !== 0) {
  44611. deltaScale = this.readEG();
  44612. nextScale = (lastScale + deltaScale + 256) % 256;
  44613. }
  44614. lastScale = nextScale === 0 ? lastScale : nextScale;
  44615. }
  44616. }
  44617. /**
  44618. * Read a sequence parameter set and return some interesting video
  44619. * properties. A sequence parameter set is the H264 metadata that
  44620. * describes the properties of upcoming video frames.
  44621. * @param data {Uint8Array} the bytes of a sequence parameter set
  44622. * @return {object} an object with configuration parsed from the
  44623. * sequence parameter set, including the dimensions of the
  44624. * associated video frames.
  44625. */;
  44626. _proto.readSPS = function readSPS() {
  44627. var frameCropLeftOffset = 0;
  44628. var frameCropRightOffset = 0;
  44629. var frameCropTopOffset = 0;
  44630. var frameCropBottomOffset = 0;
  44631. var numRefFramesInPicOrderCntCycle;
  44632. var scalingListCount;
  44633. var i;
  44634. var readUByte = this.readUByte.bind(this);
  44635. var readBits = this.readBits.bind(this);
  44636. var readUEG = this.readUEG.bind(this);
  44637. var readBoolean = this.readBoolean.bind(this);
  44638. var skipBits = this.skipBits.bind(this);
  44639. var skipEG = this.skipEG.bind(this);
  44640. var skipUEG = this.skipUEG.bind(this);
  44641. var skipScalingList = this.skipScalingList.bind(this);
  44642. readUByte();
  44643. var profileIdc = readUByte(); // profile_idc
  44644. readBits(5); // profileCompat constraint_set[0-4]_flag, u(5)
  44645. skipBits(3); // reserved_zero_3bits u(3),
  44646. readUByte(); // level_idc u(8)
  44647. skipUEG(); // seq_parameter_set_id
  44648. // some profiles have more optional data we don't need
  44649. if (profileIdc === 100 || profileIdc === 110 || profileIdc === 122 || profileIdc === 244 || profileIdc === 44 || profileIdc === 83 || profileIdc === 86 || profileIdc === 118 || profileIdc === 128) {
  44650. var chromaFormatIdc = readUEG();
  44651. if (chromaFormatIdc === 3) {
  44652. skipBits(1);
  44653. } // separate_colour_plane_flag
  44654. skipUEG(); // bit_depth_luma_minus8
  44655. skipUEG(); // bit_depth_chroma_minus8
  44656. skipBits(1); // qpprime_y_zero_transform_bypass_flag
  44657. if (readBoolean()) {
  44658. // seq_scaling_matrix_present_flag
  44659. scalingListCount = chromaFormatIdc !== 3 ? 8 : 12;
  44660. for (i = 0; i < scalingListCount; i++) {
  44661. if (readBoolean()) {
  44662. // seq_scaling_list_present_flag[ i ]
  44663. if (i < 6) {
  44664. skipScalingList(16);
  44665. } else {
  44666. skipScalingList(64);
  44667. }
  44668. }
  44669. }
  44670. }
  44671. }
  44672. skipUEG(); // log2_max_frame_num_minus4
  44673. var picOrderCntType = readUEG();
  44674. if (picOrderCntType === 0) {
  44675. readUEG(); // log2_max_pic_order_cnt_lsb_minus4
  44676. } else if (picOrderCntType === 1) {
  44677. skipBits(1); // delta_pic_order_always_zero_flag
  44678. skipEG(); // offset_for_non_ref_pic
  44679. skipEG(); // offset_for_top_to_bottom_field
  44680. numRefFramesInPicOrderCntCycle = readUEG();
  44681. for (i = 0; i < numRefFramesInPicOrderCntCycle; i++) {
  44682. skipEG();
  44683. } // offset_for_ref_frame[ i ]
  44684. }
  44685. skipUEG(); // max_num_ref_frames
  44686. skipBits(1); // gaps_in_frame_num_value_allowed_flag
  44687. var picWidthInMbsMinus1 = readUEG();
  44688. var picHeightInMapUnitsMinus1 = readUEG();
  44689. var frameMbsOnlyFlag = readBits(1);
  44690. if (frameMbsOnlyFlag === 0) {
  44691. skipBits(1);
  44692. } // mb_adaptive_frame_field_flag
  44693. skipBits(1); // direct_8x8_inference_flag
  44694. if (readBoolean()) {
  44695. // frame_cropping_flag
  44696. frameCropLeftOffset = readUEG();
  44697. frameCropRightOffset = readUEG();
  44698. frameCropTopOffset = readUEG();
  44699. frameCropBottomOffset = readUEG();
  44700. }
  44701. var pixelRatio = [1, 1];
  44702. if (readBoolean()) {
  44703. // vui_parameters_present_flag
  44704. if (readBoolean()) {
  44705. // aspect_ratio_info_present_flag
  44706. var aspectRatioIdc = readUByte();
  44707. switch (aspectRatioIdc) {
  44708. case 1:
  44709. pixelRatio = [1, 1];
  44710. break;
  44711. case 2:
  44712. pixelRatio = [12, 11];
  44713. break;
  44714. case 3:
  44715. pixelRatio = [10, 11];
  44716. break;
  44717. case 4:
  44718. pixelRatio = [16, 11];
  44719. break;
  44720. case 5:
  44721. pixelRatio = [40, 33];
  44722. break;
  44723. case 6:
  44724. pixelRatio = [24, 11];
  44725. break;
  44726. case 7:
  44727. pixelRatio = [20, 11];
  44728. break;
  44729. case 8:
  44730. pixelRatio = [32, 11];
  44731. break;
  44732. case 9:
  44733. pixelRatio = [80, 33];
  44734. break;
  44735. case 10:
  44736. pixelRatio = [18, 11];
  44737. break;
  44738. case 11:
  44739. pixelRatio = [15, 11];
  44740. break;
  44741. case 12:
  44742. pixelRatio = [64, 33];
  44743. break;
  44744. case 13:
  44745. pixelRatio = [160, 99];
  44746. break;
  44747. case 14:
  44748. pixelRatio = [4, 3];
  44749. break;
  44750. case 15:
  44751. pixelRatio = [3, 2];
  44752. break;
  44753. case 16:
  44754. pixelRatio = [2, 1];
  44755. break;
  44756. case 255:
  44757. {
  44758. pixelRatio = [readUByte() << 8 | readUByte(), readUByte() << 8 | readUByte()];
  44759. break;
  44760. }
  44761. }
  44762. }
  44763. }
  44764. return {
  44765. width: Math.ceil((picWidthInMbsMinus1 + 1) * 16 - frameCropLeftOffset * 2 - frameCropRightOffset * 2),
  44766. height: (2 - frameMbsOnlyFlag) * (picHeightInMapUnitsMinus1 + 1) * 16 - (frameMbsOnlyFlag ? 2 : 4) * (frameCropTopOffset + frameCropBottomOffset),
  44767. pixelRatio: pixelRatio
  44768. };
  44769. };
  44770. _proto.readSliceType = function readSliceType() {
  44771. // skip NALu type
  44772. this.readUByte();
  44773. // discard first_mb_in_slice
  44774. this.readUEG();
  44775. // return slice_type
  44776. return this.readUEG();
  44777. };
  44778. return ExpGolomb;
  44779. }();
  44780. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ExpGolomb);
  44781. /***/ }),
  44782. /***/ "./src/demux/id3.ts":
  44783. /*!**************************!*\
  44784. !*** ./src/demux/id3.ts ***!
  44785. \**************************/
  44786. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  44787. "use strict";
  44788. __webpack_require__.r(__webpack_exports__);
  44789. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  44790. /* harmony export */ "canParse": () => (/* binding */ canParse),
  44791. /* harmony export */ "decodeFrame": () => (/* binding */ decodeFrame),
  44792. /* harmony export */ "getID3Data": () => (/* binding */ getID3Data),
  44793. /* harmony export */ "getID3Frames": () => (/* binding */ getID3Frames),
  44794. /* harmony export */ "getTimeStamp": () => (/* binding */ getTimeStamp),
  44795. /* harmony export */ "isFooter": () => (/* binding */ isFooter),
  44796. /* harmony export */ "isHeader": () => (/* binding */ isHeader),
  44797. /* harmony export */ "isTimeStampFrame": () => (/* binding */ isTimeStampFrame),
  44798. /* harmony export */ "testables": () => (/* binding */ testables),
  44799. /* harmony export */ "utf8ArrayToStr": () => (/* binding */ utf8ArrayToStr)
  44800. /* harmony export */ });
  44801. // breaking up those two types in order to clarify what is happening in the decoding path.
  44802. /**
  44803. * Returns true if an ID3 header can be found at offset in data
  44804. * @param {Uint8Array} data - The data to search in
  44805. * @param {number} offset - The offset at which to start searching
  44806. * @return {boolean} - True if an ID3 header is found
  44807. */
  44808. var isHeader = function isHeader(data, offset) {
  44809. /*
  44810. * http://id3.org/id3v2.3.0
  44811. * [0] = 'I'
  44812. * [1] = 'D'
  44813. * [2] = '3'
  44814. * [3,4] = {Version}
  44815. * [5] = {Flags}
  44816. * [6-9] = {ID3 Size}
  44817. *
  44818. * An ID3v2 tag can be detected with the following pattern:
  44819. * $49 44 33 yy yy xx zz zz zz zz
  44820. * Where yy is less than $FF, xx is the 'flags' byte and zz is less than $80
  44821. */
  44822. if (offset + 10 <= data.length) {
  44823. // look for 'ID3' identifier
  44824. if (data[offset] === 0x49 && data[offset + 1] === 0x44 && data[offset + 2] === 0x33) {
  44825. // check version is within range
  44826. if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {
  44827. // check size is within range
  44828. if (data[offset + 6] < 0x80 && data[offset + 7] < 0x80 && data[offset + 8] < 0x80 && data[offset + 9] < 0x80) {
  44829. return true;
  44830. }
  44831. }
  44832. }
  44833. }
  44834. return false;
  44835. };
  44836. /**
  44837. * Returns true if an ID3 footer can be found at offset in data
  44838. * @param {Uint8Array} data - The data to search in
  44839. * @param {number} offset - The offset at which to start searching
  44840. * @return {boolean} - True if an ID3 footer is found
  44841. */
  44842. var isFooter = function isFooter(data, offset) {
  44843. /*
  44844. * The footer is a copy of the header, but with a different identifier
  44845. */
  44846. if (offset + 10 <= data.length) {
  44847. // look for '3DI' identifier
  44848. if (data[offset] === 0x33 && data[offset + 1] === 0x44 && data[offset + 2] === 0x49) {
  44849. // check version is within range
  44850. if (data[offset + 3] < 0xff && data[offset + 4] < 0xff) {
  44851. // check size is within range
  44852. if (data[offset + 6] < 0x80 && data[offset + 7] < 0x80 && data[offset + 8] < 0x80 && data[offset + 9] < 0x80) {
  44853. return true;
  44854. }
  44855. }
  44856. }
  44857. }
  44858. return false;
  44859. };
  44860. /**
  44861. * Returns any adjacent ID3 tags found in data starting at offset, as one block of data
  44862. * @param {Uint8Array} data - The data to search in
  44863. * @param {number} offset - The offset at which to start searching
  44864. * @return {Uint8Array | undefined} - The block of data containing any ID3 tags found
  44865. * or *undefined* if no header is found at the starting offset
  44866. */
  44867. var getID3Data = function getID3Data(data, offset) {
  44868. var front = offset;
  44869. var length = 0;
  44870. while (isHeader(data, offset)) {
  44871. // ID3 header is 10 bytes
  44872. length += 10;
  44873. var size = readSize(data, offset + 6);
  44874. length += size;
  44875. if (isFooter(data, offset + 10)) {
  44876. // ID3 footer is 10 bytes
  44877. length += 10;
  44878. }
  44879. offset += length;
  44880. }
  44881. if (length > 0) {
  44882. return data.subarray(front, front + length);
  44883. }
  44884. return undefined;
  44885. };
  44886. var readSize = function readSize(data, offset) {
  44887. var size = 0;
  44888. size = (data[offset] & 0x7f) << 21;
  44889. size |= (data[offset + 1] & 0x7f) << 14;
  44890. size |= (data[offset + 2] & 0x7f) << 7;
  44891. size |= data[offset + 3] & 0x7f;
  44892. return size;
  44893. };
  44894. var canParse = function canParse(data, offset) {
  44895. return isHeader(data, offset) && readSize(data, offset + 6) + 10 <= data.length - offset;
  44896. };
  44897. /**
  44898. * Searches for the Elementary Stream timestamp found in the ID3 data chunk
  44899. * @param {Uint8Array} data - Block of data containing one or more ID3 tags
  44900. * @return {number | undefined} - The timestamp
  44901. */
  44902. var getTimeStamp = function getTimeStamp(data) {
  44903. var frames = getID3Frames(data);
  44904. for (var i = 0; i < frames.length; i++) {
  44905. var frame = frames[i];
  44906. if (isTimeStampFrame(frame)) {
  44907. return readTimeStamp(frame);
  44908. }
  44909. }
  44910. return undefined;
  44911. };
  44912. /**
  44913. * Returns true if the ID3 frame is an Elementary Stream timestamp frame
  44914. * @param {ID3 frame} frame
  44915. */
  44916. var isTimeStampFrame = function isTimeStampFrame(frame) {
  44917. return frame && frame.key === 'PRIV' && frame.info === 'com.apple.streaming.transportStreamTimestamp';
  44918. };
  44919. var getFrameData = function getFrameData(data) {
  44920. /*
  44921. Frame ID $xx xx xx xx (four characters)
  44922. Size $xx xx xx xx
  44923. Flags $xx xx
  44924. */
  44925. var type = String.fromCharCode(data[0], data[1], data[2], data[3]);
  44926. var size = readSize(data, 4);
  44927. // skip frame id, size, and flags
  44928. var offset = 10;
  44929. return {
  44930. type: type,
  44931. size: size,
  44932. data: data.subarray(offset, offset + size)
  44933. };
  44934. };
  44935. /**
  44936. * Returns an array of ID3 frames found in all the ID3 tags in the id3Data
  44937. * @param {Uint8Array} id3Data - The ID3 data containing one or more ID3 tags
  44938. * @return {ID3.Frame[]} - Array of ID3 frame objects
  44939. */
  44940. var getID3Frames = function getID3Frames(id3Data) {
  44941. var offset = 0;
  44942. var frames = [];
  44943. while (isHeader(id3Data, offset)) {
  44944. var size = readSize(id3Data, offset + 6);
  44945. // skip past ID3 header
  44946. offset += 10;
  44947. var end = offset + size;
  44948. // loop through frames in the ID3 tag
  44949. while (offset + 8 < end) {
  44950. var frameData = getFrameData(id3Data.subarray(offset));
  44951. var frame = decodeFrame(frameData);
  44952. if (frame) {
  44953. frames.push(frame);
  44954. }
  44955. // skip frame header and frame data
  44956. offset += frameData.size + 10;
  44957. }
  44958. if (isFooter(id3Data, offset)) {
  44959. offset += 10;
  44960. }
  44961. }
  44962. return frames;
  44963. };
  44964. var decodeFrame = function decodeFrame(frame) {
  44965. if (frame.type === 'PRIV') {
  44966. return decodePrivFrame(frame);
  44967. } else if (frame.type[0] === 'W') {
  44968. return decodeURLFrame(frame);
  44969. }
  44970. return decodeTextFrame(frame);
  44971. };
  44972. var decodePrivFrame = function decodePrivFrame(frame) {
  44973. /*
  44974. Format: <text string>\0<binary data>
  44975. */
  44976. if (frame.size < 2) {
  44977. return undefined;
  44978. }
  44979. var owner = utf8ArrayToStr(frame.data, true);
  44980. var privateData = new Uint8Array(frame.data.subarray(owner.length + 1));
  44981. return {
  44982. key: frame.type,
  44983. info: owner,
  44984. data: privateData.buffer
  44985. };
  44986. };
  44987. var decodeTextFrame = function decodeTextFrame(frame) {
  44988. if (frame.size < 2) {
  44989. return undefined;
  44990. }
  44991. if (frame.type === 'TXXX') {
  44992. /*
  44993. Format:
  44994. [0] = {Text Encoding}
  44995. [1-?] = {Description}\0{Value}
  44996. */
  44997. var index = 1;
  44998. var description = utf8ArrayToStr(frame.data.subarray(index), true);
  44999. index += description.length + 1;
  45000. var value = utf8ArrayToStr(frame.data.subarray(index));
  45001. return {
  45002. key: frame.type,
  45003. info: description,
  45004. data: value
  45005. };
  45006. }
  45007. /*
  45008. Format:
  45009. [0] = {Text Encoding}
  45010. [1-?] = {Value}
  45011. */
  45012. var text = utf8ArrayToStr(frame.data.subarray(1));
  45013. return {
  45014. key: frame.type,
  45015. data: text
  45016. };
  45017. };
  45018. var decodeURLFrame = function decodeURLFrame(frame) {
  45019. if (frame.type === 'WXXX') {
  45020. /*
  45021. Format:
  45022. [0] = {Text Encoding}
  45023. [1-?] = {Description}\0{URL}
  45024. */
  45025. if (frame.size < 2) {
  45026. return undefined;
  45027. }
  45028. var index = 1;
  45029. var description = utf8ArrayToStr(frame.data.subarray(index), true);
  45030. index += description.length + 1;
  45031. var value = utf8ArrayToStr(frame.data.subarray(index));
  45032. return {
  45033. key: frame.type,
  45034. info: description,
  45035. data: value
  45036. };
  45037. }
  45038. /*
  45039. Format:
  45040. [0-?] = {URL}
  45041. */
  45042. var url = utf8ArrayToStr(frame.data);
  45043. return {
  45044. key: frame.type,
  45045. data: url
  45046. };
  45047. };
  45048. var readTimeStamp = function readTimeStamp(timeStampFrame) {
  45049. if (timeStampFrame.data.byteLength === 8) {
  45050. var data = new Uint8Array(timeStampFrame.data);
  45051. // timestamp is 33 bit expressed as a big-endian eight-octet number,
  45052. // with the upper 31 bits set to zero.
  45053. var pts33Bit = data[3] & 0x1;
  45054. var timestamp = (data[4] << 23) + (data[5] << 15) + (data[6] << 7) + data[7];
  45055. timestamp /= 45;
  45056. if (pts33Bit) {
  45057. timestamp += 47721858.84;
  45058. } // 2^32 / 90
  45059. return Math.round(timestamp);
  45060. }
  45061. return undefined;
  45062. };
  45063. // http://stackoverflow.com/questions/8936984/uint8array-to-string-in-javascript/22373197
  45064. // http://www.onicos.com/staff/iz/amuse/javascript/expert/utf.txt
  45065. /* utf.js - UTF-8 <=> UTF-16 convertion
  45066. *
  45067. * Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
  45068. * Version: 1.0
  45069. * LastModified: Dec 25 1999
  45070. * This library is free. You can redistribute it and/or modify it.
  45071. */
  45072. var utf8ArrayToStr = function utf8ArrayToStr(array, exitOnNull) {
  45073. if (exitOnNull === void 0) {
  45074. exitOnNull = false;
  45075. }
  45076. var decoder = getTextDecoder();
  45077. if (decoder) {
  45078. var decoded = decoder.decode(array);
  45079. if (exitOnNull) {
  45080. // grab up to the first null
  45081. var idx = decoded.indexOf('\0');
  45082. return idx !== -1 ? decoded.substring(0, idx) : decoded;
  45083. }
  45084. // remove any null characters
  45085. return decoded.replace(/\0/g, '');
  45086. }
  45087. var len = array.length;
  45088. var c;
  45089. var char2;
  45090. var char3;
  45091. var out = '';
  45092. var i = 0;
  45093. while (i < len) {
  45094. c = array[i++];
  45095. if (c === 0x00 && exitOnNull) {
  45096. return out;
  45097. } else if (c === 0x00 || c === 0x03) {
  45098. // If the character is 3 (END_OF_TEXT) or 0 (NULL) then skip it
  45099. continue;
  45100. }
  45101. switch (c >> 4) {
  45102. case 0:
  45103. case 1:
  45104. case 2:
  45105. case 3:
  45106. case 4:
  45107. case 5:
  45108. case 6:
  45109. case 7:
  45110. // 0xxxxxxx
  45111. out += String.fromCharCode(c);
  45112. break;
  45113. case 12:
  45114. case 13:
  45115. // 110x xxxx 10xx xxxx
  45116. char2 = array[i++];
  45117. out += String.fromCharCode((c & 0x1f) << 6 | char2 & 0x3f);
  45118. break;
  45119. case 14:
  45120. // 1110 xxxx 10xx xxxx 10xx xxxx
  45121. char2 = array[i++];
  45122. char3 = array[i++];
  45123. out += String.fromCharCode((c & 0x0f) << 12 | (char2 & 0x3f) << 6 | (char3 & 0x3f) << 0);
  45124. break;
  45125. default:
  45126. }
  45127. }
  45128. return out;
  45129. };
  45130. var testables = {
  45131. decodeTextFrame: decodeTextFrame
  45132. };
  45133. var decoder;
  45134. function getTextDecoder() {
  45135. if (!decoder && typeof self.TextDecoder !== 'undefined') {
  45136. decoder = new self.TextDecoder('utf-8');
  45137. }
  45138. return decoder;
  45139. }
  45140. /***/ }),
  45141. /***/ "./src/demux/mp3demuxer.ts":
  45142. /*!*********************************!*\
  45143. !*** ./src/demux/mp3demuxer.ts ***!
  45144. \*********************************/
  45145. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  45146. "use strict";
  45147. __webpack_require__.r(__webpack_exports__);
  45148. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  45149. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  45150. /* harmony export */ });
  45151. /* harmony import */ var _base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base-audio-demuxer */ "./src/demux/base-audio-demuxer.ts");
  45152. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  45153. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  45154. /* harmony import */ var _mpegaudio__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mpegaudio */ "./src/demux/mpegaudio.ts");
  45155. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  45156. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  45157. /**
  45158. * MP3 demuxer
  45159. */
  45160. var MP3Demuxer = /*#__PURE__*/function (_BaseAudioDemuxer) {
  45161. _inheritsLoose(MP3Demuxer, _BaseAudioDemuxer);
  45162. function MP3Demuxer() {
  45163. return _BaseAudioDemuxer.apply(this, arguments) || this;
  45164. }
  45165. var _proto = MP3Demuxer.prototype;
  45166. _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration) {
  45167. _BaseAudioDemuxer.prototype.resetInitSegment.call(this, initSegment, audioCodec, videoCodec, trackDuration);
  45168. this._audioTrack = {
  45169. container: 'audio/mpeg',
  45170. type: 'audio',
  45171. id: 2,
  45172. pid: -1,
  45173. sequenceNumber: 0,
  45174. segmentCodec: 'mp3',
  45175. samples: [],
  45176. manifestCodec: audioCodec,
  45177. duration: trackDuration,
  45178. inputTimeScale: 90000,
  45179. dropped: 0
  45180. };
  45181. };
  45182. MP3Demuxer.probe = function probe(data) {
  45183. if (!data) {
  45184. return false;
  45185. }
  45186. // check if data contains ID3 timestamp and MPEG sync word
  45187. // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
  45188. // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
  45189. // More info http://www.mp3-tech.org/programmer/frame_header.html
  45190. var id3Data = _demux_id3__WEBPACK_IMPORTED_MODULE_1__.getID3Data(data, 0) || [];
  45191. var offset = id3Data.length;
  45192. for (var length = data.length; offset < length; offset++) {
  45193. if (_mpegaudio__WEBPACK_IMPORTED_MODULE_3__.probe(data, offset)) {
  45194. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.log('MPEG Audio sync word found !');
  45195. return true;
  45196. }
  45197. }
  45198. return false;
  45199. };
  45200. _proto.canParse = function canParse(data, offset) {
  45201. return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__.canParse(data, offset);
  45202. };
  45203. _proto.appendFrame = function appendFrame(track, data, offset) {
  45204. if (this.basePTS === null) {
  45205. return;
  45206. }
  45207. return _mpegaudio__WEBPACK_IMPORTED_MODULE_3__.appendFrame(track, data, offset, this.basePTS, this.frameIndex);
  45208. };
  45209. return MP3Demuxer;
  45210. }(_base_audio_demuxer__WEBPACK_IMPORTED_MODULE_0__["default"]);
  45211. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MP3Demuxer);
  45212. /***/ }),
  45213. /***/ "./src/demux/mp4demuxer.ts":
  45214. /*!*********************************!*\
  45215. !*** ./src/demux/mp4demuxer.ts ***!
  45216. \*********************************/
  45217. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  45218. "use strict";
  45219. __webpack_require__.r(__webpack_exports__);
  45220. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  45221. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  45222. /* harmony export */ });
  45223. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  45224. /* harmony import */ var _types_demuxer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/demuxer */ "./src/types/demuxer.ts");
  45225. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  45226. /* harmony import */ var _dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./dummy-demuxed-track */ "./src/demux/dummy-demuxed-track.ts");
  45227. /**
  45228. * MP4 demuxer
  45229. */
  45230. var emsgSchemePattern = /\/emsg[-/]ID3/i;
  45231. var MP4Demuxer = /*#__PURE__*/function () {
  45232. function MP4Demuxer(observer, config) {
  45233. this.remainderData = null;
  45234. this.timeOffset = 0;
  45235. this.config = void 0;
  45236. this.videoTrack = void 0;
  45237. this.audioTrack = void 0;
  45238. this.id3Track = void 0;
  45239. this.txtTrack = void 0;
  45240. this.config = config;
  45241. }
  45242. var _proto = MP4Demuxer.prototype;
  45243. _proto.resetTimeStamp = function resetTimeStamp() {};
  45244. _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration) {
  45245. var videoTrack = this.videoTrack = (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('video', 1);
  45246. var audioTrack = this.audioTrack = (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('audio', 1);
  45247. var captionTrack = this.txtTrack = (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('text', 1);
  45248. this.id3Track = (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)('id3', 1);
  45249. this.timeOffset = 0;
  45250. if (!initSegment || !initSegment.byteLength) {
  45251. return;
  45252. }
  45253. var initData = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseInitSegment)(initSegment);
  45254. if (initData.video) {
  45255. var _initData$video = initData.video,
  45256. id = _initData$video.id,
  45257. timescale = _initData$video.timescale,
  45258. codec = _initData$video.codec;
  45259. videoTrack.id = id;
  45260. videoTrack.timescale = captionTrack.timescale = timescale;
  45261. videoTrack.codec = codec;
  45262. }
  45263. if (initData.audio) {
  45264. var _initData$audio = initData.audio,
  45265. _id = _initData$audio.id,
  45266. _timescale = _initData$audio.timescale,
  45267. _codec = _initData$audio.codec;
  45268. audioTrack.id = _id;
  45269. audioTrack.timescale = _timescale;
  45270. audioTrack.codec = _codec;
  45271. }
  45272. captionTrack.id = _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.RemuxerTrackIdConfig.text;
  45273. videoTrack.sampleDuration = 0;
  45274. videoTrack.duration = audioTrack.duration = trackDuration;
  45275. };
  45276. _proto.resetContiguity = function resetContiguity() {};
  45277. MP4Demuxer.probe = function probe(data) {
  45278. // ensure we find a moof box in the first 16 kB
  45279. data = data.length > 16384 ? data.subarray(0, 16384) : data;
  45280. return (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.findBox)(data, ['moof']).length > 0;
  45281. };
  45282. _proto.demux = function demux(data, timeOffset) {
  45283. this.timeOffset = timeOffset;
  45284. // Load all data into the avc track. The CMAF remuxer will look for the data in the samples object; the rest of the fields do not matter
  45285. var videoSamples = data;
  45286. var videoTrack = this.videoTrack;
  45287. var textTrack = this.txtTrack;
  45288. if (this.config.progressive) {
  45289. // Split the bytestream into two ranges: one encompassing all data up until the start of the last moof, and everything else.
  45290. // This is done to guarantee that we're sending valid data to MSE - when demuxing progressively, we have no guarantee
  45291. // that the fetch loader gives us flush moof+mdat pairs. If we push jagged data to MSE, it will throw an exception.
  45292. if (this.remainderData) {
  45293. videoSamples = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.appendUint8Array)(this.remainderData, data);
  45294. }
  45295. var segmentedData = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.segmentValidRange)(videoSamples);
  45296. this.remainderData = segmentedData.remainder;
  45297. videoTrack.samples = segmentedData.valid || new Uint8Array();
  45298. } else {
  45299. videoTrack.samples = videoSamples;
  45300. }
  45301. var id3Track = this.extractID3Track(videoTrack, timeOffset);
  45302. textTrack.samples = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseSamples)(timeOffset, videoTrack);
  45303. return {
  45304. videoTrack: videoTrack,
  45305. audioTrack: this.audioTrack,
  45306. id3Track: id3Track,
  45307. textTrack: this.txtTrack
  45308. };
  45309. };
  45310. _proto.flush = function flush() {
  45311. var timeOffset = this.timeOffset;
  45312. var videoTrack = this.videoTrack;
  45313. var textTrack = this.txtTrack;
  45314. videoTrack.samples = this.remainderData || new Uint8Array();
  45315. this.remainderData = null;
  45316. var id3Track = this.extractID3Track(videoTrack, this.timeOffset);
  45317. textTrack.samples = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseSamples)(timeOffset, videoTrack);
  45318. return {
  45319. videoTrack: videoTrack,
  45320. audioTrack: (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)(),
  45321. id3Track: id3Track,
  45322. textTrack: (0,_dummy_demuxed_track__WEBPACK_IMPORTED_MODULE_3__.dummyTrack)()
  45323. };
  45324. };
  45325. _proto.extractID3Track = function extractID3Track(videoTrack, timeOffset) {
  45326. var id3Track = this.id3Track;
  45327. if (videoTrack.samples.length) {
  45328. var emsgs = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.findBox)(videoTrack.samples, ['emsg']);
  45329. if (emsgs) {
  45330. emsgs.forEach(function (data) {
  45331. var emsgInfo = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseEmsg)(data);
  45332. if (emsgSchemePattern.test(emsgInfo.schemeIdUri)) {
  45333. var pts = (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(emsgInfo.presentationTime) ? emsgInfo.presentationTime / emsgInfo.timeScale : timeOffset + emsgInfo.presentationTimeDelta / emsgInfo.timeScale;
  45334. var duration = emsgInfo.eventDuration === 0xffffffff ? Number.POSITIVE_INFINITY : emsgInfo.eventDuration / emsgInfo.timeScale;
  45335. // Safari takes anything <= 0.001 seconds and maps it to Infinity
  45336. if (duration <= 0.001) {
  45337. duration = Number.POSITIVE_INFINITY;
  45338. }
  45339. var payload = emsgInfo.payload;
  45340. id3Track.samples.push({
  45341. data: payload,
  45342. len: payload.byteLength,
  45343. dts: pts,
  45344. pts: pts,
  45345. type: _types_demuxer__WEBPACK_IMPORTED_MODULE_1__.MetadataSchema.emsg,
  45346. duration: duration
  45347. });
  45348. }
  45349. });
  45350. }
  45351. }
  45352. return id3Track;
  45353. };
  45354. _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) {
  45355. return Promise.reject(new Error('The MP4 demuxer does not support SAMPLE-AES decryption'));
  45356. };
  45357. _proto.destroy = function destroy() {};
  45358. return MP4Demuxer;
  45359. }();
  45360. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MP4Demuxer);
  45361. /***/ }),
  45362. /***/ "./src/demux/mpegaudio.ts":
  45363. /*!********************************!*\
  45364. !*** ./src/demux/mpegaudio.ts ***!
  45365. \********************************/
  45366. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  45367. "use strict";
  45368. __webpack_require__.r(__webpack_exports__);
  45369. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  45370. /* harmony export */ "appendFrame": () => (/* binding */ appendFrame),
  45371. /* harmony export */ "canParse": () => (/* binding */ canParse),
  45372. /* harmony export */ "isHeader": () => (/* binding */ isHeader),
  45373. /* harmony export */ "isHeaderPattern": () => (/* binding */ isHeaderPattern),
  45374. /* harmony export */ "parseHeader": () => (/* binding */ parseHeader),
  45375. /* harmony export */ "probe": () => (/* binding */ probe)
  45376. /* harmony export */ });
  45377. /**
  45378. * MPEG parser helper
  45379. */
  45380. var chromeVersion = null;
  45381. var BitratesMap = [32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160];
  45382. var SamplingRateMap = [44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000];
  45383. var SamplesCoefficients = [
  45384. // MPEG 2.5
  45385. [0,
  45386. // Reserved
  45387. 72,
  45388. // Layer3
  45389. 144,
  45390. // Layer2
  45391. 12 // Layer1
  45392. ],
  45393. // Reserved
  45394. [0,
  45395. // Reserved
  45396. 0,
  45397. // Layer3
  45398. 0,
  45399. // Layer2
  45400. 0 // Layer1
  45401. ],
  45402. // MPEG 2
  45403. [0,
  45404. // Reserved
  45405. 72,
  45406. // Layer3
  45407. 144,
  45408. // Layer2
  45409. 12 // Layer1
  45410. ],
  45411. // MPEG 1
  45412. [0,
  45413. // Reserved
  45414. 144,
  45415. // Layer3
  45416. 144,
  45417. // Layer2
  45418. 12 // Layer1
  45419. ]];
  45420. var BytesInSlot = [0,
  45421. // Reserved
  45422. 1,
  45423. // Layer3
  45424. 1,
  45425. // Layer2
  45426. 4 // Layer1
  45427. ];
  45428. function appendFrame(track, data, offset, pts, frameIndex) {
  45429. // Using http://www.datavoyage.com/mpgscript/mpeghdr.htm as a reference
  45430. if (offset + 24 > data.length) {
  45431. return;
  45432. }
  45433. var header = parseHeader(data, offset);
  45434. if (header && offset + header.frameLength <= data.length) {
  45435. var frameDuration = header.samplesPerFrame * 90000 / header.sampleRate;
  45436. var stamp = pts + frameIndex * frameDuration;
  45437. var sample = {
  45438. unit: data.subarray(offset, offset + header.frameLength),
  45439. pts: stamp,
  45440. dts: stamp
  45441. };
  45442. track.config = [];
  45443. track.channelCount = header.channelCount;
  45444. track.samplerate = header.sampleRate;
  45445. track.samples.push(sample);
  45446. return {
  45447. sample: sample,
  45448. length: header.frameLength,
  45449. missing: 0
  45450. };
  45451. }
  45452. }
  45453. function parseHeader(data, offset) {
  45454. var mpegVersion = data[offset + 1] >> 3 & 3;
  45455. var mpegLayer = data[offset + 1] >> 1 & 3;
  45456. var bitRateIndex = data[offset + 2] >> 4 & 15;
  45457. var sampleRateIndex = data[offset + 2] >> 2 & 3;
  45458. if (mpegVersion !== 1 && bitRateIndex !== 0 && bitRateIndex !== 15 && sampleRateIndex !== 3) {
  45459. var paddingBit = data[offset + 2] >> 1 & 1;
  45460. var channelMode = data[offset + 3] >> 6;
  45461. var columnInBitrates = mpegVersion === 3 ? 3 - mpegLayer : mpegLayer === 3 ? 3 : 4;
  45462. var bitRate = BitratesMap[columnInBitrates * 14 + bitRateIndex - 1] * 1000;
  45463. var columnInSampleRates = mpegVersion === 3 ? 0 : mpegVersion === 2 ? 1 : 2;
  45464. var sampleRate = SamplingRateMap[columnInSampleRates * 3 + sampleRateIndex];
  45465. var channelCount = channelMode === 3 ? 1 : 2; // If bits of channel mode are `11` then it is a single channel (Mono)
  45466. var sampleCoefficient = SamplesCoefficients[mpegVersion][mpegLayer];
  45467. var bytesInSlot = BytesInSlot[mpegLayer];
  45468. var samplesPerFrame = sampleCoefficient * 8 * bytesInSlot;
  45469. var frameLength = Math.floor(sampleCoefficient * bitRate / sampleRate + paddingBit) * bytesInSlot;
  45470. if (chromeVersion === null) {
  45471. var userAgent = navigator.userAgent || '';
  45472. var result = userAgent.match(/Chrome\/(\d+)/i);
  45473. chromeVersion = result ? parseInt(result[1]) : 0;
  45474. }
  45475. var needChromeFix = !!chromeVersion && chromeVersion <= 87;
  45476. if (needChromeFix && mpegLayer === 2 && bitRate >= 224000 && channelMode === 0) {
  45477. // Work around bug in Chromium by setting channelMode to dual-channel (01) instead of stereo (00)
  45478. data[offset + 3] = data[offset + 3] | 0x80;
  45479. }
  45480. return {
  45481. sampleRate: sampleRate,
  45482. channelCount: channelCount,
  45483. frameLength: frameLength,
  45484. samplesPerFrame: samplesPerFrame
  45485. };
  45486. }
  45487. }
  45488. function isHeaderPattern(data, offset) {
  45489. return data[offset] === 0xff && (data[offset + 1] & 0xe0) === 0xe0 && (data[offset + 1] & 0x06) !== 0x00;
  45490. }
  45491. function isHeader(data, offset) {
  45492. // Look for MPEG header | 1111 1111 | 111X XYZX | where X can be either 0 or 1 and Y or Z should be 1
  45493. // Layer bits (position 14 and 15) in header should be always different from 0 (Layer I or Layer II or Layer III)
  45494. // More info http://www.mp3-tech.org/programmer/frame_header.html
  45495. return offset + 1 < data.length && isHeaderPattern(data, offset);
  45496. }
  45497. function canParse(data, offset) {
  45498. var headerSize = 4;
  45499. return isHeaderPattern(data, offset) && headerSize <= data.length - offset;
  45500. }
  45501. function probe(data, offset) {
  45502. // same as isHeader but we also check that MPEG frame follows last MPEG frame
  45503. // or end of data is reached
  45504. if (offset + 1 < data.length && isHeaderPattern(data, offset)) {
  45505. // MPEG header Length
  45506. var headerLength = 4;
  45507. // MPEG frame Length
  45508. var header = parseHeader(data, offset);
  45509. var frameLength = headerLength;
  45510. if (header !== null && header !== void 0 && header.frameLength) {
  45511. frameLength = header.frameLength;
  45512. }
  45513. var newOffset = offset + frameLength;
  45514. return newOffset === data.length || isHeader(data, newOffset);
  45515. }
  45516. return false;
  45517. }
  45518. /***/ }),
  45519. /***/ "./src/demux/sample-aes.ts":
  45520. /*!*********************************!*\
  45521. !*** ./src/demux/sample-aes.ts ***!
  45522. \*********************************/
  45523. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  45524. "use strict";
  45525. __webpack_require__.r(__webpack_exports__);
  45526. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  45527. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  45528. /* harmony export */ });
  45529. /* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts");
  45530. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  45531. /**
  45532. * SAMPLE-AES decrypter
  45533. */
  45534. var SampleAesDecrypter = /*#__PURE__*/function () {
  45535. function SampleAesDecrypter(observer, config, keyData) {
  45536. this.keyData = void 0;
  45537. this.decrypter = void 0;
  45538. this.keyData = keyData;
  45539. this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_0__["default"](config, {
  45540. removePKCS7Padding: false
  45541. });
  45542. }
  45543. var _proto = SampleAesDecrypter.prototype;
  45544. _proto.decryptBuffer = function decryptBuffer(encryptedData) {
  45545. return this.decrypter.decrypt(encryptedData, this.keyData.key.buffer, this.keyData.iv.buffer);
  45546. }
  45547. // AAC - encrypt all full 16 bytes blocks starting from offset 16
  45548. ;
  45549. _proto.decryptAacSample = function decryptAacSample(samples, sampleIndex, callback) {
  45550. var _this = this;
  45551. var curUnit = samples[sampleIndex].unit;
  45552. if (curUnit.length <= 16) {
  45553. // No encrypted portion in this sample (first 16 bytes is not
  45554. // encrypted, see https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/HLS_Sample_Encryption/Encryption/Encryption.html),
  45555. return;
  45556. }
  45557. var encryptedData = curUnit.subarray(16, curUnit.length - curUnit.length % 16);
  45558. var encryptedBuffer = encryptedData.buffer.slice(encryptedData.byteOffset, encryptedData.byteOffset + encryptedData.length);
  45559. this.decryptBuffer(encryptedBuffer).then(function (decryptedBuffer) {
  45560. var decryptedData = new Uint8Array(decryptedBuffer);
  45561. curUnit.set(decryptedData, 16);
  45562. if (!_this.decrypter.isSync()) {
  45563. _this.decryptAacSamples(samples, sampleIndex + 1, callback);
  45564. }
  45565. });
  45566. };
  45567. _proto.decryptAacSamples = function decryptAacSamples(samples, sampleIndex, callback) {
  45568. for (;; sampleIndex++) {
  45569. if (sampleIndex >= samples.length) {
  45570. callback();
  45571. return;
  45572. }
  45573. if (samples[sampleIndex].unit.length < 32) {
  45574. continue;
  45575. }
  45576. this.decryptAacSample(samples, sampleIndex, callback);
  45577. if (!this.decrypter.isSync()) {
  45578. return;
  45579. }
  45580. }
  45581. }
  45582. // AVC - encrypt one 16 bytes block out of ten, starting from offset 32
  45583. ;
  45584. _proto.getAvcEncryptedData = function getAvcEncryptedData(decodedData) {
  45585. var encryptedDataLen = Math.floor((decodedData.length - 48) / 160) * 16 + 16;
  45586. var encryptedData = new Int8Array(encryptedDataLen);
  45587. var outputPos = 0;
  45588. for (var inputPos = 32; inputPos < decodedData.length - 16; inputPos += 160, outputPos += 16) {
  45589. encryptedData.set(decodedData.subarray(inputPos, inputPos + 16), outputPos);
  45590. }
  45591. return encryptedData;
  45592. };
  45593. _proto.getAvcDecryptedUnit = function getAvcDecryptedUnit(decodedData, decryptedData) {
  45594. var uint8DecryptedData = new Uint8Array(decryptedData);
  45595. var inputPos = 0;
  45596. for (var outputPos = 32; outputPos < decodedData.length - 16; outputPos += 160, inputPos += 16) {
  45597. decodedData.set(uint8DecryptedData.subarray(inputPos, inputPos + 16), outputPos);
  45598. }
  45599. return decodedData;
  45600. };
  45601. _proto.decryptAvcSample = function decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit) {
  45602. var _this2 = this;
  45603. var decodedData = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_1__.discardEPB)(curUnit.data);
  45604. var encryptedData = this.getAvcEncryptedData(decodedData);
  45605. this.decryptBuffer(encryptedData.buffer).then(function (decryptedBuffer) {
  45606. curUnit.data = _this2.getAvcDecryptedUnit(decodedData, decryptedBuffer);
  45607. if (!_this2.decrypter.isSync()) {
  45608. _this2.decryptAvcSamples(samples, sampleIndex, unitIndex + 1, callback);
  45609. }
  45610. });
  45611. };
  45612. _proto.decryptAvcSamples = function decryptAvcSamples(samples, sampleIndex, unitIndex, callback) {
  45613. if (samples instanceof Uint8Array) {
  45614. throw new Error('Cannot decrypt samples of type Uint8Array');
  45615. }
  45616. for (;; sampleIndex++, unitIndex = 0) {
  45617. if (sampleIndex >= samples.length) {
  45618. callback();
  45619. return;
  45620. }
  45621. var curUnits = samples[sampleIndex].units;
  45622. for (;; unitIndex++) {
  45623. if (unitIndex >= curUnits.length) {
  45624. break;
  45625. }
  45626. var curUnit = curUnits[unitIndex];
  45627. if (curUnit.data.length <= 48 || curUnit.type !== 1 && curUnit.type !== 5) {
  45628. continue;
  45629. }
  45630. this.decryptAvcSample(samples, sampleIndex, unitIndex, callback, curUnit);
  45631. if (!this.decrypter.isSync()) {
  45632. return;
  45633. }
  45634. }
  45635. }
  45636. };
  45637. return SampleAesDecrypter;
  45638. }();
  45639. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SampleAesDecrypter);
  45640. /***/ }),
  45641. /***/ "./src/demux/transmuxer-interface.ts":
  45642. /*!*******************************************!*\
  45643. !*** ./src/demux/transmuxer-interface.ts ***!
  45644. \*******************************************/
  45645. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  45646. "use strict";
  45647. __webpack_require__.r(__webpack_exports__);
  45648. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  45649. /* harmony export */ "default": () => (/* binding */ TransmuxerInterface)
  45650. /* harmony export */ });
  45651. /* harmony import */ var _webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./webworkify-webpack */ "./src/demux/webworkify-webpack.js");
  45652. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  45653. /* harmony import */ var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/transmuxer */ "./src/demux/transmuxer.ts");
  45654. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  45655. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  45656. /* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mediasource-helper */ "./src/utils/mediasource-helper.ts");
  45657. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js");
  45658. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_6__);
  45659. var MediaSource = (0,_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_5__.getMediaSource)() || {
  45660. isTypeSupported: function isTypeSupported() {
  45661. return false;
  45662. }
  45663. };
  45664. var TransmuxerInterface = /*#__PURE__*/function () {
  45665. function TransmuxerInterface(hls, id, onTransmuxComplete, onFlush) {
  45666. var _this = this;
  45667. this.hls = void 0;
  45668. this.id = void 0;
  45669. this.observer = void 0;
  45670. this.frag = null;
  45671. this.part = null;
  45672. this.useWorker = void 0;
  45673. this.worker = void 0;
  45674. this.onwmsg = void 0;
  45675. this.transmuxer = null;
  45676. this.onTransmuxComplete = void 0;
  45677. this.onFlush = void 0;
  45678. var config = hls.config;
  45679. this.hls = hls;
  45680. this.id = id;
  45681. this.useWorker = !!config.enableWorker;
  45682. this.onTransmuxComplete = onTransmuxComplete;
  45683. this.onFlush = onFlush;
  45684. var forwardMessage = function forwardMessage(ev, data) {
  45685. data = data || {};
  45686. data.frag = _this.frag;
  45687. data.id = _this.id;
  45688. _this.hls.trigger(ev, data);
  45689. };
  45690. // forward events to main thread
  45691. this.observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_6__.EventEmitter();
  45692. this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED, forwardMessage);
  45693. this.observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, forwardMessage);
  45694. var typeSupported = {
  45695. mp4: MediaSource.isTypeSupported('video/mp4'),
  45696. mpeg: MediaSource.isTypeSupported('audio/mpeg'),
  45697. mp3: MediaSource.isTypeSupported('audio/mp4; codecs="mp3"')
  45698. };
  45699. // navigator.vendor is not always available in Web Worker
  45700. // refer to https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/navigator
  45701. var vendor = navigator.vendor;
  45702. if (this.useWorker && typeof Worker !== 'undefined') {
  45703. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log('demuxing in webworker');
  45704. var worker;
  45705. try {
  45706. worker = this.worker = (0,_webworkify_webpack__WEBPACK_IMPORTED_MODULE_0__["default"])(/*require.resolve*/(/*! ../demux/transmuxer-worker.ts */ "./src/demux/transmuxer-worker.ts"));
  45707. this.onwmsg = this.onWorkerMessage.bind(this);
  45708. worker.addEventListener('message', this.onwmsg);
  45709. worker.onerror = function (event) {
  45710. _this.useWorker = false;
  45711. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Exception in webworker, fallback to inline');
  45712. _this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  45713. type: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.OTHER_ERROR,
  45714. details: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.INTERNAL_EXCEPTION,
  45715. fatal: false,
  45716. event: 'demuxerWorker',
  45717. error: new Error(event.message + " (" + event.filename + ":" + event.lineno + ")")
  45718. });
  45719. };
  45720. worker.postMessage({
  45721. cmd: 'init',
  45722. typeSupported: typeSupported,
  45723. vendor: vendor,
  45724. id: id,
  45725. config: JSON.stringify(config)
  45726. });
  45727. } catch (err) {
  45728. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn('Error in worker:', err);
  45729. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.error('Error while initializing DemuxerWorker, fallback to inline');
  45730. if (worker) {
  45731. // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
  45732. self.URL.revokeObjectURL(worker.objectURL);
  45733. }
  45734. this.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, typeSupported, config, vendor, id);
  45735. this.worker = null;
  45736. }
  45737. } else {
  45738. this.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__["default"](this.observer, typeSupported, config, vendor, id);
  45739. }
  45740. }
  45741. var _proto = TransmuxerInterface.prototype;
  45742. _proto.destroy = function destroy() {
  45743. var w = this.worker;
  45744. if (w) {
  45745. w.removeEventListener('message', this.onwmsg);
  45746. w.terminate();
  45747. this.worker = null;
  45748. this.onwmsg = undefined;
  45749. } else {
  45750. var transmuxer = this.transmuxer;
  45751. if (transmuxer) {
  45752. transmuxer.destroy();
  45753. this.transmuxer = null;
  45754. }
  45755. }
  45756. var observer = this.observer;
  45757. if (observer) {
  45758. observer.removeAllListeners();
  45759. }
  45760. this.frag = null;
  45761. // @ts-ignore
  45762. this.observer = null;
  45763. // @ts-ignore
  45764. this.hls = null;
  45765. };
  45766. _proto.push = function push(data, initSegmentData, audioCodec, videoCodec, frag, part, duration, accurateTimeOffset, chunkMeta, defaultInitPTS) {
  45767. var _frag$initSegment,
  45768. _lastFrag$initSegment,
  45769. _this2 = this;
  45770. chunkMeta.transmuxing.start = self.performance.now();
  45771. var transmuxer = this.transmuxer,
  45772. worker = this.worker;
  45773. var timeOffset = part ? part.start : frag.start;
  45774. // TODO: push "clear-lead" decrypt data for unencrypted fragments in streams with encrypted ones
  45775. var decryptdata = frag.decryptdata;
  45776. var lastFrag = this.frag;
  45777. var discontinuity = !(lastFrag && frag.cc === lastFrag.cc);
  45778. var trackSwitch = !(lastFrag && chunkMeta.level === lastFrag.level);
  45779. var snDiff = lastFrag ? chunkMeta.sn - lastFrag.sn : -1;
  45780. var partDiff = this.part ? chunkMeta.part - this.part.index : -1;
  45781. var progressive = snDiff === 0 && chunkMeta.id > 1 && chunkMeta.id === (lastFrag === null || lastFrag === void 0 ? void 0 : lastFrag.stats.chunkCount);
  45782. var contiguous = !trackSwitch && (snDiff === 1 || snDiff === 0 && (partDiff === 1 || progressive && partDiff <= 0));
  45783. var now = self.performance.now();
  45784. if (trackSwitch || snDiff || frag.stats.parsing.start === 0) {
  45785. frag.stats.parsing.start = now;
  45786. }
  45787. if (part && (partDiff || !contiguous)) {
  45788. part.stats.parsing.start = now;
  45789. }
  45790. var initSegmentChange = !(lastFrag && ((_frag$initSegment = frag.initSegment) === null || _frag$initSegment === void 0 ? void 0 : _frag$initSegment.url) === ((_lastFrag$initSegment = lastFrag.initSegment) === null || _lastFrag$initSegment === void 0 ? void 0 : _lastFrag$initSegment.url));
  45791. var state = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange);
  45792. if (!contiguous || discontinuity || initSegmentChange) {
  45793. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[transmuxer-interface, " + frag.type + "]: Starting new transmux session for sn: " + chunkMeta.sn + " p: " + chunkMeta.part + " level: " + chunkMeta.level + " id: " + chunkMeta.id + "\n discontinuity: " + discontinuity + "\n trackSwitch: " + trackSwitch + "\n contiguous: " + contiguous + "\n accurateTimeOffset: " + accurateTimeOffset + "\n timeOffset: " + timeOffset + "\n initSegmentChange: " + initSegmentChange);
  45794. var config = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.TransmuxConfig(audioCodec, videoCodec, initSegmentData, duration, defaultInitPTS);
  45795. this.configureTransmuxer(config);
  45796. }
  45797. this.frag = frag;
  45798. this.part = part;
  45799. // Frags with sn of 'initSegment' are not transmuxed
  45800. if (worker) {
  45801. // post fragment payload as transferable objects for ArrayBuffer (no copy)
  45802. worker.postMessage({
  45803. cmd: 'demux',
  45804. data: data,
  45805. decryptdata: decryptdata,
  45806. chunkMeta: chunkMeta,
  45807. state: state
  45808. }, data instanceof ArrayBuffer ? [data] : []);
  45809. } else if (transmuxer) {
  45810. var _transmuxResult = transmuxer.push(data, decryptdata, chunkMeta, state);
  45811. if ((0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.isPromise)(_transmuxResult)) {
  45812. transmuxer.async = true;
  45813. _transmuxResult.then(function (data) {
  45814. _this2.handleTransmuxComplete(data);
  45815. }).catch(function (error) {
  45816. _this2.transmuxerError(error, chunkMeta, 'transmuxer-interface push error');
  45817. });
  45818. } else {
  45819. transmuxer.async = false;
  45820. this.handleTransmuxComplete(_transmuxResult);
  45821. }
  45822. }
  45823. };
  45824. _proto.flush = function flush(chunkMeta) {
  45825. var _this3 = this;
  45826. chunkMeta.transmuxing.start = self.performance.now();
  45827. var transmuxer = this.transmuxer,
  45828. worker = this.worker;
  45829. if (worker) {
  45830. 1;
  45831. worker.postMessage({
  45832. cmd: 'flush',
  45833. chunkMeta: chunkMeta
  45834. });
  45835. } else if (transmuxer) {
  45836. var _transmuxResult2 = transmuxer.flush(chunkMeta);
  45837. var asyncFlush = (0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.isPromise)(_transmuxResult2);
  45838. if (asyncFlush || transmuxer.async) {
  45839. if (!(0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_2__.isPromise)(_transmuxResult2)) {
  45840. _transmuxResult2 = Promise.resolve(_transmuxResult2);
  45841. }
  45842. _transmuxResult2.then(function (data) {
  45843. _this3.handleFlushResult(data, chunkMeta);
  45844. }).catch(function (error) {
  45845. _this3.transmuxerError(error, chunkMeta, 'transmuxer-interface flush error');
  45846. });
  45847. } else {
  45848. this.handleFlushResult(_transmuxResult2, chunkMeta);
  45849. }
  45850. }
  45851. };
  45852. _proto.transmuxerError = function transmuxerError(error, chunkMeta, reason) {
  45853. if (!this.hls) {
  45854. return;
  45855. }
  45856. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  45857. type: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MEDIA_ERROR,
  45858. details: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.FRAG_PARSING_ERROR,
  45859. chunkMeta: chunkMeta,
  45860. fatal: false,
  45861. error: error,
  45862. err: error,
  45863. reason: reason
  45864. });
  45865. };
  45866. _proto.handleFlushResult = function handleFlushResult(results, chunkMeta) {
  45867. var _this4 = this;
  45868. results.forEach(function (result) {
  45869. _this4.handleTransmuxComplete(result);
  45870. });
  45871. this.onFlush(chunkMeta);
  45872. };
  45873. _proto.onWorkerMessage = function onWorkerMessage(ev) {
  45874. var data = ev.data;
  45875. var hls = this.hls;
  45876. switch (data.event) {
  45877. case 'init':
  45878. {
  45879. // revoke the Object URL that was used to create transmuxer worker, so as not to leak it
  45880. self.URL.revokeObjectURL(this.worker.objectURL);
  45881. break;
  45882. }
  45883. case 'transmuxComplete':
  45884. {
  45885. this.handleTransmuxComplete(data.data);
  45886. break;
  45887. }
  45888. case 'flush':
  45889. {
  45890. this.onFlush(data.data);
  45891. break;
  45892. }
  45893. // pass logs from the worker thread to the main logger
  45894. case 'workerLog':
  45895. if (_utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger[data.data.logType]) {
  45896. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger[data.data.logType](data.data.message);
  45897. }
  45898. break;
  45899. default:
  45900. {
  45901. data.data = data.data || {};
  45902. data.data.frag = this.frag;
  45903. data.data.id = this.id;
  45904. hls.trigger(data.event, data.data);
  45905. break;
  45906. }
  45907. }
  45908. };
  45909. _proto.configureTransmuxer = function configureTransmuxer(config) {
  45910. var worker = this.worker,
  45911. transmuxer = this.transmuxer;
  45912. if (worker) {
  45913. worker.postMessage({
  45914. cmd: 'configure',
  45915. config: config
  45916. });
  45917. } else if (transmuxer) {
  45918. transmuxer.configure(config);
  45919. }
  45920. };
  45921. _proto.handleTransmuxComplete = function handleTransmuxComplete(result) {
  45922. result.chunkMeta.transmuxing.end = self.performance.now();
  45923. this.onTransmuxComplete(result);
  45924. };
  45925. return TransmuxerInterface;
  45926. }();
  45927. /***/ }),
  45928. /***/ "./src/demux/transmuxer-worker.ts":
  45929. /*!****************************************!*\
  45930. !*** ./src/demux/transmuxer-worker.ts ***!
  45931. \****************************************/
  45932. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  45933. "use strict";
  45934. __webpack_require__.r(__webpack_exports__);
  45935. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  45936. /* harmony export */ "default": () => (/* binding */ TransmuxerWorker)
  45937. /* harmony export */ });
  45938. /* harmony import */ var _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../demux/transmuxer */ "./src/demux/transmuxer.ts");
  45939. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  45940. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  45941. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js");
  45942. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_3__);
  45943. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  45944. function TransmuxerWorker(self) {
  45945. var observer = new eventemitter3__WEBPACK_IMPORTED_MODULE_3__.EventEmitter();
  45946. var forwardMessage = function forwardMessage(ev, data) {
  45947. self.postMessage({
  45948. event: ev,
  45949. data: data
  45950. });
  45951. };
  45952. // forward events to main thread
  45953. observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.FRAG_DECRYPTED, forwardMessage);
  45954. observer.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, forwardMessage);
  45955. // forward logger events to main thread
  45956. var forwardWorkerLogs = function forwardWorkerLogs() {
  45957. var _loop = function _loop(logFn) {
  45958. var func = function func(message) {
  45959. forwardMessage('workerLog', {
  45960. logType: logFn,
  45961. message: message
  45962. });
  45963. };
  45964. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger[logFn] = func;
  45965. };
  45966. for (var logFn in _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger) {
  45967. _loop(logFn);
  45968. }
  45969. };
  45970. self.addEventListener('message', function (ev) {
  45971. var data = ev.data;
  45972. switch (data.cmd) {
  45973. case 'init':
  45974. {
  45975. var config = JSON.parse(data.config);
  45976. self.transmuxer = new _demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__["default"](observer, data.typeSupported, config, data.vendor, data.id);
  45977. (0,_utils_logger__WEBPACK_IMPORTED_MODULE_2__.enableLogs)(config.debug, data.id);
  45978. forwardWorkerLogs();
  45979. forwardMessage('init', null);
  45980. break;
  45981. }
  45982. case 'configure':
  45983. {
  45984. self.transmuxer.configure(data.config);
  45985. break;
  45986. }
  45987. case 'demux':
  45988. {
  45989. var transmuxResult = self.transmuxer.push(data.data, data.decryptdata, data.chunkMeta, data.state);
  45990. if ((0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__.isPromise)(transmuxResult)) {
  45991. self.transmuxer.async = true;
  45992. transmuxResult.then(function (data) {
  45993. emitTransmuxComplete(self, data);
  45994. }).catch(function (error) {
  45995. forwardMessage(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  45996. type: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MEDIA_ERROR,
  45997. details: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.FRAG_PARSING_ERROR,
  45998. chunkMeta: data.chunkMeta,
  45999. fatal: false,
  46000. error: error,
  46001. err: error,
  46002. reason: "transmuxer-worker push error"
  46003. });
  46004. });
  46005. } else {
  46006. self.transmuxer.async = false;
  46007. emitTransmuxComplete(self, transmuxResult);
  46008. }
  46009. break;
  46010. }
  46011. case 'flush':
  46012. {
  46013. var id = data.chunkMeta;
  46014. var _transmuxResult = self.transmuxer.flush(id);
  46015. var asyncFlush = (0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__.isPromise)(_transmuxResult);
  46016. if (asyncFlush || self.transmuxer.async) {
  46017. if (!(0,_demux_transmuxer__WEBPACK_IMPORTED_MODULE_0__.isPromise)(_transmuxResult)) {
  46018. _transmuxResult = Promise.resolve(_transmuxResult);
  46019. }
  46020. _transmuxResult.then(function (results) {
  46021. handleFlushResult(self, results, id);
  46022. }).catch(function (error) {
  46023. forwardMessage(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  46024. type: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MEDIA_ERROR,
  46025. details: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.FRAG_PARSING_ERROR,
  46026. chunkMeta: data.chunkMeta,
  46027. fatal: false,
  46028. error: error,
  46029. err: error,
  46030. reason: "transmuxer-worker flush error"
  46031. });
  46032. });
  46033. } else {
  46034. handleFlushResult(self, _transmuxResult, id);
  46035. }
  46036. break;
  46037. }
  46038. default:
  46039. break;
  46040. }
  46041. });
  46042. }
  46043. function emitTransmuxComplete(self, transmuxResult) {
  46044. if (isEmptyResult(transmuxResult.remuxResult)) {
  46045. return false;
  46046. }
  46047. var transferable = [];
  46048. var _transmuxResult$remux = transmuxResult.remuxResult,
  46049. audio = _transmuxResult$remux.audio,
  46050. video = _transmuxResult$remux.video;
  46051. if (audio) {
  46052. addToTransferable(transferable, audio);
  46053. }
  46054. if (video) {
  46055. addToTransferable(transferable, video);
  46056. }
  46057. self.postMessage({
  46058. event: 'transmuxComplete',
  46059. data: transmuxResult
  46060. }, transferable);
  46061. return true;
  46062. }
  46063. // Converts data to a transferable object https://developers.google.com/web/updates/2011/12/Transferable-Objects-Lightning-Fast)
  46064. // in order to minimize message passing overhead
  46065. function addToTransferable(transferable, track) {
  46066. if (track.data1) {
  46067. transferable.push(track.data1.buffer);
  46068. }
  46069. if (track.data2) {
  46070. transferable.push(track.data2.buffer);
  46071. }
  46072. }
  46073. function handleFlushResult(self, results, chunkMeta) {
  46074. var parsed = results.reduce(function (parsed, result) {
  46075. return emitTransmuxComplete(self, result) || parsed;
  46076. }, false);
  46077. if (!parsed) {
  46078. // Emit at least one "transmuxComplete" message even if media is not found to update stream-controller state to PARSING
  46079. self.postMessage({
  46080. event: 'transmuxComplete',
  46081. data: results[0]
  46082. });
  46083. }
  46084. self.postMessage({
  46085. event: 'flush',
  46086. data: chunkMeta
  46087. });
  46088. }
  46089. function isEmptyResult(remuxResult) {
  46090. return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
  46091. }
  46092. /***/ }),
  46093. /***/ "./src/demux/transmuxer.ts":
  46094. /*!*********************************!*\
  46095. !*** ./src/demux/transmuxer.ts ***!
  46096. \*********************************/
  46097. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  46098. "use strict";
  46099. __webpack_require__.r(__webpack_exports__);
  46100. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  46101. /* harmony export */ "TransmuxConfig": () => (/* binding */ TransmuxConfig),
  46102. /* harmony export */ "TransmuxState": () => (/* binding */ TransmuxState),
  46103. /* harmony export */ "default": () => (/* binding */ Transmuxer),
  46104. /* harmony export */ "isPromise": () => (/* binding */ isPromise)
  46105. /* harmony export */ });
  46106. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  46107. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  46108. /* harmony import */ var _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../crypt/decrypter */ "./src/crypt/decrypter.ts");
  46109. /* harmony import */ var _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/aacdemuxer */ "./src/demux/aacdemuxer.ts");
  46110. /* harmony import */ var _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../demux/mp4demuxer */ "./src/demux/mp4demuxer.ts");
  46111. /* harmony import */ var _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../demux/tsdemuxer */ "./src/demux/tsdemuxer.ts");
  46112. /* harmony import */ var _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../demux/mp3demuxer */ "./src/demux/mp3demuxer.ts");
  46113. /* harmony import */ var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../remux/mp4-remuxer */ "./src/remux/mp4-remuxer.ts");
  46114. /* harmony import */ var _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../remux/passthrough-remuxer */ "./src/remux/passthrough-remuxer.ts");
  46115. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  46116. var now;
  46117. // performance.now() not available on WebWorker, at least on Safari Desktop
  46118. try {
  46119. now = self.performance.now.bind(self.performance);
  46120. } catch (err) {
  46121. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.debug('Unable to use Performance API on this environment');
  46122. now = self.Date.now;
  46123. }
  46124. var muxConfig = [{
  46125. demux: _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"],
  46126. remux: _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"]
  46127. }, {
  46128. demux: _demux_tsdemuxer__WEBPACK_IMPORTED_MODULE_5__["default"],
  46129. remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"]
  46130. }, {
  46131. demux: _demux_aacdemuxer__WEBPACK_IMPORTED_MODULE_3__["default"],
  46132. remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"]
  46133. }, {
  46134. demux: _demux_mp3demuxer__WEBPACK_IMPORTED_MODULE_6__["default"],
  46135. remux: _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_7__["default"]
  46136. }];
  46137. var Transmuxer = /*#__PURE__*/function () {
  46138. function Transmuxer(observer, typeSupported, config, vendor, id) {
  46139. this.async = false;
  46140. this.observer = void 0;
  46141. this.typeSupported = void 0;
  46142. this.config = void 0;
  46143. this.vendor = void 0;
  46144. this.id = void 0;
  46145. this.demuxer = void 0;
  46146. this.remuxer = void 0;
  46147. this.decrypter = void 0;
  46148. this.probe = void 0;
  46149. this.decryptionPromise = null;
  46150. this.transmuxConfig = void 0;
  46151. this.currentTransmuxState = void 0;
  46152. this.observer = observer;
  46153. this.typeSupported = typeSupported;
  46154. this.config = config;
  46155. this.vendor = vendor;
  46156. this.id = id;
  46157. }
  46158. var _proto = Transmuxer.prototype;
  46159. _proto.configure = function configure(transmuxConfig) {
  46160. this.transmuxConfig = transmuxConfig;
  46161. if (this.decrypter) {
  46162. this.decrypter.reset();
  46163. }
  46164. };
  46165. _proto.push = function push(data, decryptdata, chunkMeta, state) {
  46166. var _this = this;
  46167. var stats = chunkMeta.transmuxing;
  46168. stats.executeStart = now();
  46169. var uintData = new Uint8Array(data);
  46170. var currentTransmuxState = this.currentTransmuxState,
  46171. transmuxConfig = this.transmuxConfig;
  46172. if (state) {
  46173. this.currentTransmuxState = state;
  46174. }
  46175. var _ref = state || currentTransmuxState,
  46176. contiguous = _ref.contiguous,
  46177. discontinuity = _ref.discontinuity,
  46178. trackSwitch = _ref.trackSwitch,
  46179. accurateTimeOffset = _ref.accurateTimeOffset,
  46180. timeOffset = _ref.timeOffset,
  46181. initSegmentChange = _ref.initSegmentChange;
  46182. var audioCodec = transmuxConfig.audioCodec,
  46183. videoCodec = transmuxConfig.videoCodec,
  46184. defaultInitPts = transmuxConfig.defaultInitPts,
  46185. duration = transmuxConfig.duration,
  46186. initSegmentData = transmuxConfig.initSegmentData;
  46187. var keyData = getEncryptionType(uintData, decryptdata);
  46188. if (keyData && keyData.method === 'AES-128') {
  46189. var decrypter = this.getDecrypter();
  46190. // Software decryption is synchronous; webCrypto is not
  46191. if (decrypter.isSync()) {
  46192. // Software decryption is progressive. Progressive decryption may not return a result on each call. Any cached
  46193. // data is handled in the flush() call
  46194. var decryptedData = decrypter.softwareDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer);
  46195. // For Low-Latency HLS Parts, decrypt in place, since part parsing is expected on push progress
  46196. var loadingParts = chunkMeta.part > -1;
  46197. if (loadingParts) {
  46198. decryptedData = decrypter.flush();
  46199. }
  46200. if (!decryptedData) {
  46201. stats.executeEnd = now();
  46202. return emptyResult(chunkMeta);
  46203. }
  46204. uintData = new Uint8Array(decryptedData);
  46205. } else {
  46206. this.decryptionPromise = decrypter.webCryptoDecrypt(uintData, keyData.key.buffer, keyData.iv.buffer).then(function (decryptedData) {
  46207. // Calling push here is important; if flush() is called while this is still resolving, this ensures that
  46208. // the decrypted data has been transmuxed
  46209. var result = _this.push(decryptedData, null, chunkMeta);
  46210. _this.decryptionPromise = null;
  46211. return result;
  46212. });
  46213. return this.decryptionPromise;
  46214. }
  46215. }
  46216. var resetMuxers = this.needsProbing(discontinuity, trackSwitch);
  46217. if (resetMuxers) {
  46218. this.configureTransmuxer(uintData);
  46219. }
  46220. if (discontinuity || trackSwitch || initSegmentChange || resetMuxers) {
  46221. this.resetInitSegment(initSegmentData, audioCodec, videoCodec, duration, decryptdata);
  46222. }
  46223. if (discontinuity || initSegmentChange || resetMuxers) {
  46224. this.resetInitialTimestamp(defaultInitPts);
  46225. }
  46226. if (!contiguous) {
  46227. this.resetContiguity();
  46228. }
  46229. var result = this.transmux(uintData, keyData, timeOffset, accurateTimeOffset, chunkMeta);
  46230. var currentState = this.currentTransmuxState;
  46231. currentState.contiguous = true;
  46232. currentState.discontinuity = false;
  46233. currentState.trackSwitch = false;
  46234. stats.executeEnd = now();
  46235. return result;
  46236. }
  46237. // Due to data caching, flush calls can produce more than one TransmuxerResult (hence the Array type)
  46238. ;
  46239. _proto.flush = function flush(chunkMeta) {
  46240. var _this2 = this;
  46241. var stats = chunkMeta.transmuxing;
  46242. stats.executeStart = now();
  46243. var decrypter = this.decrypter,
  46244. currentTransmuxState = this.currentTransmuxState,
  46245. decryptionPromise = this.decryptionPromise;
  46246. if (decryptionPromise) {
  46247. // Upon resolution, the decryption promise calls push() and returns its TransmuxerResult up the stack. Therefore
  46248. // only flushing is required for async decryption
  46249. return decryptionPromise.then(function () {
  46250. return _this2.flush(chunkMeta);
  46251. });
  46252. }
  46253. var transmuxResults = [];
  46254. var timeOffset = currentTransmuxState.timeOffset;
  46255. if (decrypter) {
  46256. // The decrypter may have data cached, which needs to be demuxed. In this case we'll have two TransmuxResults
  46257. // This happens in the case that we receive only 1 push call for a segment (either for non-progressive downloads,
  46258. // or for progressive downloads with small segments)
  46259. var decryptedData = decrypter.flush();
  46260. if (decryptedData) {
  46261. // Push always returns a TransmuxerResult if decryptdata is null
  46262. transmuxResults.push(this.push(decryptedData, null, chunkMeta));
  46263. }
  46264. }
  46265. var demuxer = this.demuxer,
  46266. remuxer = this.remuxer;
  46267. if (!demuxer || !remuxer) {
  46268. // If probing failed, then Hls.js has been given content its not able to handle
  46269. this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, _events__WEBPACK_IMPORTED_MODULE_0__.Events.ERROR, {
  46270. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.MEDIA_ERROR,
  46271. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_PARSING_ERROR,
  46272. fatal: true,
  46273. reason: 'no demux matching with content found'
  46274. });
  46275. stats.executeEnd = now();
  46276. return [emptyResult(chunkMeta)];
  46277. }
  46278. var demuxResultOrPromise = demuxer.flush(timeOffset);
  46279. if (isPromise(demuxResultOrPromise)) {
  46280. // Decrypt final SAMPLE-AES samples
  46281. return demuxResultOrPromise.then(function (demuxResult) {
  46282. _this2.flushRemux(transmuxResults, demuxResult, chunkMeta);
  46283. return transmuxResults;
  46284. });
  46285. }
  46286. this.flushRemux(transmuxResults, demuxResultOrPromise, chunkMeta);
  46287. return transmuxResults;
  46288. };
  46289. _proto.flushRemux = function flushRemux(transmuxResults, demuxResult, chunkMeta) {
  46290. var audioTrack = demuxResult.audioTrack,
  46291. videoTrack = demuxResult.videoTrack,
  46292. id3Track = demuxResult.id3Track,
  46293. textTrack = demuxResult.textTrack;
  46294. var _this$currentTransmux = this.currentTransmuxState,
  46295. accurateTimeOffset = _this$currentTransmux.accurateTimeOffset,
  46296. timeOffset = _this$currentTransmux.timeOffset;
  46297. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("[transmuxer.ts]: Flushed fragment " + chunkMeta.sn + (chunkMeta.part > -1 ? ' p: ' + chunkMeta.part : '') + " of level " + chunkMeta.level);
  46298. var remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, true, this.id);
  46299. transmuxResults.push({
  46300. remuxResult: remuxResult,
  46301. chunkMeta: chunkMeta
  46302. });
  46303. chunkMeta.transmuxing.executeEnd = now();
  46304. };
  46305. _proto.resetInitialTimestamp = function resetInitialTimestamp(defaultInitPts) {
  46306. var demuxer = this.demuxer,
  46307. remuxer = this.remuxer;
  46308. if (!demuxer || !remuxer) {
  46309. return;
  46310. }
  46311. demuxer.resetTimeStamp(defaultInitPts);
  46312. remuxer.resetTimeStamp(defaultInitPts);
  46313. };
  46314. _proto.resetContiguity = function resetContiguity() {
  46315. var demuxer = this.demuxer,
  46316. remuxer = this.remuxer;
  46317. if (!demuxer || !remuxer) {
  46318. return;
  46319. }
  46320. demuxer.resetContiguity();
  46321. remuxer.resetNextTimestamp();
  46322. };
  46323. _proto.resetInitSegment = function resetInitSegment(initSegmentData, audioCodec, videoCodec, trackDuration, decryptdata) {
  46324. var demuxer = this.demuxer,
  46325. remuxer = this.remuxer;
  46326. if (!demuxer || !remuxer) {
  46327. return;
  46328. }
  46329. demuxer.resetInitSegment(initSegmentData, audioCodec, videoCodec, trackDuration);
  46330. remuxer.resetInitSegment(initSegmentData, audioCodec, videoCodec, decryptdata);
  46331. };
  46332. _proto.destroy = function destroy() {
  46333. if (this.demuxer) {
  46334. this.demuxer.destroy();
  46335. this.demuxer = undefined;
  46336. }
  46337. if (this.remuxer) {
  46338. this.remuxer.destroy();
  46339. this.remuxer = undefined;
  46340. }
  46341. };
  46342. _proto.transmux = function transmux(data, keyData, timeOffset, accurateTimeOffset, chunkMeta) {
  46343. var result;
  46344. if (keyData && keyData.method === 'SAMPLE-AES') {
  46345. result = this.transmuxSampleAes(data, keyData, timeOffset, accurateTimeOffset, chunkMeta);
  46346. } else {
  46347. result = this.transmuxUnencrypted(data, timeOffset, accurateTimeOffset, chunkMeta);
  46348. }
  46349. return result;
  46350. };
  46351. _proto.transmuxUnencrypted = function transmuxUnencrypted(data, timeOffset, accurateTimeOffset, chunkMeta) {
  46352. var _demux = this.demuxer.demux(data, timeOffset, false, !this.config.progressive),
  46353. audioTrack = _demux.audioTrack,
  46354. videoTrack = _demux.videoTrack,
  46355. id3Track = _demux.id3Track,
  46356. textTrack = _demux.textTrack;
  46357. var remuxResult = this.remuxer.remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, false, this.id);
  46358. return {
  46359. remuxResult: remuxResult,
  46360. chunkMeta: chunkMeta
  46361. };
  46362. };
  46363. _proto.transmuxSampleAes = function transmuxSampleAes(data, decryptData, timeOffset, accurateTimeOffset, chunkMeta) {
  46364. var _this3 = this;
  46365. return this.demuxer.demuxSampleAes(data, decryptData, timeOffset).then(function (demuxResult) {
  46366. var remuxResult = _this3.remuxer.remux(demuxResult.audioTrack, demuxResult.videoTrack, demuxResult.id3Track, demuxResult.textTrack, timeOffset, accurateTimeOffset, false, _this3.id);
  46367. return {
  46368. remuxResult: remuxResult,
  46369. chunkMeta: chunkMeta
  46370. };
  46371. });
  46372. };
  46373. _proto.configureTransmuxer = function configureTransmuxer(data) {
  46374. var config = this.config,
  46375. observer = this.observer,
  46376. typeSupported = this.typeSupported,
  46377. vendor = this.vendor;
  46378. // probe for content type
  46379. var mux;
  46380. for (var i = 0, len = muxConfig.length; i < len; i++) {
  46381. if (muxConfig[i].demux.probe(data)) {
  46382. mux = muxConfig[i];
  46383. break;
  46384. }
  46385. }
  46386. if (!mux) {
  46387. // If probing previous configs fail, use mp4 passthrough
  46388. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.warn('Failed to find demuxer by probing frag, treating as mp4 passthrough');
  46389. mux = {
  46390. demux: _demux_mp4demuxer__WEBPACK_IMPORTED_MODULE_4__["default"],
  46391. remux: _remux_passthrough_remuxer__WEBPACK_IMPORTED_MODULE_8__["default"]
  46392. };
  46393. }
  46394. // so let's check that current remuxer and demuxer are still valid
  46395. var demuxer = this.demuxer;
  46396. var remuxer = this.remuxer;
  46397. var Remuxer = mux.remux;
  46398. var Demuxer = mux.demux;
  46399. if (!remuxer || !(remuxer instanceof Remuxer)) {
  46400. this.remuxer = new Remuxer(observer, config, typeSupported, vendor);
  46401. }
  46402. if (!demuxer || !(demuxer instanceof Demuxer)) {
  46403. this.demuxer = new Demuxer(observer, config, typeSupported);
  46404. this.probe = Demuxer.probe;
  46405. }
  46406. };
  46407. _proto.needsProbing = function needsProbing(discontinuity, trackSwitch) {
  46408. // in case of continuity change, or track switch
  46409. // we might switch from content type (AAC container to TS container, or TS to fmp4 for example)
  46410. return !this.demuxer || !this.remuxer || discontinuity || trackSwitch;
  46411. };
  46412. _proto.getDecrypter = function getDecrypter() {
  46413. var decrypter = this.decrypter;
  46414. if (!decrypter) {
  46415. decrypter = this.decrypter = new _crypt_decrypter__WEBPACK_IMPORTED_MODULE_2__["default"](this.config);
  46416. }
  46417. return decrypter;
  46418. };
  46419. return Transmuxer;
  46420. }();
  46421. function getEncryptionType(data, decryptData) {
  46422. var encryptionType = null;
  46423. if (data.byteLength > 0 && decryptData != null && decryptData.key != null && decryptData.iv !== null && decryptData.method != null) {
  46424. encryptionType = decryptData;
  46425. }
  46426. return encryptionType;
  46427. }
  46428. var emptyResult = function emptyResult(chunkMeta) {
  46429. return {
  46430. remuxResult: {},
  46431. chunkMeta: chunkMeta
  46432. };
  46433. };
  46434. function isPromise(p) {
  46435. return 'then' in p && p.then instanceof Function;
  46436. }
  46437. var TransmuxConfig = function TransmuxConfig(audioCodec, videoCodec, initSegmentData, duration, defaultInitPts) {
  46438. this.audioCodec = void 0;
  46439. this.videoCodec = void 0;
  46440. this.initSegmentData = void 0;
  46441. this.duration = void 0;
  46442. this.defaultInitPts = void 0;
  46443. this.audioCodec = audioCodec;
  46444. this.videoCodec = videoCodec;
  46445. this.initSegmentData = initSegmentData;
  46446. this.duration = duration;
  46447. this.defaultInitPts = defaultInitPts;
  46448. };
  46449. var TransmuxState = function TransmuxState(discontinuity, contiguous, accurateTimeOffset, trackSwitch, timeOffset, initSegmentChange) {
  46450. this.discontinuity = void 0;
  46451. this.contiguous = void 0;
  46452. this.accurateTimeOffset = void 0;
  46453. this.trackSwitch = void 0;
  46454. this.timeOffset = void 0;
  46455. this.initSegmentChange = void 0;
  46456. this.discontinuity = discontinuity;
  46457. this.contiguous = contiguous;
  46458. this.accurateTimeOffset = accurateTimeOffset;
  46459. this.trackSwitch = trackSwitch;
  46460. this.timeOffset = timeOffset;
  46461. this.initSegmentChange = initSegmentChange;
  46462. };
  46463. /***/ }),
  46464. /***/ "./src/demux/tsdemuxer.ts":
  46465. /*!********************************!*\
  46466. !*** ./src/demux/tsdemuxer.ts ***!
  46467. \********************************/
  46468. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  46469. "use strict";
  46470. __webpack_require__.r(__webpack_exports__);
  46471. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  46472. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  46473. /* harmony export */ });
  46474. /* harmony import */ var _adts__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./adts */ "./src/demux/adts.ts");
  46475. /* harmony import */ var _mpegaudio__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mpegaudio */ "./src/demux/mpegaudio.ts");
  46476. /* harmony import */ var _exp_golomb__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./exp-golomb */ "./src/demux/exp-golomb.ts");
  46477. /* harmony import */ var _sample_aes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./sample-aes */ "./src/demux/sample-aes.ts");
  46478. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  46479. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  46480. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  46481. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  46482. /* harmony import */ var _types_demuxer__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../types/demuxer */ "./src/types/demuxer.ts");
  46483. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  46484. /**
  46485. * highly optimized TS demuxer:
  46486. * parse PAT, PMT
  46487. * extract PES packet from audio and video PIDs
  46488. * extract AVC/H264 NAL units and AAC/ADTS samples from PES packet
  46489. * trigger the remuxer upon parsing completion
  46490. * it also tries to workaround as best as it can audio codec switch (HE-AAC to AAC and vice versa), without having to restart the MediaSource.
  46491. * it also controls the remuxing process :
  46492. * upon discontinuity or level switch detection, it will also notifies the remuxer so that it can reset its state.
  46493. */
  46494. var PACKET_LENGTH = 188;
  46495. var TSDemuxer = /*#__PURE__*/function () {
  46496. function TSDemuxer(observer, config, typeSupported) {
  46497. this.observer = void 0;
  46498. this.config = void 0;
  46499. this.typeSupported = void 0;
  46500. this.sampleAes = null;
  46501. this.pmtParsed = false;
  46502. this.audioCodec = void 0;
  46503. this.videoCodec = void 0;
  46504. this._duration = 0;
  46505. this._pmtId = -1;
  46506. this._avcTrack = void 0;
  46507. this._audioTrack = void 0;
  46508. this._id3Track = void 0;
  46509. this._txtTrack = void 0;
  46510. this.aacOverFlow = null;
  46511. this.avcSample = null;
  46512. this.remainderData = null;
  46513. this.observer = observer;
  46514. this.config = config;
  46515. this.typeSupported = typeSupported;
  46516. }
  46517. TSDemuxer.probe = function probe(data) {
  46518. var syncOffset = TSDemuxer.syncOffset(data);
  46519. if (syncOffset > 0) {
  46520. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn("MPEG2-TS detected but first sync word found @ offset " + syncOffset);
  46521. }
  46522. return syncOffset !== -1;
  46523. };
  46524. TSDemuxer.syncOffset = function syncOffset(data) {
  46525. var length = data.length;
  46526. var scanwindow = Math.min(PACKET_LENGTH * 5, data.length - PACKET_LENGTH) + 1;
  46527. var i = 0;
  46528. while (i < scanwindow) {
  46529. // a TS init segment should contain at least 2 TS packets: PAT and PMT, each starting with 0x47
  46530. var foundPat = false;
  46531. for (var j = i; j < length; j += PACKET_LENGTH) {
  46532. if (data[j] === 0x47) {
  46533. if (!foundPat && parsePID(data, j) === 0) {
  46534. foundPat = true;
  46535. }
  46536. if (foundPat && j + PACKET_LENGTH > scanwindow) {
  46537. return i;
  46538. }
  46539. } else {
  46540. break;
  46541. }
  46542. }
  46543. i++;
  46544. }
  46545. return -1;
  46546. }
  46547. /**
  46548. * Creates a track model internal to demuxer used to drive remuxing input
  46549. *
  46550. * @param type 'audio' | 'video' | 'id3' | 'text'
  46551. * @param duration
  46552. * @return TSDemuxer's internal track model
  46553. */;
  46554. TSDemuxer.createTrack = function createTrack(type, duration) {
  46555. return {
  46556. container: type === 'video' || type === 'audio' ? 'video/mp2t' : undefined,
  46557. type: type,
  46558. id: _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__.RemuxerTrackIdConfig[type],
  46559. pid: -1,
  46560. inputTimeScale: 90000,
  46561. sequenceNumber: 0,
  46562. samples: [],
  46563. dropped: 0,
  46564. duration: type === 'audio' ? duration : undefined
  46565. };
  46566. }
  46567. /**
  46568. * Initializes a new init segment on the demuxer/remuxer interface. Needed for discontinuities/track-switches (or at stream start)
  46569. * Resets all internal track instances of the demuxer.
  46570. */;
  46571. var _proto = TSDemuxer.prototype;
  46572. _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, trackDuration) {
  46573. this.pmtParsed = false;
  46574. this._pmtId = -1;
  46575. this._avcTrack = TSDemuxer.createTrack('video');
  46576. this._audioTrack = TSDemuxer.createTrack('audio', trackDuration);
  46577. this._id3Track = TSDemuxer.createTrack('id3');
  46578. this._txtTrack = TSDemuxer.createTrack('text');
  46579. this._audioTrack.segmentCodec = 'aac';
  46580. // flush any partial content
  46581. this.aacOverFlow = null;
  46582. this.avcSample = null;
  46583. this.remainderData = null;
  46584. this.audioCodec = audioCodec;
  46585. this.videoCodec = videoCodec;
  46586. this._duration = trackDuration;
  46587. };
  46588. _proto.resetTimeStamp = function resetTimeStamp() {};
  46589. _proto.resetContiguity = function resetContiguity() {
  46590. var _audioTrack = this._audioTrack,
  46591. _avcTrack = this._avcTrack,
  46592. _id3Track = this._id3Track;
  46593. if (_audioTrack) {
  46594. _audioTrack.pesData = null;
  46595. }
  46596. if (_avcTrack) {
  46597. _avcTrack.pesData = null;
  46598. }
  46599. if (_id3Track) {
  46600. _id3Track.pesData = null;
  46601. }
  46602. this.aacOverFlow = null;
  46603. this.avcSample = null;
  46604. this.remainderData = null;
  46605. };
  46606. _proto.demux = function demux(data, timeOffset, isSampleAes, flush) {
  46607. if (isSampleAes === void 0) {
  46608. isSampleAes = false;
  46609. }
  46610. if (flush === void 0) {
  46611. flush = false;
  46612. }
  46613. if (!isSampleAes) {
  46614. this.sampleAes = null;
  46615. }
  46616. var pes;
  46617. var videoTrack = this._avcTrack;
  46618. var audioTrack = this._audioTrack;
  46619. var id3Track = this._id3Track;
  46620. var textTrack = this._txtTrack;
  46621. var avcId = videoTrack.pid;
  46622. var avcData = videoTrack.pesData;
  46623. var audioId = audioTrack.pid;
  46624. var id3Id = id3Track.pid;
  46625. var audioData = audioTrack.pesData;
  46626. var id3Data = id3Track.pesData;
  46627. var unknownPID = null;
  46628. var pmtParsed = this.pmtParsed;
  46629. var pmtId = this._pmtId;
  46630. var len = data.length;
  46631. if (this.remainderData) {
  46632. data = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__.appendUint8Array)(this.remainderData, data);
  46633. len = data.length;
  46634. this.remainderData = null;
  46635. }
  46636. if (len < PACKET_LENGTH && !flush) {
  46637. this.remainderData = data;
  46638. return {
  46639. audioTrack: audioTrack,
  46640. videoTrack: videoTrack,
  46641. id3Track: id3Track,
  46642. textTrack: textTrack
  46643. };
  46644. }
  46645. var syncOffset = Math.max(0, TSDemuxer.syncOffset(data));
  46646. len -= (len - syncOffset) % PACKET_LENGTH;
  46647. if (len < data.byteLength && !flush) {
  46648. this.remainderData = new Uint8Array(data.buffer, len, data.buffer.byteLength - len);
  46649. }
  46650. // loop through TS packets
  46651. var tsPacketErrors = 0;
  46652. for (var start = syncOffset; start < len; start += PACKET_LENGTH) {
  46653. if (data[start] === 0x47) {
  46654. var stt = !!(data[start + 1] & 0x40);
  46655. var pid = parsePID(data, start);
  46656. var atf = (data[start + 3] & 0x30) >> 4;
  46657. // if an adaption field is present, its length is specified by the fifth byte of the TS packet header.
  46658. var offset = void 0;
  46659. if (atf > 1) {
  46660. offset = start + 5 + data[start + 4];
  46661. // continue if there is only adaptation field
  46662. if (offset === start + PACKET_LENGTH) {
  46663. continue;
  46664. }
  46665. } else {
  46666. offset = start + 4;
  46667. }
  46668. switch (pid) {
  46669. case avcId:
  46670. if (stt) {
  46671. if (avcData && (pes = parsePES(avcData))) {
  46672. this.parseAVCPES(videoTrack, textTrack, pes, false);
  46673. }
  46674. avcData = {
  46675. data: [],
  46676. size: 0
  46677. };
  46678. }
  46679. if (avcData) {
  46680. avcData.data.push(data.subarray(offset, start + PACKET_LENGTH));
  46681. avcData.size += start + PACKET_LENGTH - offset;
  46682. }
  46683. break;
  46684. case audioId:
  46685. if (stt) {
  46686. if (audioData && (pes = parsePES(audioData))) {
  46687. switch (audioTrack.segmentCodec) {
  46688. case 'aac':
  46689. this.parseAACPES(audioTrack, pes);
  46690. break;
  46691. case 'mp3':
  46692. this.parseMPEGPES(audioTrack, pes);
  46693. break;
  46694. }
  46695. }
  46696. audioData = {
  46697. data: [],
  46698. size: 0
  46699. };
  46700. }
  46701. if (audioData) {
  46702. audioData.data.push(data.subarray(offset, start + PACKET_LENGTH));
  46703. audioData.size += start + PACKET_LENGTH - offset;
  46704. }
  46705. break;
  46706. case id3Id:
  46707. if (stt) {
  46708. if (id3Data && (pes = parsePES(id3Data))) {
  46709. this.parseID3PES(id3Track, pes);
  46710. }
  46711. id3Data = {
  46712. data: [],
  46713. size: 0
  46714. };
  46715. }
  46716. if (id3Data) {
  46717. id3Data.data.push(data.subarray(offset, start + PACKET_LENGTH));
  46718. id3Data.size += start + PACKET_LENGTH - offset;
  46719. }
  46720. break;
  46721. case 0:
  46722. if (stt) {
  46723. offset += data[offset] + 1;
  46724. }
  46725. pmtId = this._pmtId = parsePAT(data, offset);
  46726. // logger.log('PMT PID:' + this._pmtId);
  46727. break;
  46728. case pmtId:
  46729. {
  46730. if (stt) {
  46731. offset += data[offset] + 1;
  46732. }
  46733. var parsedPIDs = parsePMT(data, offset, this.typeSupported, isSampleAes);
  46734. // only update track id if track PID found while parsing PMT
  46735. // this is to avoid resetting the PID to -1 in case
  46736. // track PID transiently disappears from the stream
  46737. // this could happen in case of transient missing audio samples for example
  46738. // NOTE this is only the PID of the track as found in TS,
  46739. // but we are not using this for MP4 track IDs.
  46740. avcId = parsedPIDs.avc;
  46741. if (avcId > 0) {
  46742. videoTrack.pid = avcId;
  46743. }
  46744. audioId = parsedPIDs.audio;
  46745. if (audioId > 0) {
  46746. audioTrack.pid = audioId;
  46747. audioTrack.segmentCodec = parsedPIDs.segmentCodec;
  46748. }
  46749. id3Id = parsedPIDs.id3;
  46750. if (id3Id > 0) {
  46751. id3Track.pid = id3Id;
  46752. }
  46753. if (unknownPID !== null && !pmtParsed) {
  46754. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn("MPEG-TS PMT found at " + start + " after unknown PID '" + unknownPID + "'. Backtracking to sync byte @" + syncOffset + " to parse all TS packets.");
  46755. unknownPID = null;
  46756. // we set it to -188, the += 188 in the for loop will reset start to 0
  46757. start = syncOffset - 188;
  46758. }
  46759. pmtParsed = this.pmtParsed = true;
  46760. break;
  46761. }
  46762. case 0x11:
  46763. case 0x1fff:
  46764. break;
  46765. default:
  46766. unknownPID = pid;
  46767. break;
  46768. }
  46769. } else {
  46770. tsPacketErrors++;
  46771. }
  46772. }
  46773. if (tsPacketErrors > 0) {
  46774. this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR, _events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR, {
  46775. type: _errors__WEBPACK_IMPORTED_MODULE_7__.ErrorTypes.MEDIA_ERROR,
  46776. details: _errors__WEBPACK_IMPORTED_MODULE_7__.ErrorDetails.FRAG_PARSING_ERROR,
  46777. fatal: false,
  46778. reason: "Found " + tsPacketErrors + " TS packet/s that do not start with 0x47"
  46779. });
  46780. }
  46781. videoTrack.pesData = avcData;
  46782. audioTrack.pesData = audioData;
  46783. id3Track.pesData = id3Data;
  46784. var demuxResult = {
  46785. audioTrack: audioTrack,
  46786. videoTrack: videoTrack,
  46787. id3Track: id3Track,
  46788. textTrack: textTrack
  46789. };
  46790. if (flush) {
  46791. this.extractRemainingSamples(demuxResult);
  46792. }
  46793. return demuxResult;
  46794. };
  46795. _proto.flush = function flush() {
  46796. var remainderData = this.remainderData;
  46797. this.remainderData = null;
  46798. var result;
  46799. if (remainderData) {
  46800. result = this.demux(remainderData, -1, false, true);
  46801. } else {
  46802. result = {
  46803. videoTrack: this._avcTrack,
  46804. audioTrack: this._audioTrack,
  46805. id3Track: this._id3Track,
  46806. textTrack: this._txtTrack
  46807. };
  46808. }
  46809. this.extractRemainingSamples(result);
  46810. if (this.sampleAes) {
  46811. return this.decrypt(result, this.sampleAes);
  46812. }
  46813. return result;
  46814. };
  46815. _proto.extractRemainingSamples = function extractRemainingSamples(demuxResult) {
  46816. var audioTrack = demuxResult.audioTrack,
  46817. videoTrack = demuxResult.videoTrack,
  46818. id3Track = demuxResult.id3Track,
  46819. textTrack = demuxResult.textTrack;
  46820. var avcData = videoTrack.pesData;
  46821. var audioData = audioTrack.pesData;
  46822. var id3Data = id3Track.pesData;
  46823. // try to parse last PES packets
  46824. var pes;
  46825. if (avcData && (pes = parsePES(avcData))) {
  46826. this.parseAVCPES(videoTrack, textTrack, pes, true);
  46827. videoTrack.pesData = null;
  46828. } else {
  46829. // either avcData null or PES truncated, keep it for next frag parsing
  46830. videoTrack.pesData = avcData;
  46831. }
  46832. if (audioData && (pes = parsePES(audioData))) {
  46833. switch (audioTrack.segmentCodec) {
  46834. case 'aac':
  46835. this.parseAACPES(audioTrack, pes);
  46836. break;
  46837. case 'mp3':
  46838. this.parseMPEGPES(audioTrack, pes);
  46839. break;
  46840. }
  46841. audioTrack.pesData = null;
  46842. } else {
  46843. if (audioData !== null && audioData !== void 0 && audioData.size) {
  46844. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('last AAC PES packet truncated,might overlap between fragments');
  46845. }
  46846. // either audioData null or PES truncated, keep it for next frag parsing
  46847. audioTrack.pesData = audioData;
  46848. }
  46849. if (id3Data && (pes = parsePES(id3Data))) {
  46850. this.parseID3PES(id3Track, pes);
  46851. id3Track.pesData = null;
  46852. } else {
  46853. // either id3Data null or PES truncated, keep it for next frag parsing
  46854. id3Track.pesData = id3Data;
  46855. }
  46856. };
  46857. _proto.demuxSampleAes = function demuxSampleAes(data, keyData, timeOffset) {
  46858. var demuxResult = this.demux(data, timeOffset, true, !this.config.progressive);
  46859. var sampleAes = this.sampleAes = new _sample_aes__WEBPACK_IMPORTED_MODULE_3__["default"](this.observer, this.config, keyData);
  46860. return this.decrypt(demuxResult, sampleAes);
  46861. };
  46862. _proto.decrypt = function decrypt(demuxResult, sampleAes) {
  46863. return new Promise(function (resolve) {
  46864. var audioTrack = demuxResult.audioTrack,
  46865. videoTrack = demuxResult.videoTrack;
  46866. if (audioTrack.samples && audioTrack.segmentCodec === 'aac') {
  46867. sampleAes.decryptAacSamples(audioTrack.samples, 0, function () {
  46868. if (videoTrack.samples) {
  46869. sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, function () {
  46870. resolve(demuxResult);
  46871. });
  46872. } else {
  46873. resolve(demuxResult);
  46874. }
  46875. });
  46876. } else if (videoTrack.samples) {
  46877. sampleAes.decryptAvcSamples(videoTrack.samples, 0, 0, function () {
  46878. resolve(demuxResult);
  46879. });
  46880. }
  46881. });
  46882. };
  46883. _proto.destroy = function destroy() {
  46884. this._duration = 0;
  46885. };
  46886. _proto.parseAVCPES = function parseAVCPES(track, textTrack, pes, last) {
  46887. var _this = this;
  46888. var units = this.parseAVCNALu(track, pes.data);
  46889. var debug = false;
  46890. var avcSample = this.avcSample;
  46891. var push;
  46892. var spsfound = false;
  46893. // free pes.data to save up some memory
  46894. pes.data = null;
  46895. // if new NAL units found and last sample still there, let's push ...
  46896. // this helps parsing streams with missing AUD (only do this if AUD never found)
  46897. if (avcSample && units.length && !track.audFound) {
  46898. pushAccessUnit(avcSample, track);
  46899. avcSample = this.avcSample = createAVCSample(false, pes.pts, pes.dts, '');
  46900. }
  46901. units.forEach(function (unit) {
  46902. switch (unit.type) {
  46903. // NDR
  46904. case 1:
  46905. {
  46906. push = true;
  46907. if (!avcSample) {
  46908. avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
  46909. }
  46910. if (debug) {
  46911. avcSample.debug += 'NDR ';
  46912. }
  46913. avcSample.frame = true;
  46914. var data = unit.data;
  46915. // only check slice type to detect KF in case SPS found in same packet (any keyframe is preceded by SPS ...)
  46916. if (spsfound && data.length > 4) {
  46917. // retrieve slice type by parsing beginning of NAL unit (follow H264 spec, slice_header definition) to detect keyframe embedded in NDR
  46918. var sliceType = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](data).readSliceType();
  46919. // 2 : I slice, 4 : SI slice, 7 : I slice, 9: SI slice
  46920. // SI slice : A slice that is coded using intra prediction only and using quantisation of the prediction samples.
  46921. // An SI slice can be coded such that its decoded samples can be constructed identically to an SP slice.
  46922. // I slice: A slice that is not an SI slice that is decoded using intra prediction only.
  46923. // if (sliceType === 2 || sliceType === 7) {
  46924. if (sliceType === 2 || sliceType === 4 || sliceType === 7 || sliceType === 9) {
  46925. avcSample.key = true;
  46926. }
  46927. }
  46928. break;
  46929. // IDR
  46930. }
  46931. case 5:
  46932. push = true;
  46933. // handle PES not starting with AUD
  46934. if (!avcSample) {
  46935. avcSample = _this.avcSample = createAVCSample(true, pes.pts, pes.dts, '');
  46936. }
  46937. if (debug) {
  46938. avcSample.debug += 'IDR ';
  46939. }
  46940. avcSample.key = true;
  46941. avcSample.frame = true;
  46942. break;
  46943. // SEI
  46944. case 6:
  46945. {
  46946. push = true;
  46947. if (debug && avcSample) {
  46948. avcSample.debug += 'SEI ';
  46949. }
  46950. (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_5__.parseSEIMessageFromNALu)(unit.data, 1, pes.pts, textTrack.samples);
  46951. break;
  46952. // SPS
  46953. }
  46954. case 7:
  46955. push = true;
  46956. spsfound = true;
  46957. if (debug && avcSample) {
  46958. avcSample.debug += 'SPS ';
  46959. }
  46960. if (!track.sps) {
  46961. var expGolombDecoder = new _exp_golomb__WEBPACK_IMPORTED_MODULE_2__["default"](unit.data);
  46962. var config = expGolombDecoder.readSPS();
  46963. track.width = config.width;
  46964. track.height = config.height;
  46965. track.pixelRatio = config.pixelRatio;
  46966. // TODO: `track.sps` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`.
  46967. track.sps = [unit.data];
  46968. track.duration = _this._duration;
  46969. var codecarray = unit.data.subarray(1, 4);
  46970. var codecstring = 'avc1.';
  46971. for (var i = 0; i < 3; i++) {
  46972. var h = codecarray[i].toString(16);
  46973. if (h.length < 2) {
  46974. h = '0' + h;
  46975. }
  46976. codecstring += h;
  46977. }
  46978. track.codec = codecstring;
  46979. }
  46980. break;
  46981. // PPS
  46982. case 8:
  46983. push = true;
  46984. if (debug && avcSample) {
  46985. avcSample.debug += 'PPS ';
  46986. }
  46987. if (!track.pps) {
  46988. // TODO: `track.pss` is defined as a `number[]`, but we're setting it to a `Uint8Array[]`.
  46989. track.pps = [unit.data];
  46990. }
  46991. break;
  46992. // AUD
  46993. case 9:
  46994. push = false;
  46995. track.audFound = true;
  46996. if (avcSample) {
  46997. pushAccessUnit(avcSample, track);
  46998. }
  46999. avcSample = _this.avcSample = createAVCSample(false, pes.pts, pes.dts, debug ? 'AUD ' : '');
  47000. break;
  47001. // Filler Data
  47002. case 12:
  47003. push = true;
  47004. break;
  47005. default:
  47006. push = false;
  47007. if (avcSample) {
  47008. avcSample.debug += 'unknown NAL ' + unit.type + ' ';
  47009. }
  47010. break;
  47011. }
  47012. if (avcSample && push) {
  47013. var _units = avcSample.units;
  47014. _units.push(unit);
  47015. }
  47016. });
  47017. // if last PES packet, push samples
  47018. if (last && avcSample) {
  47019. pushAccessUnit(avcSample, track);
  47020. this.avcSample = null;
  47021. }
  47022. };
  47023. _proto.getLastNalUnit = function getLastNalUnit(samples) {
  47024. var _avcSample;
  47025. var avcSample = this.avcSample;
  47026. var lastUnit;
  47027. // try to fallback to previous sample if current one is empty
  47028. if (!avcSample || avcSample.units.length === 0) {
  47029. avcSample = samples[samples.length - 1];
  47030. }
  47031. if ((_avcSample = avcSample) !== null && _avcSample !== void 0 && _avcSample.units) {
  47032. var units = avcSample.units;
  47033. lastUnit = units[units.length - 1];
  47034. }
  47035. return lastUnit;
  47036. };
  47037. _proto.parseAVCNALu = function parseAVCNALu(track, array) {
  47038. var len = array.byteLength;
  47039. var state = track.naluState || 0;
  47040. var lastState = state;
  47041. var units = [];
  47042. var i = 0;
  47043. var value;
  47044. var overflow;
  47045. var unitType;
  47046. var lastUnitStart = -1;
  47047. var lastUnitType = 0;
  47048. // logger.log('PES:' + Hex.hexDump(array));
  47049. if (state === -1) {
  47050. // special use case where we found 3 or 4-byte start codes exactly at the end of previous PES packet
  47051. lastUnitStart = 0;
  47052. // NALu type is value read from offset 0
  47053. lastUnitType = array[0] & 0x1f;
  47054. state = 0;
  47055. i = 1;
  47056. }
  47057. while (i < len) {
  47058. value = array[i++];
  47059. // optimization. state 0 and 1 are the predominant case. let's handle them outside of the switch/case
  47060. if (!state) {
  47061. state = value ? 0 : 1;
  47062. continue;
  47063. }
  47064. if (state === 1) {
  47065. state = value ? 0 : 2;
  47066. continue;
  47067. }
  47068. // here we have state either equal to 2 or 3
  47069. if (!value) {
  47070. state = 3;
  47071. } else if (value === 1) {
  47072. if (lastUnitStart >= 0) {
  47073. var unit = {
  47074. data: array.subarray(lastUnitStart, i - state - 1),
  47075. type: lastUnitType
  47076. };
  47077. // logger.log('pushing NALU, type/size:' + unit.type + '/' + unit.data.byteLength);
  47078. units.push(unit);
  47079. } else {
  47080. // lastUnitStart is undefined => this is the first start code found in this PES packet
  47081. // first check if start code delimiter is overlapping between 2 PES packets,
  47082. // ie it started in last packet (lastState not zero)
  47083. // and ended at the beginning of this PES packet (i <= 4 - lastState)
  47084. var lastUnit = this.getLastNalUnit(track.samples);
  47085. if (lastUnit) {
  47086. if (lastState && i <= 4 - lastState) {
  47087. // start delimiter overlapping between PES packets
  47088. // strip start delimiter bytes from the end of last NAL unit
  47089. // check if lastUnit had a state different from zero
  47090. if (lastUnit.state) {
  47091. // strip last bytes
  47092. lastUnit.data = lastUnit.data.subarray(0, lastUnit.data.byteLength - lastState);
  47093. }
  47094. }
  47095. // If NAL units are not starting right at the beginning of the PES packet, push preceding data into previous NAL unit.
  47096. overflow = i - state - 1;
  47097. if (overflow > 0) {
  47098. // logger.log('first NALU found with overflow:' + overflow);
  47099. var tmp = new Uint8Array(lastUnit.data.byteLength + overflow);
  47100. tmp.set(lastUnit.data, 0);
  47101. tmp.set(array.subarray(0, overflow), lastUnit.data.byteLength);
  47102. lastUnit.data = tmp;
  47103. lastUnit.state = 0;
  47104. }
  47105. }
  47106. }
  47107. // check if we can read unit type
  47108. if (i < len) {
  47109. unitType = array[i] & 0x1f;
  47110. // logger.log('find NALU @ offset:' + i + ',type:' + unitType);
  47111. lastUnitStart = i;
  47112. lastUnitType = unitType;
  47113. state = 0;
  47114. } else {
  47115. // not enough byte to read unit type. let's read it on next PES parsing
  47116. state = -1;
  47117. }
  47118. } else {
  47119. state = 0;
  47120. }
  47121. }
  47122. if (lastUnitStart >= 0 && state >= 0) {
  47123. var _unit = {
  47124. data: array.subarray(lastUnitStart, len),
  47125. type: lastUnitType,
  47126. state: state
  47127. };
  47128. units.push(_unit);
  47129. // logger.log('pushing NALU, type/size/state:' + unit.type + '/' + unit.data.byteLength + '/' + state);
  47130. }
  47131. // no NALu found
  47132. if (units.length === 0) {
  47133. // append pes.data to previous NAL unit
  47134. var _lastUnit = this.getLastNalUnit(track.samples);
  47135. if (_lastUnit) {
  47136. var _tmp = new Uint8Array(_lastUnit.data.byteLength + array.byteLength);
  47137. _tmp.set(_lastUnit.data, 0);
  47138. _tmp.set(array, _lastUnit.data.byteLength);
  47139. _lastUnit.data = _tmp;
  47140. }
  47141. }
  47142. track.naluState = state;
  47143. return units;
  47144. };
  47145. _proto.parseAACPES = function parseAACPES(track, pes) {
  47146. var startOffset = 0;
  47147. var aacOverFlow = this.aacOverFlow;
  47148. var data = pes.data;
  47149. if (aacOverFlow) {
  47150. this.aacOverFlow = null;
  47151. var frameMissingBytes = aacOverFlow.missing;
  47152. var sampleLength = aacOverFlow.sample.unit.byteLength;
  47153. // logger.log(`AAC: append overflowing ${sampleLength} bytes to beginning of new PES`);
  47154. if (frameMissingBytes === -1) {
  47155. var tmp = new Uint8Array(sampleLength + data.byteLength);
  47156. tmp.set(aacOverFlow.sample.unit, 0);
  47157. tmp.set(data, sampleLength);
  47158. data = tmp;
  47159. } else {
  47160. var frameOverflowBytes = sampleLength - frameMissingBytes;
  47161. aacOverFlow.sample.unit.set(data.subarray(0, frameMissingBytes), frameOverflowBytes);
  47162. track.samples.push(aacOverFlow.sample);
  47163. startOffset = aacOverFlow.missing;
  47164. }
  47165. }
  47166. // look for ADTS header (0xFFFx)
  47167. var offset;
  47168. var len;
  47169. for (offset = startOffset, len = data.length; offset < len - 1; offset++) {
  47170. if (_adts__WEBPACK_IMPORTED_MODULE_0__.isHeader(data, offset)) {
  47171. break;
  47172. }
  47173. }
  47174. // if ADTS header does not start straight from the beginning of the PES payload, raise an error
  47175. if (offset !== startOffset) {
  47176. var reason;
  47177. var fatal;
  47178. if (offset < len - 1) {
  47179. reason = "AAC PES did not start with ADTS header,offset:" + offset;
  47180. fatal = false;
  47181. } else {
  47182. reason = 'no ADTS header found in AAC PES';
  47183. fatal = true;
  47184. }
  47185. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn("parsing error:" + reason);
  47186. this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR, _events__WEBPACK_IMPORTED_MODULE_4__.Events.ERROR, {
  47187. type: _errors__WEBPACK_IMPORTED_MODULE_7__.ErrorTypes.MEDIA_ERROR,
  47188. details: _errors__WEBPACK_IMPORTED_MODULE_7__.ErrorDetails.FRAG_PARSING_ERROR,
  47189. fatal: fatal,
  47190. reason: reason
  47191. });
  47192. if (fatal) {
  47193. return;
  47194. }
  47195. }
  47196. _adts__WEBPACK_IMPORTED_MODULE_0__.initTrackConfig(track, this.observer, data, offset, this.audioCodec);
  47197. var pts;
  47198. if (pes.pts !== undefined) {
  47199. pts = pes.pts;
  47200. } else if (aacOverFlow) {
  47201. // if last AAC frame is overflowing, we should ensure timestamps are contiguous:
  47202. // first sample PTS should be equal to last sample PTS + frameDuration
  47203. var frameDuration = _adts__WEBPACK_IMPORTED_MODULE_0__.getFrameDuration(track.samplerate);
  47204. pts = aacOverFlow.sample.pts + frameDuration;
  47205. } else {
  47206. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('[tsdemuxer]: AAC PES unknown PTS');
  47207. return;
  47208. }
  47209. // scan for aac samples
  47210. var frameIndex = 0;
  47211. var frame;
  47212. while (offset < len) {
  47213. frame = _adts__WEBPACK_IMPORTED_MODULE_0__.appendFrame(track, data, offset, pts, frameIndex);
  47214. offset += frame.length;
  47215. if (!frame.missing) {
  47216. frameIndex++;
  47217. for (; offset < len - 1; offset++) {
  47218. if (_adts__WEBPACK_IMPORTED_MODULE_0__.isHeader(data, offset)) {
  47219. break;
  47220. }
  47221. }
  47222. } else {
  47223. this.aacOverFlow = frame;
  47224. break;
  47225. }
  47226. }
  47227. };
  47228. _proto.parseMPEGPES = function parseMPEGPES(track, pes) {
  47229. var data = pes.data;
  47230. var length = data.length;
  47231. var frameIndex = 0;
  47232. var offset = 0;
  47233. var pts = pes.pts;
  47234. if (pts === undefined) {
  47235. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('[tsdemuxer]: MPEG PES unknown PTS');
  47236. return;
  47237. }
  47238. while (offset < length) {
  47239. if (_mpegaudio__WEBPACK_IMPORTED_MODULE_1__.isHeader(data, offset)) {
  47240. var frame = _mpegaudio__WEBPACK_IMPORTED_MODULE_1__.appendFrame(track, data, offset, pts, frameIndex);
  47241. if (frame) {
  47242. offset += frame.length;
  47243. frameIndex++;
  47244. } else {
  47245. // logger.log('Unable to parse Mpeg audio frame');
  47246. break;
  47247. }
  47248. } else {
  47249. // nothing found, keep looking
  47250. offset++;
  47251. }
  47252. }
  47253. };
  47254. _proto.parseID3PES = function parseID3PES(id3Track, pes) {
  47255. if (pes.pts === undefined) {
  47256. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('[tsdemuxer]: ID3 PES unknown PTS');
  47257. return;
  47258. }
  47259. var id3Sample = _extends({}, pes, {
  47260. type: this._avcTrack ? _types_demuxer__WEBPACK_IMPORTED_MODULE_8__.MetadataSchema.emsg : _types_demuxer__WEBPACK_IMPORTED_MODULE_8__.MetadataSchema.audioId3,
  47261. duration: Number.POSITIVE_INFINITY
  47262. });
  47263. id3Track.samples.push(id3Sample);
  47264. };
  47265. return TSDemuxer;
  47266. }();
  47267. function createAVCSample(key, pts, dts, debug) {
  47268. return {
  47269. key: key,
  47270. frame: false,
  47271. pts: pts,
  47272. dts: dts,
  47273. units: [],
  47274. debug: debug,
  47275. length: 0
  47276. };
  47277. }
  47278. function parsePID(data, offset) {
  47279. // pid is a 13-bit field starting at the last bit of TS[1]
  47280. return ((data[offset + 1] & 0x1f) << 8) + data[offset + 2];
  47281. }
  47282. function parsePAT(data, offset) {
  47283. // skip the PSI header and parse the first PMT entry
  47284. return (data[offset + 10] & 0x1f) << 8 | data[offset + 11];
  47285. }
  47286. function parsePMT(data, offset, typeSupported, isSampleAes) {
  47287. var result = {
  47288. audio: -1,
  47289. avc: -1,
  47290. id3: -1,
  47291. segmentCodec: 'aac'
  47292. };
  47293. var sectionLength = (data[offset + 1] & 0x0f) << 8 | data[offset + 2];
  47294. var tableEnd = offset + 3 + sectionLength - 4;
  47295. // to determine where the table is, we have to figure out how
  47296. // long the program info descriptors are
  47297. var programInfoLength = (data[offset + 10] & 0x0f) << 8 | data[offset + 11];
  47298. // advance the offset to the first entry in the mapping table
  47299. offset += 12 + programInfoLength;
  47300. while (offset < tableEnd) {
  47301. var pid = parsePID(data, offset);
  47302. switch (data[offset]) {
  47303. case 0xcf:
  47304. // SAMPLE-AES AAC
  47305. if (!isSampleAes) {
  47306. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('ADTS AAC with AES-128-CBC frame encryption found in unencrypted stream');
  47307. break;
  47308. }
  47309. /* falls through */
  47310. case 0x0f:
  47311. // ISO/IEC 13818-7 ADTS AAC (MPEG-2 lower bit-rate audio)
  47312. // logger.log('AAC PID:' + pid);
  47313. if (result.audio === -1) {
  47314. result.audio = pid;
  47315. }
  47316. break;
  47317. // Packetized metadata (ID3)
  47318. case 0x15:
  47319. // logger.log('ID3 PID:' + pid);
  47320. if (result.id3 === -1) {
  47321. result.id3 = pid;
  47322. }
  47323. break;
  47324. case 0xdb:
  47325. // SAMPLE-AES AVC
  47326. if (!isSampleAes) {
  47327. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('H.264 with AES-128-CBC slice encryption found in unencrypted stream');
  47328. break;
  47329. }
  47330. /* falls through */
  47331. case 0x1b:
  47332. // ITU-T Rec. H.264 and ISO/IEC 14496-10 (lower bit-rate video)
  47333. // logger.log('AVC PID:' + pid);
  47334. if (result.avc === -1) {
  47335. result.avc = pid;
  47336. }
  47337. break;
  47338. // ISO/IEC 11172-3 (MPEG-1 audio)
  47339. // or ISO/IEC 13818-3 (MPEG-2 halved sample rate audio)
  47340. case 0x03:
  47341. case 0x04:
  47342. // logger.log('MPEG PID:' + pid);
  47343. if (typeSupported.mpeg !== true && typeSupported.mp3 !== true) {
  47344. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log('MPEG audio found, not supported in this browser');
  47345. } else if (result.audio === -1) {
  47346. result.audio = pid;
  47347. result.segmentCodec = 'mp3';
  47348. }
  47349. break;
  47350. case 0x24:
  47351. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn('Unsupported HEVC stream type found');
  47352. break;
  47353. default:
  47354. // logger.log('unknown stream type:' + data[offset]);
  47355. break;
  47356. }
  47357. // move to the next table entry
  47358. // skip past the elementary stream descriptors, if present
  47359. offset += ((data[offset + 3] & 0x0f) << 8 | data[offset + 4]) + 5;
  47360. }
  47361. return result;
  47362. }
  47363. function parsePES(stream) {
  47364. var i = 0;
  47365. var frag;
  47366. var pesLen;
  47367. var pesHdrLen;
  47368. var pesPts;
  47369. var pesDts;
  47370. var data = stream.data;
  47371. // safety check
  47372. if (!stream || stream.size === 0) {
  47373. return null;
  47374. }
  47375. // we might need up to 19 bytes to read PES header
  47376. // if first chunk of data is less than 19 bytes, let's merge it with following ones until we get 19 bytes
  47377. // usually only one merge is needed (and this is rare ...)
  47378. while (data[0].length < 19 && data.length > 1) {
  47379. var newData = new Uint8Array(data[0].length + data[1].length);
  47380. newData.set(data[0]);
  47381. newData.set(data[1], data[0].length);
  47382. data[0] = newData;
  47383. data.splice(1, 1);
  47384. }
  47385. // retrieve PTS/DTS from first fragment
  47386. frag = data[0];
  47387. var pesPrefix = (frag[0] << 16) + (frag[1] << 8) + frag[2];
  47388. if (pesPrefix === 1) {
  47389. pesLen = (frag[4] << 8) + frag[5];
  47390. // if PES parsed length is not zero and greater than total received length, stop parsing. PES might be truncated
  47391. // minus 6 : PES header size
  47392. if (pesLen && pesLen > stream.size - 6) {
  47393. return null;
  47394. }
  47395. var pesFlags = frag[7];
  47396. if (pesFlags & 0xc0) {
  47397. /* PES header described here : http://dvd.sourceforge.net/dvdinfo/pes-hdr.html
  47398. as PTS / DTS is 33 bit we cannot use bitwise operator in JS,
  47399. as Bitwise operators treat their operands as a sequence of 32 bits */
  47400. pesPts = (frag[9] & 0x0e) * 536870912 +
  47401. // 1 << 29
  47402. (frag[10] & 0xff) * 4194304 +
  47403. // 1 << 22
  47404. (frag[11] & 0xfe) * 16384 +
  47405. // 1 << 14
  47406. (frag[12] & 0xff) * 128 +
  47407. // 1 << 7
  47408. (frag[13] & 0xfe) / 2;
  47409. if (pesFlags & 0x40) {
  47410. pesDts = (frag[14] & 0x0e) * 536870912 +
  47411. // 1 << 29
  47412. (frag[15] & 0xff) * 4194304 +
  47413. // 1 << 22
  47414. (frag[16] & 0xfe) * 16384 +
  47415. // 1 << 14
  47416. (frag[17] & 0xff) * 128 +
  47417. // 1 << 7
  47418. (frag[18] & 0xfe) / 2;
  47419. if (pesPts - pesDts > 60 * 90000) {
  47420. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.warn(Math.round((pesPts - pesDts) / 90000) + "s delta between PTS and DTS, align them");
  47421. pesPts = pesDts;
  47422. }
  47423. } else {
  47424. pesDts = pesPts;
  47425. }
  47426. }
  47427. pesHdrLen = frag[8];
  47428. // 9 bytes : 6 bytes for PES header + 3 bytes for PES extension
  47429. var payloadStartOffset = pesHdrLen + 9;
  47430. if (stream.size <= payloadStartOffset) {
  47431. return null;
  47432. }
  47433. stream.size -= payloadStartOffset;
  47434. // reassemble PES packet
  47435. var pesData = new Uint8Array(stream.size);
  47436. for (var j = 0, dataLen = data.length; j < dataLen; j++) {
  47437. frag = data[j];
  47438. var len = frag.byteLength;
  47439. if (payloadStartOffset) {
  47440. if (payloadStartOffset > len) {
  47441. // trim full frag if PES header bigger than frag
  47442. payloadStartOffset -= len;
  47443. continue;
  47444. } else {
  47445. // trim partial frag if PES header smaller than frag
  47446. frag = frag.subarray(payloadStartOffset);
  47447. len -= payloadStartOffset;
  47448. payloadStartOffset = 0;
  47449. }
  47450. }
  47451. pesData.set(frag, i);
  47452. i += len;
  47453. }
  47454. if (pesLen) {
  47455. // payload size : remove PES header + PES extension
  47456. pesLen -= pesHdrLen + 3;
  47457. }
  47458. return {
  47459. data: pesData,
  47460. pts: pesPts,
  47461. dts: pesDts,
  47462. len: pesLen
  47463. };
  47464. }
  47465. return null;
  47466. }
  47467. function pushAccessUnit(avcSample, avcTrack) {
  47468. if (avcSample.units.length && avcSample.frame) {
  47469. // if sample does not have PTS/DTS, patch with last sample PTS/DTS
  47470. if (avcSample.pts === undefined) {
  47471. var samples = avcTrack.samples;
  47472. var nbSamples = samples.length;
  47473. if (nbSamples) {
  47474. var lastSample = samples[nbSamples - 1];
  47475. avcSample.pts = lastSample.pts;
  47476. avcSample.dts = lastSample.dts;
  47477. } else {
  47478. // dropping samples, no timestamp found
  47479. avcTrack.dropped++;
  47480. return;
  47481. }
  47482. }
  47483. avcTrack.samples.push(avcSample);
  47484. }
  47485. if (avcSample.debug.length) {
  47486. _utils_logger__WEBPACK_IMPORTED_MODULE_6__.logger.log(avcSample.pts + '/' + avcSample.dts + ':' + avcSample.debug);
  47487. }
  47488. }
  47489. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (TSDemuxer);
  47490. /***/ }),
  47491. /***/ "./src/demux/webworkify-webpack.js":
  47492. /*!*****************************************!*\
  47493. !*** ./src/demux/webworkify-webpack.js ***!
  47494. \*****************************************/
  47495. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  47496. "use strict";
  47497. __webpack_require__.r(__webpack_exports__);
  47498. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  47499. /* harmony export */ "default": () => (/* export default binding */ __WEBPACK_DEFAULT_EXPORT__)
  47500. /* harmony export */ });
  47501. /*
  47502. * Fork of webworkify-webpack with support for Webpack 5
  47503. * https://github.com/wupeng-engineer/webworkify-webpack/blob/db0de7/index.js
  47504. */
  47505. var webpackBootstrapFunc = function webpackBootstrapFunc() {
  47506. // webpackBootstrap
  47507. /******/
  47508. var __webpack_modules__ = ENTRY_MODULE;
  47509. /************************************************************************/
  47510. /******/ // The module cache
  47511. /******/
  47512. var __webpack_module_cache__ = {};
  47513. /******/
  47514. /******/ // The require function
  47515. /******/
  47516. var __nested_webpack_require_497__ = function __webpack_require__(moduleId) {
  47517. /******/ // Check if module is in cache
  47518. /******/var cachedModule = __webpack_module_cache__[moduleId];
  47519. /******/
  47520. if (cachedModule !== undefined) {
  47521. /******/return cachedModule.exports;
  47522. /******/
  47523. }
  47524. /******/ // Create a new module (and put it into the cache)
  47525. /******/
  47526. var module = __webpack_module_cache__[moduleId] = {
  47527. /******/ // no module.id needed
  47528. /******/ // no module.loaded needed
  47529. /******/exports: {}
  47530. /******/
  47531. };
  47532. /******/
  47533. /******/ // Execute the module function
  47534. /******/
  47535. __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  47536. /******/
  47537. /******/ // Return the exports of the module
  47538. /******/
  47539. return module.exports;
  47540. /******/
  47541. };
  47542. /******/
  47543. /******/ // expose the modules object (__webpack_modules__)
  47544. /******/
  47545. __nested_webpack_require_497__.m = __webpack_modules__;
  47546. /******/
  47547. /************************************************************************/
  47548. /******/ /* webpack/runtime/compat get default export */
  47549. /******/
  47550. (function () {
  47551. /******/ // getDefaultExport function for compatibility with non-harmony modules
  47552. /******/__nested_webpack_require_497__.n = function (module) {
  47553. /******/var getter = module && module.__esModule ? /******/function () {
  47554. return module['default'];
  47555. } : /******/function () {
  47556. return module;
  47557. };
  47558. /******/
  47559. __nested_webpack_require_497__.d(getter, {
  47560. a: getter
  47561. });
  47562. /******/
  47563. return getter;
  47564. /******/
  47565. };
  47566. /******/
  47567. })();
  47568. /******/
  47569. /******/ /* webpack/runtime/define property getters */
  47570. /******/
  47571. (function () {
  47572. /******/ // define getter functions for harmony exports
  47573. /******/__nested_webpack_require_497__.d = function (exports, definition) {
  47574. /******/for (var key in definition) {
  47575. /******/if (__nested_webpack_require_497__.o(definition, key) && !__nested_webpack_require_497__.o(exports, key)) {
  47576. /******/Object.defineProperty(exports, key, {
  47577. enumerable: true,
  47578. get: definition[key]
  47579. });
  47580. /******/
  47581. }
  47582. /******/
  47583. }
  47584. /******/
  47585. };
  47586. /******/
  47587. })();
  47588. /******/
  47589. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  47590. /******/
  47591. (function () {
  47592. /******/__nested_webpack_require_497__.o = function (obj, prop) {
  47593. return Object.prototype.hasOwnProperty.call(obj, prop);
  47594. };
  47595. /******/
  47596. })();
  47597. /******/
  47598. /******/ /* webpack/runtime/make namespace object */
  47599. /******/
  47600. (function () {
  47601. /******/ // define __esModule on exports
  47602. /******/__nested_webpack_require_497__.r = function (exports) {
  47603. /******/if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  47604. /******/Object.defineProperty(exports, Symbol.toStringTag, {
  47605. value: 'Module'
  47606. });
  47607. /******/
  47608. }
  47609. /******/
  47610. Object.defineProperty(exports, '__esModule', {
  47611. value: true
  47612. });
  47613. /******/
  47614. };
  47615. /******/
  47616. })();
  47617. /******/
  47618. /************************************************************************/
  47619. /******/
  47620. /******/ // module factories are used so entry inlining is disabled
  47621. /******/ // startup
  47622. /******/ // Load entry module and return exports
  47623. /******/
  47624. var result = __nested_webpack_require_497__(ENTRY_MODULE);
  47625. /******/
  47626. return result.default || result;
  47627. };
  47628. var webpackBootstrapFuncArr = webpackBootstrapFunc.toString().split('ENTRY_MODULE');
  47629. var moduleNameReqExp = '[\\.|\\-|\\+|\\w|\/|@]+';
  47630. var dependencyRegExp = '\\(\\s*(\/\\*.*?\\*\/)?\\s*.*?(' + moduleNameReqExp + ').*?\\)';
  47631. function quoteRegExp(str) {
  47632. return (str + '').replace(/[.?*+^$[\]\\(){}|-]/g, '\\$&');
  47633. }
  47634. function isNumeric(n) {
  47635. return !isNaN(1 * n);
  47636. }
  47637. function getModuleDependencies(sources, module, queueName) {
  47638. var retval = {};
  47639. retval[queueName] = [];
  47640. var fnString = module.toString().replace(/^"[^"]+"/, 'function');
  47641. ;
  47642. var wrapperSignature = fnString.match(/^function\s?\w*\(\w+,\s*\w+,\s*(\w+)\)/) || fnString.match(/^\(\w+,\s*\w+,\s*(\w+)\)\s?\=\s?\>/);
  47643. if (!wrapperSignature) return retval;
  47644. var webpackRequireName = wrapperSignature[1];
  47645. var re = new RegExp('(\\\\n|\\W)' + quoteRegExp(webpackRequireName) + dependencyRegExp, 'g');
  47646. var match;
  47647. while (match = re.exec(fnString)) {
  47648. if (match[3] === 'dll-reference') continue;
  47649. retval[queueName].push(match[3]);
  47650. }
  47651. re = new RegExp('\\(' + quoteRegExp(webpackRequireName) + '\\("(dll-reference\\s(' + moduleNameReqExp + '))"\\)\\)' + dependencyRegExp, 'g');
  47652. while (match = re.exec(fnString)) {
  47653. if (!sources[match[2]]) {
  47654. retval[queueName].push(match[1]);
  47655. sources[match[2]] = __webpack_require__(match[1]).m;
  47656. }
  47657. retval[match[2]] = retval[match[2]] || [];
  47658. retval[match[2]].push(match[4]);
  47659. }
  47660. var keys = Object.keys(retval);
  47661. for (var i = 0; i < keys.length; i++) {
  47662. for (var j = 0; j < retval[keys[i]].length; j++) {
  47663. if (isNumeric(retval[keys[i]][j])) {
  47664. retval[keys[i]][j] = 1 * retval[keys[i]][j];
  47665. }
  47666. }
  47667. }
  47668. return retval;
  47669. }
  47670. function hasValuesInQueues(queues) {
  47671. var keys = Object.keys(queues);
  47672. return keys.reduce(function (hasValues, key) {
  47673. return hasValues || queues[key].length > 0;
  47674. }, false);
  47675. }
  47676. function getRequiredModules(sources, moduleId) {
  47677. var modulesQueue = {
  47678. main: [moduleId]
  47679. };
  47680. var requiredModules = {
  47681. main: []
  47682. };
  47683. var seenModules = {
  47684. main: {}
  47685. };
  47686. while (hasValuesInQueues(modulesQueue)) {
  47687. var queues = Object.keys(modulesQueue);
  47688. for (var i = 0; i < queues.length; i++) {
  47689. var queueName = queues[i];
  47690. var queue = modulesQueue[queueName];
  47691. var moduleToCheck = queue.pop();
  47692. seenModules[queueName] = seenModules[queueName] || {};
  47693. if (seenModules[queueName][moduleToCheck] || !sources[queueName][moduleToCheck]) continue;
  47694. seenModules[queueName][moduleToCheck] = true;
  47695. requiredModules[queueName] = requiredModules[queueName] || [];
  47696. requiredModules[queueName].push(moduleToCheck);
  47697. var newModules = getModuleDependencies(sources, sources[queueName][moduleToCheck], queueName);
  47698. var newModulesKeys = Object.keys(newModules);
  47699. for (var j = 0; j < newModulesKeys.length; j++) {
  47700. modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]] || [];
  47701. modulesQueue[newModulesKeys[j]] = modulesQueue[newModulesKeys[j]].concat(newModules[newModulesKeys[j]]);
  47702. }
  47703. }
  47704. }
  47705. return requiredModules;
  47706. }
  47707. function getWebpackString(requiredModules, sources, entryModule, key) {
  47708. var moduleString = requiredModules[key].map(function (id) {
  47709. return "\"" + id + "\": " + sources[key][id].toString().replace(/^"[^"]+"/, 'function');
  47710. }).join(",");
  47711. return webpackBootstrapFuncArr[0] + "{" + moduleString + "}" + webpackBootstrapFuncArr[1] + "\"" + entryModule + "\"" + webpackBootstrapFuncArr[2];
  47712. }
  47713. /* harmony default export */ function __WEBPACK_DEFAULT_EXPORT__(moduleId, options) {
  47714. options = options || {};
  47715. var sources = {
  47716. main: __webpack_require__.m
  47717. };
  47718. var requiredModules = options.all ? {
  47719. main: Object.keys(sources.main)
  47720. } : getRequiredModules(sources, moduleId);
  47721. var src = '';
  47722. Object.keys(requiredModules).filter(function (m) {
  47723. return m !== 'main';
  47724. }).forEach(function (module) {
  47725. var entryModule = 0;
  47726. while (requiredModules[module][entryModule]) {
  47727. entryModule++;
  47728. }
  47729. requiredModules[module].push(entryModule);
  47730. sources[module][entryModule] = '(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })';
  47731. src = src + ("var " + module + " = (" + getWebpackString(requiredModules, sources, entryModule, modules) + ")();\n");
  47732. });
  47733. src = src + ("new ((" + getWebpackString(requiredModules, sources, moduleId, 'main') + ")())(self);");
  47734. var blob = new window.Blob([src], {
  47735. type: 'text/javascript'
  47736. });
  47737. var URL = window.URL || window.webkitURL || window.mozURL || window.msURL;
  47738. var workerUrl = URL.createObjectURL(blob);
  47739. var worker = new window.Worker(workerUrl);
  47740. worker.objectURL = workerUrl;
  47741. return worker;
  47742. }
  47743. /***/ }),
  47744. /***/ "./src/errors.ts":
  47745. /*!***********************!*\
  47746. !*** ./src/errors.ts ***!
  47747. \***********************/
  47748. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  47749. "use strict";
  47750. __webpack_require__.r(__webpack_exports__);
  47751. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  47752. /* harmony export */ "ErrorDetails": () => (/* binding */ ErrorDetails),
  47753. /* harmony export */ "ErrorTypes": () => (/* binding */ ErrorTypes)
  47754. /* harmony export */ });
  47755. var ErrorTypes;
  47756. /**
  47757. * @enum {ErrorDetails}
  47758. * @typedef {string} ErrorDetail
  47759. */
  47760. (function (ErrorTypes) {
  47761. ErrorTypes["NETWORK_ERROR"] = "networkError";
  47762. ErrorTypes["MEDIA_ERROR"] = "mediaError";
  47763. ErrorTypes["KEY_SYSTEM_ERROR"] = "keySystemError";
  47764. ErrorTypes["MUX_ERROR"] = "muxError";
  47765. ErrorTypes["OTHER_ERROR"] = "otherError";
  47766. })(ErrorTypes || (ErrorTypes = {}));
  47767. var ErrorDetails;
  47768. (function (ErrorDetails) {
  47769. ErrorDetails["KEY_SYSTEM_NO_KEYS"] = "keySystemNoKeys";
  47770. ErrorDetails["KEY_SYSTEM_NO_ACCESS"] = "keySystemNoAccess";
  47771. ErrorDetails["KEY_SYSTEM_NO_SESSION"] = "keySystemNoSession";
  47772. ErrorDetails["KEY_SYSTEM_NO_CONFIGURED_LICENSE"] = "keySystemNoConfiguredLicense";
  47773. ErrorDetails["KEY_SYSTEM_LICENSE_REQUEST_FAILED"] = "keySystemLicenseRequestFailed";
  47774. ErrorDetails["KEY_SYSTEM_SERVER_CERTIFICATE_REQUEST_FAILED"] = "keySystemServerCertificateRequestFailed";
  47775. ErrorDetails["KEY_SYSTEM_SERVER_CERTIFICATE_UPDATE_FAILED"] = "keySystemServerCertificateUpdateFailed";
  47776. ErrorDetails["KEY_SYSTEM_SESSION_UPDATE_FAILED"] = "keySystemSessionUpdateFailed";
  47777. ErrorDetails["KEY_SYSTEM_STATUS_OUTPUT_RESTRICTED"] = "keySystemStatusOutputRestricted";
  47778. ErrorDetails["KEY_SYSTEM_STATUS_INTERNAL_ERROR"] = "keySystemStatusInternalError";
  47779. ErrorDetails["MANIFEST_LOAD_ERROR"] = "manifestLoadError";
  47780. ErrorDetails["MANIFEST_LOAD_TIMEOUT"] = "manifestLoadTimeOut";
  47781. ErrorDetails["MANIFEST_PARSING_ERROR"] = "manifestParsingError";
  47782. ErrorDetails["MANIFEST_INCOMPATIBLE_CODECS_ERROR"] = "manifestIncompatibleCodecsError";
  47783. ErrorDetails["LEVEL_EMPTY_ERROR"] = "levelEmptyError";
  47784. ErrorDetails["LEVEL_LOAD_ERROR"] = "levelLoadError";
  47785. ErrorDetails["LEVEL_LOAD_TIMEOUT"] = "levelLoadTimeOut";
  47786. ErrorDetails["LEVEL_SWITCH_ERROR"] = "levelSwitchError";
  47787. ErrorDetails["AUDIO_TRACK_LOAD_ERROR"] = "audioTrackLoadError";
  47788. ErrorDetails["AUDIO_TRACK_LOAD_TIMEOUT"] = "audioTrackLoadTimeOut";
  47789. ErrorDetails["SUBTITLE_LOAD_ERROR"] = "subtitleTrackLoadError";
  47790. ErrorDetails["SUBTITLE_TRACK_LOAD_TIMEOUT"] = "subtitleTrackLoadTimeOut";
  47791. ErrorDetails["FRAG_LOAD_ERROR"] = "fragLoadError";
  47792. ErrorDetails["FRAG_LOAD_TIMEOUT"] = "fragLoadTimeOut";
  47793. ErrorDetails["FRAG_DECRYPT_ERROR"] = "fragDecryptError";
  47794. ErrorDetails["FRAG_PARSING_ERROR"] = "fragParsingError";
  47795. ErrorDetails["REMUX_ALLOC_ERROR"] = "remuxAllocError";
  47796. ErrorDetails["KEY_LOAD_ERROR"] = "keyLoadError";
  47797. ErrorDetails["KEY_LOAD_TIMEOUT"] = "keyLoadTimeOut";
  47798. ErrorDetails["BUFFER_ADD_CODEC_ERROR"] = "bufferAddCodecError";
  47799. ErrorDetails["BUFFER_INCOMPATIBLE_CODECS_ERROR"] = "bufferIncompatibleCodecsError";
  47800. ErrorDetails["BUFFER_APPEND_ERROR"] = "bufferAppendError";
  47801. ErrorDetails["BUFFER_APPENDING_ERROR"] = "bufferAppendingError";
  47802. ErrorDetails["BUFFER_STALLED_ERROR"] = "bufferStalledError";
  47803. ErrorDetails["BUFFER_FULL_ERROR"] = "bufferFullError";
  47804. ErrorDetails["BUFFER_SEEK_OVER_HOLE"] = "bufferSeekOverHole";
  47805. ErrorDetails["BUFFER_NUDGE_ON_STALL"] = "bufferNudgeOnStall";
  47806. ErrorDetails["INTERNAL_EXCEPTION"] = "internalException";
  47807. ErrorDetails["INTERNAL_ABORTED"] = "aborted";
  47808. ErrorDetails["UNKNOWN"] = "unknown";
  47809. })(ErrorDetails || (ErrorDetails = {}));
  47810. /***/ }),
  47811. /***/ "./src/events.ts":
  47812. /*!***********************!*\
  47813. !*** ./src/events.ts ***!
  47814. \***********************/
  47815. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  47816. "use strict";
  47817. __webpack_require__.r(__webpack_exports__);
  47818. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  47819. /* harmony export */ "Events": () => (/* binding */ Events)
  47820. /* harmony export */ });
  47821. /**
  47822. * @readonly
  47823. * @enum {string}
  47824. */
  47825. var Events;
  47826. (function (Events) {
  47827. Events["MEDIA_ATTACHING"] = "hlsMediaAttaching";
  47828. Events["MEDIA_ATTACHED"] = "hlsMediaAttached";
  47829. Events["MEDIA_DETACHING"] = "hlsMediaDetaching";
  47830. Events["MEDIA_DETACHED"] = "hlsMediaDetached";
  47831. Events["BUFFER_RESET"] = "hlsBufferReset";
  47832. Events["BUFFER_CODECS"] = "hlsBufferCodecs";
  47833. Events["BUFFER_CREATED"] = "hlsBufferCreated";
  47834. Events["BUFFER_APPENDING"] = "hlsBufferAppending";
  47835. Events["BUFFER_APPENDED"] = "hlsBufferAppended";
  47836. Events["BUFFER_EOS"] = "hlsBufferEos";
  47837. Events["BUFFER_FLUSHING"] = "hlsBufferFlushing";
  47838. Events["BUFFER_FLUSHED"] = "hlsBufferFlushed";
  47839. Events["MANIFEST_LOADING"] = "hlsManifestLoading";
  47840. Events["MANIFEST_LOADED"] = "hlsManifestLoaded";
  47841. Events["MANIFEST_PARSED"] = "hlsManifestParsed";
  47842. Events["LEVEL_SWITCHING"] = "hlsLevelSwitching";
  47843. Events["LEVEL_SWITCHED"] = "hlsLevelSwitched";
  47844. Events["LEVEL_LOADING"] = "hlsLevelLoading";
  47845. Events["LEVEL_LOADED"] = "hlsLevelLoaded";
  47846. Events["LEVEL_UPDATED"] = "hlsLevelUpdated";
  47847. Events["LEVEL_PTS_UPDATED"] = "hlsLevelPtsUpdated";
  47848. Events["LEVELS_UPDATED"] = "hlsLevelsUpdated";
  47849. Events["AUDIO_TRACKS_UPDATED"] = "hlsAudioTracksUpdated";
  47850. Events["AUDIO_TRACK_SWITCHING"] = "hlsAudioTrackSwitching";
  47851. Events["AUDIO_TRACK_SWITCHED"] = "hlsAudioTrackSwitched";
  47852. Events["AUDIO_TRACK_LOADING"] = "hlsAudioTrackLoading";
  47853. Events["AUDIO_TRACK_LOADED"] = "hlsAudioTrackLoaded";
  47854. Events["SUBTITLE_TRACKS_UPDATED"] = "hlsSubtitleTracksUpdated";
  47855. Events["SUBTITLE_TRACKS_CLEARED"] = "hlsSubtitleTracksCleared";
  47856. Events["SUBTITLE_TRACK_SWITCH"] = "hlsSubtitleTrackSwitch";
  47857. Events["SUBTITLE_TRACK_LOADING"] = "hlsSubtitleTrackLoading";
  47858. Events["SUBTITLE_TRACK_LOADED"] = "hlsSubtitleTrackLoaded";
  47859. Events["SUBTITLE_FRAG_PROCESSED"] = "hlsSubtitleFragProcessed";
  47860. Events["CUES_PARSED"] = "hlsCuesParsed";
  47861. Events["NON_NATIVE_TEXT_TRACKS_FOUND"] = "hlsNonNativeTextTracksFound";
  47862. Events["INIT_PTS_FOUND"] = "hlsInitPtsFound";
  47863. Events["FRAG_LOADING"] = "hlsFragLoading";
  47864. Events["FRAG_LOAD_EMERGENCY_ABORTED"] = "hlsFragLoadEmergencyAborted";
  47865. Events["FRAG_LOADED"] = "hlsFragLoaded";
  47866. Events["FRAG_DECRYPTED"] = "hlsFragDecrypted";
  47867. Events["FRAG_PARSING_INIT_SEGMENT"] = "hlsFragParsingInitSegment";
  47868. Events["FRAG_PARSING_USERDATA"] = "hlsFragParsingUserdata";
  47869. Events["FRAG_PARSING_METADATA"] = "hlsFragParsingMetadata";
  47870. Events["FRAG_PARSED"] = "hlsFragParsed";
  47871. Events["FRAG_BUFFERED"] = "hlsFragBuffered";
  47872. Events["FRAG_CHANGED"] = "hlsFragChanged";
  47873. Events["FPS_DROP"] = "hlsFpsDrop";
  47874. Events["FPS_DROP_LEVEL_CAPPING"] = "hlsFpsDropLevelCapping";
  47875. Events["ERROR"] = "hlsError";
  47876. Events["DESTROYING"] = "hlsDestroying";
  47877. Events["KEY_LOADING"] = "hlsKeyLoading";
  47878. Events["KEY_LOADED"] = "hlsKeyLoaded";
  47879. Events["LIVE_BACK_BUFFER_REACHED"] = "hlsLiveBackBufferReached";
  47880. Events["BACK_BUFFER_REACHED"] = "hlsBackBufferReached";
  47881. })(Events || (Events = {}));
  47882. /***/ }),
  47883. /***/ "./src/hls.ts":
  47884. /*!********************!*\
  47885. !*** ./src/hls.ts ***!
  47886. \********************/
  47887. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  47888. "use strict";
  47889. __webpack_require__.r(__webpack_exports__);
  47890. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  47891. /* harmony export */ "default": () => (/* binding */ Hls)
  47892. /* harmony export */ });
  47893. /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js");
  47894. /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_0__);
  47895. /* harmony import */ var _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./loader/playlist-loader */ "./src/loader/playlist-loader.ts");
  47896. /* harmony import */ var _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controller/id3-track-controller */ "./src/controller/id3-track-controller.ts");
  47897. /* harmony import */ var _controller_latency_controller__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./controller/latency-controller */ "./src/controller/latency-controller.ts");
  47898. /* harmony import */ var _controller_level_controller__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./controller/level-controller */ "./src/controller/level-controller.ts");
  47899. /* harmony import */ var _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./controller/fragment-tracker */ "./src/controller/fragment-tracker.ts");
  47900. /* harmony import */ var _loader_key_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./loader/key-loader */ "./src/loader/key-loader.ts");
  47901. /* harmony import */ var _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./controller/stream-controller */ "./src/controller/stream-controller.ts");
  47902. /* harmony import */ var _is_supported__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./is-supported */ "./src/is-supported.ts");
  47903. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./utils/logger */ "./src/utils/logger.ts");
  47904. /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./config */ "./src/config.ts");
  47905. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! eventemitter3 */ "./node_modules/eventemitter3/index.js");
  47906. /* harmony import */ var eventemitter3__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(eventemitter3__WEBPACK_IMPORTED_MODULE_11__);
  47907. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./events */ "./src/events.ts");
  47908. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./errors */ "./src/errors.ts");
  47909. /* harmony import */ var _types_level__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./types/level */ "./src/types/level.ts");
  47910. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  47911. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  47912. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  47913. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  47914. /**
  47915. * @module Hls
  47916. * @class
  47917. * @constructor
  47918. */
  47919. var Hls = /*#__PURE__*/function () {
  47920. Hls.isSupported = function isSupported() {
  47921. return (0,_is_supported__WEBPACK_IMPORTED_MODULE_8__.isSupported)();
  47922. };
  47923. /**
  47924. * Creates an instance of an HLS client that can attach to exactly one `HTMLMediaElement`.
  47925. *
  47926. * @constructs Hls
  47927. * @param {HlsConfig} config
  47928. */
  47929. function Hls(userConfig) {
  47930. if (userConfig === void 0) {
  47931. userConfig = {};
  47932. }
  47933. this.config = void 0;
  47934. this.userConfig = void 0;
  47935. this.coreComponents = void 0;
  47936. this.networkControllers = void 0;
  47937. this._emitter = new eventemitter3__WEBPACK_IMPORTED_MODULE_11__.EventEmitter();
  47938. this._autoLevelCapping = void 0;
  47939. this._maxHdcpLevel = null;
  47940. this.abrController = void 0;
  47941. this.bufferController = void 0;
  47942. this.capLevelController = void 0;
  47943. this.latencyController = void 0;
  47944. this.levelController = void 0;
  47945. this.streamController = void 0;
  47946. this.audioTrackController = void 0;
  47947. this.subtitleTrackController = void 0;
  47948. this.emeController = void 0;
  47949. this.cmcdController = void 0;
  47950. this._media = null;
  47951. this.url = null;
  47952. var config = this.config = (0,_config__WEBPACK_IMPORTED_MODULE_10__.mergeConfig)(Hls.DefaultConfig, userConfig);
  47953. this.userConfig = userConfig;
  47954. (0,_utils_logger__WEBPACK_IMPORTED_MODULE_9__.enableLogs)(config.debug, 'Hls instance');
  47955. this._autoLevelCapping = -1;
  47956. if (config.progressive) {
  47957. (0,_config__WEBPACK_IMPORTED_MODULE_10__.enableStreamingMode)(config);
  47958. }
  47959. // core controllers and network loaders
  47960. var ConfigAbrController = config.abrController,
  47961. ConfigBufferController = config.bufferController,
  47962. ConfigCapLevelController = config.capLevelController,
  47963. ConfigFpsController = config.fpsController;
  47964. var abrController = this.abrController = new ConfigAbrController(this);
  47965. var bufferController = this.bufferController = new ConfigBufferController(this);
  47966. var capLevelController = this.capLevelController = new ConfigCapLevelController(this);
  47967. var fpsController = new ConfigFpsController(this);
  47968. var playListLoader = new _loader_playlist_loader__WEBPACK_IMPORTED_MODULE_1__["default"](this);
  47969. var id3TrackController = new _controller_id3_track_controller__WEBPACK_IMPORTED_MODULE_2__["default"](this);
  47970. // network controllers
  47971. var levelController = this.levelController = new _controller_level_controller__WEBPACK_IMPORTED_MODULE_4__["default"](this);
  47972. // FragmentTracker must be defined before StreamController because the order of event handling is important
  47973. var fragmentTracker = new _controller_fragment_tracker__WEBPACK_IMPORTED_MODULE_5__.FragmentTracker(this);
  47974. var keyLoader = new _loader_key_loader__WEBPACK_IMPORTED_MODULE_6__["default"](this.config);
  47975. var streamController = this.streamController = new _controller_stream_controller__WEBPACK_IMPORTED_MODULE_7__["default"](this, fragmentTracker, keyLoader);
  47976. // Cap level controller uses streamController to flush the buffer
  47977. capLevelController.setStreamController(streamController);
  47978. // fpsController uses streamController to switch when frames are being dropped
  47979. fpsController.setStreamController(streamController);
  47980. var networkControllers = [playListLoader, levelController, streamController];
  47981. this.networkControllers = networkControllers;
  47982. var coreComponents = [abrController, bufferController, capLevelController, fpsController, id3TrackController, fragmentTracker];
  47983. this.audioTrackController = this.createController(config.audioTrackController, networkControllers);
  47984. var AudioStreamControllerClass = config.audioStreamController;
  47985. if (AudioStreamControllerClass) {
  47986. networkControllers.push(new AudioStreamControllerClass(this, fragmentTracker, keyLoader));
  47987. }
  47988. // subtitleTrackController must be defined before subtitleStreamController because the order of event handling is important
  47989. this.subtitleTrackController = this.createController(config.subtitleTrackController, networkControllers);
  47990. var SubtitleStreamControllerClass = config.subtitleStreamController;
  47991. if (SubtitleStreamControllerClass) {
  47992. networkControllers.push(new SubtitleStreamControllerClass(this, fragmentTracker, keyLoader));
  47993. }
  47994. this.createController(config.timelineController, coreComponents);
  47995. keyLoader.emeController = this.emeController = this.createController(config.emeController, coreComponents);
  47996. this.cmcdController = this.createController(config.cmcdController, coreComponents);
  47997. this.latencyController = this.createController(_controller_latency_controller__WEBPACK_IMPORTED_MODULE_3__["default"], coreComponents);
  47998. this.coreComponents = coreComponents;
  47999. }
  48000. var _proto = Hls.prototype;
  48001. _proto.createController = function createController(ControllerClass, components) {
  48002. if (ControllerClass) {
  48003. var controllerInstance = new ControllerClass(this);
  48004. if (components) {
  48005. components.push(controllerInstance);
  48006. }
  48007. return controllerInstance;
  48008. }
  48009. return null;
  48010. }
  48011. // Delegate the EventEmitter through the public API of Hls.js
  48012. ;
  48013. _proto.on = function on(event, listener, context) {
  48014. if (context === void 0) {
  48015. context = this;
  48016. }
  48017. this._emitter.on(event, listener, context);
  48018. };
  48019. _proto.once = function once(event, listener, context) {
  48020. if (context === void 0) {
  48021. context = this;
  48022. }
  48023. this._emitter.once(event, listener, context);
  48024. };
  48025. _proto.removeAllListeners = function removeAllListeners(event) {
  48026. this._emitter.removeAllListeners(event);
  48027. };
  48028. _proto.off = function off(event, listener, context, once) {
  48029. if (context === void 0) {
  48030. context = this;
  48031. }
  48032. this._emitter.off(event, listener, context, once);
  48033. };
  48034. _proto.listeners = function listeners(event) {
  48035. return this._emitter.listeners(event);
  48036. };
  48037. _proto.emit = function emit(event, name, eventObject) {
  48038. return this._emitter.emit(event, name, eventObject);
  48039. };
  48040. _proto.trigger = function trigger(event, eventObject) {
  48041. if (this.config.debug) {
  48042. return this.emit(event, event, eventObject);
  48043. } else {
  48044. try {
  48045. return this.emit(event, event, eventObject);
  48046. } catch (e) {
  48047. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.error('An internal error happened while handling event ' + event + '. Error message: "' + e.message + '". Here is a stacktrace:', e);
  48048. this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.ERROR, {
  48049. type: _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorTypes.OTHER_ERROR,
  48050. details: _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails.INTERNAL_EXCEPTION,
  48051. fatal: false,
  48052. event: event,
  48053. error: e
  48054. });
  48055. }
  48056. }
  48057. return false;
  48058. };
  48059. _proto.listenerCount = function listenerCount(event) {
  48060. return this._emitter.listenerCount(event);
  48061. }
  48062. /**
  48063. * Dispose of the instance
  48064. */;
  48065. _proto.destroy = function destroy() {
  48066. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('destroy');
  48067. this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.DESTROYING, undefined);
  48068. this.detachMedia();
  48069. this.removeAllListeners();
  48070. this._autoLevelCapping = -1;
  48071. this.url = null;
  48072. this.networkControllers.forEach(function (component) {
  48073. return component.destroy();
  48074. });
  48075. this.networkControllers.length = 0;
  48076. this.coreComponents.forEach(function (component) {
  48077. return component.destroy();
  48078. });
  48079. this.coreComponents.length = 0;
  48080. }
  48081. /**
  48082. * Attaches Hls.js to a media element
  48083. * @param {HTMLMediaElement} media
  48084. */;
  48085. _proto.attachMedia = function attachMedia(media) {
  48086. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('attachMedia');
  48087. this._media = media;
  48088. this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.MEDIA_ATTACHING, {
  48089. media: media
  48090. });
  48091. }
  48092. /**
  48093. * Detach Hls.js from the media
  48094. */;
  48095. _proto.detachMedia = function detachMedia() {
  48096. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('detachMedia');
  48097. this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.MEDIA_DETACHING, undefined);
  48098. this._media = null;
  48099. }
  48100. /**
  48101. * Set the source URL. Can be relative or absolute.
  48102. * @param {string} url
  48103. */;
  48104. _proto.loadSource = function loadSource(url) {
  48105. this.stopLoad();
  48106. var media = this.media;
  48107. var loadedSource = this.url;
  48108. var loadingSource = this.url = url_toolkit__WEBPACK_IMPORTED_MODULE_0__.buildAbsoluteURL(self.location.href, url, {
  48109. alwaysNormalize: true
  48110. });
  48111. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("loadSource:" + loadingSource);
  48112. if (media && loadedSource && loadedSource !== loadingSource && this.bufferController.hasSourceTypes()) {
  48113. this.detachMedia();
  48114. this.attachMedia(media);
  48115. }
  48116. // when attaching to a source URL, trigger a playlist load
  48117. this.trigger(_events__WEBPACK_IMPORTED_MODULE_12__.Events.MANIFEST_LOADING, {
  48118. url: url
  48119. });
  48120. }
  48121. /**
  48122. * Start loading data from the stream source.
  48123. * Depending on default config, client starts loading automatically when a source is set.
  48124. *
  48125. * @param {number} startPosition Set the start position to stream from
  48126. * @default -1 None (from earliest point)
  48127. */;
  48128. _proto.startLoad = function startLoad(startPosition) {
  48129. if (startPosition === void 0) {
  48130. startPosition = -1;
  48131. }
  48132. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("startLoad(" + startPosition + ")");
  48133. this.networkControllers.forEach(function (controller) {
  48134. controller.startLoad(startPosition);
  48135. });
  48136. }
  48137. /**
  48138. * Stop loading of any stream data.
  48139. */;
  48140. _proto.stopLoad = function stopLoad() {
  48141. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('stopLoad');
  48142. this.networkControllers.forEach(function (controller) {
  48143. controller.stopLoad();
  48144. });
  48145. }
  48146. /**
  48147. * Swap through possible audio codecs in the stream (for example to switch from stereo to 5.1)
  48148. */;
  48149. _proto.swapAudioCodec = function swapAudioCodec() {
  48150. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('swapAudioCodec');
  48151. this.streamController.swapAudioCodec();
  48152. }
  48153. /**
  48154. * When the media-element fails, this allows to detach and then re-attach it
  48155. * as one call (convenience method).
  48156. *
  48157. * Automatic recovery of media-errors by this process is configurable.
  48158. */;
  48159. _proto.recoverMediaError = function recoverMediaError() {
  48160. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log('recoverMediaError');
  48161. var media = this._media;
  48162. this.detachMedia();
  48163. if (media) {
  48164. this.attachMedia(media);
  48165. }
  48166. };
  48167. _proto.removeLevel = function removeLevel(levelIndex, urlId) {
  48168. if (urlId === void 0) {
  48169. urlId = 0;
  48170. }
  48171. this.levelController.removeLevel(levelIndex, urlId);
  48172. }
  48173. /**
  48174. * @type {Level[]}
  48175. */;
  48176. _createClass(Hls, [{
  48177. key: "levels",
  48178. get: function get() {
  48179. var levels = this.levelController.levels;
  48180. return levels ? levels : [];
  48181. }
  48182. /**
  48183. * Index of quality level currently played
  48184. * @type {number}
  48185. */
  48186. }, {
  48187. key: "currentLevel",
  48188. get: function get() {
  48189. return this.streamController.currentLevel;
  48190. }
  48191. /**
  48192. * Set quality level index immediately .
  48193. * This will flush the current buffer to replace the quality asap.
  48194. * That means playback will interrupt at least shortly to re-buffer and re-sync eventually.
  48195. * @type {number} -1 for automatic level selection
  48196. */,
  48197. set: function set(newLevel) {
  48198. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set currentLevel:" + newLevel);
  48199. this.loadLevel = newLevel;
  48200. this.abrController.clearTimer();
  48201. this.streamController.immediateLevelSwitch();
  48202. }
  48203. /**
  48204. * Index of next quality level loaded as scheduled by stream controller.
  48205. * @type {number}
  48206. */
  48207. }, {
  48208. key: "nextLevel",
  48209. get: function get() {
  48210. return this.streamController.nextLevel;
  48211. }
  48212. /**
  48213. * Set quality level index for next loaded data.
  48214. * This will switch the video quality asap, without interrupting playback.
  48215. * May abort current loading of data, and flush parts of buffer (outside currently played fragment region).
  48216. * @type {number} -1 for automatic level selection
  48217. */,
  48218. set: function set(newLevel) {
  48219. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set nextLevel:" + newLevel);
  48220. this.levelController.manualLevel = newLevel;
  48221. this.streamController.nextLevelSwitch();
  48222. }
  48223. /**
  48224. * Return the quality level of the currently or last (of none is loaded currently) segment
  48225. * @type {number}
  48226. */
  48227. }, {
  48228. key: "loadLevel",
  48229. get: function get() {
  48230. return this.levelController.level;
  48231. }
  48232. /**
  48233. * Set quality level index for next loaded data in a conservative way.
  48234. * This will switch the quality without flushing, but interrupt current loading.
  48235. * Thus the moment when the quality switch will appear in effect will only be after the already existing buffer.
  48236. * @type {number} newLevel -1 for automatic level selection
  48237. */,
  48238. set: function set(newLevel) {
  48239. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set loadLevel:" + newLevel);
  48240. this.levelController.manualLevel = newLevel;
  48241. }
  48242. /**
  48243. * get next quality level loaded
  48244. * @type {number}
  48245. */
  48246. }, {
  48247. key: "nextLoadLevel",
  48248. get: function get() {
  48249. return this.levelController.nextLoadLevel;
  48250. }
  48251. /**
  48252. * Set quality level of next loaded segment in a fully "non-destructive" way.
  48253. * Same as `loadLevel` but will wait for next switch (until current loading is done).
  48254. * @type {number} level
  48255. */,
  48256. set: function set(level) {
  48257. this.levelController.nextLoadLevel = level;
  48258. }
  48259. /**
  48260. * Return "first level": like a default level, if not set,
  48261. * falls back to index of first level referenced in manifest
  48262. * @type {number}
  48263. */
  48264. }, {
  48265. key: "firstLevel",
  48266. get: function get() {
  48267. return Math.max(this.levelController.firstLevel, this.minAutoLevel);
  48268. }
  48269. /**
  48270. * Sets "first-level", see getter.
  48271. * @type {number}
  48272. */,
  48273. set: function set(newLevel) {
  48274. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set firstLevel:" + newLevel);
  48275. this.levelController.firstLevel = newLevel;
  48276. }
  48277. /**
  48278. * Return start level (level of first fragment that will be played back)
  48279. * if not overrided by user, first level appearing in manifest will be used as start level
  48280. * if -1 : automatic start level selection, playback will start from level matching download bandwidth
  48281. * (determined from download of first segment)
  48282. * @type {number}
  48283. */
  48284. }, {
  48285. key: "startLevel",
  48286. get: function get() {
  48287. return this.levelController.startLevel;
  48288. }
  48289. /**
  48290. * set start level (level of first fragment that will be played back)
  48291. * if not overrided by user, first level appearing in manifest will be used as start level
  48292. * if -1 : automatic start level selection, playback will start from level matching download bandwidth
  48293. * (determined from download of first segment)
  48294. * @type {number} newLevel
  48295. */,
  48296. set: function set(newLevel) {
  48297. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set startLevel:" + newLevel);
  48298. // if not in automatic start level detection, ensure startLevel is greater than minAutoLevel
  48299. if (newLevel !== -1) {
  48300. newLevel = Math.max(newLevel, this.minAutoLevel);
  48301. }
  48302. this.levelController.startLevel = newLevel;
  48303. }
  48304. /**
  48305. * Get the current setting for capLevelToPlayerSize
  48306. *
  48307. * @type {boolean}
  48308. */
  48309. }, {
  48310. key: "capLevelToPlayerSize",
  48311. get: function get() {
  48312. return this.config.capLevelToPlayerSize;
  48313. }
  48314. /**
  48315. * set dynamically set capLevelToPlayerSize against (`CapLevelController`)
  48316. *
  48317. * @type {boolean}
  48318. */,
  48319. set: function set(shouldStartCapping) {
  48320. var newCapLevelToPlayerSize = !!shouldStartCapping;
  48321. if (newCapLevelToPlayerSize !== this.config.capLevelToPlayerSize) {
  48322. if (newCapLevelToPlayerSize) {
  48323. this.capLevelController.startCapping(); // If capping occurs, nextLevelSwitch will happen based on size.
  48324. } else {
  48325. this.capLevelController.stopCapping();
  48326. this.autoLevelCapping = -1;
  48327. this.streamController.nextLevelSwitch(); // Now we're uncapped, get the next level asap.
  48328. }
  48329. this.config.capLevelToPlayerSize = newCapLevelToPlayerSize;
  48330. }
  48331. }
  48332. /**
  48333. * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
  48334. * @type {number}
  48335. */
  48336. }, {
  48337. key: "autoLevelCapping",
  48338. get: function get() {
  48339. return this._autoLevelCapping;
  48340. }
  48341. /**
  48342. * get bandwidth estimate
  48343. * @type {number}
  48344. */,
  48345. set:
  48346. /**
  48347. * Capping/max level value that should be used by automatic level selection algorithm (`ABRController`)
  48348. * @type {number}
  48349. */
  48350. function set(newLevel) {
  48351. if (this._autoLevelCapping !== newLevel) {
  48352. _utils_logger__WEBPACK_IMPORTED_MODULE_9__.logger.log("set autoLevelCapping:" + newLevel);
  48353. this._autoLevelCapping = newLevel;
  48354. }
  48355. }
  48356. }, {
  48357. key: "bandwidthEstimate",
  48358. get: function get() {
  48359. var bwEstimator = this.abrController.bwEstimator;
  48360. if (!bwEstimator) {
  48361. return NaN;
  48362. }
  48363. return bwEstimator.getEstimate();
  48364. }
  48365. }, {
  48366. key: "maxHdcpLevel",
  48367. get: function get() {
  48368. return this._maxHdcpLevel;
  48369. },
  48370. set: function set(value) {
  48371. if (_types_level__WEBPACK_IMPORTED_MODULE_14__.HdcpLevels.indexOf(value) > -1) {
  48372. this._maxHdcpLevel = value;
  48373. }
  48374. }
  48375. /**
  48376. * True when automatic level selection enabled
  48377. * @type {boolean}
  48378. */
  48379. }, {
  48380. key: "autoLevelEnabled",
  48381. get: function get() {
  48382. return this.levelController.manualLevel === -1;
  48383. }
  48384. /**
  48385. * Level set manually (if any)
  48386. * @type {number}
  48387. */
  48388. }, {
  48389. key: "manualLevel",
  48390. get: function get() {
  48391. return this.levelController.manualLevel;
  48392. }
  48393. /**
  48394. * min level selectable in auto mode according to config.minAutoBitrate
  48395. * @type {number}
  48396. */
  48397. }, {
  48398. key: "minAutoLevel",
  48399. get: function get() {
  48400. var levels = this.levels,
  48401. minAutoBitrate = this.config.minAutoBitrate;
  48402. if (!levels) return 0;
  48403. var len = levels.length;
  48404. for (var i = 0; i < len; i++) {
  48405. if (levels[i].maxBitrate >= minAutoBitrate) {
  48406. return i;
  48407. }
  48408. }
  48409. return 0;
  48410. }
  48411. /**
  48412. * max level selectable in auto mode according to autoLevelCapping
  48413. * @type {number}
  48414. */
  48415. }, {
  48416. key: "maxAutoLevel",
  48417. get: function get() {
  48418. var levels = this.levels,
  48419. autoLevelCapping = this.autoLevelCapping,
  48420. maxHdcpLevel = this.maxHdcpLevel;
  48421. var maxAutoLevel;
  48422. if (autoLevelCapping === -1 && levels && levels.length) {
  48423. maxAutoLevel = levels.length - 1;
  48424. } else {
  48425. maxAutoLevel = autoLevelCapping;
  48426. }
  48427. if (maxHdcpLevel) {
  48428. for (var i = maxAutoLevel; i--;) {
  48429. var hdcpLevel = levels[i].attrs['HDCP-LEVEL'];
  48430. if (hdcpLevel && hdcpLevel <= maxHdcpLevel) {
  48431. return i;
  48432. }
  48433. }
  48434. }
  48435. return maxAutoLevel;
  48436. }
  48437. /**
  48438. * next automatically selected quality level
  48439. * @type {number}
  48440. */
  48441. }, {
  48442. key: "nextAutoLevel",
  48443. get: function get() {
  48444. // ensure next auto level is between min and max auto level
  48445. return Math.min(Math.max(this.abrController.nextAutoLevel, this.minAutoLevel), this.maxAutoLevel);
  48446. }
  48447. /**
  48448. * this setter is used to force next auto level.
  48449. * this is useful to force a switch down in auto mode:
  48450. * in case of load error on level N, hls.js can set nextAutoLevel to N-1 for example)
  48451. * forced value is valid for one fragment. upon successful frag loading at forced level,
  48452. * this value will be resetted to -1 by ABR controller.
  48453. * @type {number}
  48454. */,
  48455. set: function set(nextLevel) {
  48456. this.abrController.nextAutoLevel = Math.max(this.minAutoLevel, nextLevel);
  48457. }
  48458. /**
  48459. * get the datetime value relative to media.currentTime for the active level Program Date Time if present
  48460. * @type {Date}
  48461. */
  48462. }, {
  48463. key: "playingDate",
  48464. get: function get() {
  48465. return this.streamController.currentProgramDateTime;
  48466. }
  48467. }, {
  48468. key: "mainForwardBufferInfo",
  48469. get: function get() {
  48470. return this.streamController.getMainFwdBufferInfo();
  48471. }
  48472. /**
  48473. * @type {AudioTrack[]}
  48474. */
  48475. }, {
  48476. key: "audioTracks",
  48477. get: function get() {
  48478. var audioTrackController = this.audioTrackController;
  48479. return audioTrackController ? audioTrackController.audioTracks : [];
  48480. }
  48481. /**
  48482. * index of the selected audio track (index in audio track lists)
  48483. * @type {number}
  48484. */
  48485. }, {
  48486. key: "audioTrack",
  48487. get: function get() {
  48488. var audioTrackController = this.audioTrackController;
  48489. return audioTrackController ? audioTrackController.audioTrack : -1;
  48490. }
  48491. /**
  48492. * selects an audio track, based on its index in audio track lists
  48493. * @type {number}
  48494. */,
  48495. set: function set(audioTrackId) {
  48496. var audioTrackController = this.audioTrackController;
  48497. if (audioTrackController) {
  48498. audioTrackController.audioTrack = audioTrackId;
  48499. }
  48500. }
  48501. /**
  48502. * get alternate subtitle tracks list from playlist
  48503. * @type {MediaPlaylist[]}
  48504. */
  48505. }, {
  48506. key: "subtitleTracks",
  48507. get: function get() {
  48508. var subtitleTrackController = this.subtitleTrackController;
  48509. return subtitleTrackController ? subtitleTrackController.subtitleTracks : [];
  48510. }
  48511. /**
  48512. * index of the selected subtitle track (index in subtitle track lists)
  48513. * @type {number}
  48514. */
  48515. }, {
  48516. key: "subtitleTrack",
  48517. get: function get() {
  48518. var subtitleTrackController = this.subtitleTrackController;
  48519. return subtitleTrackController ? subtitleTrackController.subtitleTrack : -1;
  48520. },
  48521. set:
  48522. /**
  48523. * select an subtitle track, based on its index in subtitle track lists
  48524. * @type {number}
  48525. */
  48526. function set(subtitleTrackId) {
  48527. var subtitleTrackController = this.subtitleTrackController;
  48528. if (subtitleTrackController) {
  48529. subtitleTrackController.subtitleTrack = subtitleTrackId;
  48530. }
  48531. }
  48532. /**
  48533. * @type {boolean}
  48534. */
  48535. }, {
  48536. key: "media",
  48537. get: function get() {
  48538. return this._media;
  48539. }
  48540. }, {
  48541. key: "subtitleDisplay",
  48542. get: function get() {
  48543. var subtitleTrackController = this.subtitleTrackController;
  48544. return subtitleTrackController ? subtitleTrackController.subtitleDisplay : false;
  48545. }
  48546. /**
  48547. * Enable/disable subtitle display rendering
  48548. * @type {boolean}
  48549. */,
  48550. set: function set(value) {
  48551. var subtitleTrackController = this.subtitleTrackController;
  48552. if (subtitleTrackController) {
  48553. subtitleTrackController.subtitleDisplay = value;
  48554. }
  48555. }
  48556. /**
  48557. * get mode for Low-Latency HLS loading
  48558. * @type {boolean}
  48559. */
  48560. }, {
  48561. key: "lowLatencyMode",
  48562. get: function get() {
  48563. return this.config.lowLatencyMode;
  48564. }
  48565. /**
  48566. * Enable/disable Low-Latency HLS part playlist and segment loading, and start live streams at playlist PART-HOLD-BACK rather than HOLD-BACK.
  48567. * @type {boolean}
  48568. */,
  48569. set: function set(mode) {
  48570. this.config.lowLatencyMode = mode;
  48571. }
  48572. /**
  48573. * position (in seconds) of live sync point (ie edge of live position minus safety delay defined by ```hls.config.liveSyncDuration```)
  48574. * @type {number}
  48575. */
  48576. }, {
  48577. key: "liveSyncPosition",
  48578. get: function get() {
  48579. return this.latencyController.liveSyncPosition;
  48580. }
  48581. /**
  48582. * estimated position (in seconds) of live edge (ie edge of live playlist plus time sync playlist advanced)
  48583. * returns 0 before first playlist is loaded
  48584. * @type {number}
  48585. */
  48586. }, {
  48587. key: "latency",
  48588. get: function get() {
  48589. return this.latencyController.latency;
  48590. }
  48591. /**
  48592. * maximum distance from the edge before the player seeks forward to ```hls.liveSyncPosition```
  48593. * configured using ```liveMaxLatencyDurationCount``` (multiple of target duration) or ```liveMaxLatencyDuration```
  48594. * returns 0 before first playlist is loaded
  48595. * @type {number}
  48596. */
  48597. }, {
  48598. key: "maxLatency",
  48599. get: function get() {
  48600. return this.latencyController.maxLatency;
  48601. }
  48602. /**
  48603. * target distance from the edge as calculated by the latency controller
  48604. * @type {number}
  48605. */
  48606. }, {
  48607. key: "targetLatency",
  48608. get: function get() {
  48609. return this.latencyController.targetLatency;
  48610. }
  48611. /**
  48612. * the rate at which the edge of the current live playlist is advancing or 1 if there is none
  48613. * @type {number}
  48614. */
  48615. }, {
  48616. key: "drift",
  48617. get: function get() {
  48618. return this.latencyController.drift;
  48619. }
  48620. /**
  48621. * set to true when startLoad is called before MANIFEST_PARSED event
  48622. * @type {boolean}
  48623. */
  48624. }, {
  48625. key: "forceStartLoad",
  48626. get: function get() {
  48627. return this.streamController.forceStartLoad;
  48628. }
  48629. }], [{
  48630. key: "version",
  48631. get: function get() {
  48632. return "1.3.4";
  48633. }
  48634. }, {
  48635. key: "Events",
  48636. get: function get() {
  48637. return _events__WEBPACK_IMPORTED_MODULE_12__.Events;
  48638. }
  48639. }, {
  48640. key: "ErrorTypes",
  48641. get: function get() {
  48642. return _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorTypes;
  48643. }
  48644. }, {
  48645. key: "ErrorDetails",
  48646. get: function get() {
  48647. return _errors__WEBPACK_IMPORTED_MODULE_13__.ErrorDetails;
  48648. }
  48649. }, {
  48650. key: "DefaultConfig",
  48651. get: function get() {
  48652. if (!Hls.defaultConfig) {
  48653. return _config__WEBPACK_IMPORTED_MODULE_10__.hlsDefaultConfig;
  48654. }
  48655. return Hls.defaultConfig;
  48656. }
  48657. /**
  48658. * @type {HlsConfig}
  48659. */,
  48660. set: function set(defaultConfig) {
  48661. Hls.defaultConfig = defaultConfig;
  48662. }
  48663. }]);
  48664. return Hls;
  48665. }();
  48666. Hls.defaultConfig = void 0;
  48667. /***/ }),
  48668. /***/ "./src/is-supported.ts":
  48669. /*!*****************************!*\
  48670. !*** ./src/is-supported.ts ***!
  48671. \*****************************/
  48672. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  48673. "use strict";
  48674. __webpack_require__.r(__webpack_exports__);
  48675. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  48676. /* harmony export */ "changeTypeSupported": () => (/* binding */ changeTypeSupported),
  48677. /* harmony export */ "isSupported": () => (/* binding */ isSupported)
  48678. /* harmony export */ });
  48679. /* harmony import */ var _utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/mediasource-helper */ "./src/utils/mediasource-helper.ts");
  48680. function getSourceBuffer() {
  48681. return self.SourceBuffer || self.WebKitSourceBuffer;
  48682. }
  48683. function isSupported() {
  48684. var mediaSource = (0,_utils_mediasource_helper__WEBPACK_IMPORTED_MODULE_0__.getMediaSource)();
  48685. if (!mediaSource) {
  48686. return false;
  48687. }
  48688. var sourceBuffer = getSourceBuffer();
  48689. var isTypeSupported = mediaSource && typeof mediaSource.isTypeSupported === 'function' && mediaSource.isTypeSupported('video/mp4; codecs="avc1.42E01E,mp4a.40.2"');
  48690. // if SourceBuffer is exposed ensure its API is valid
  48691. // safari and old version of Chrome doe not expose SourceBuffer globally so checking SourceBuffer.prototype is impossible
  48692. var sourceBufferValidAPI = !sourceBuffer || sourceBuffer.prototype && typeof sourceBuffer.prototype.appendBuffer === 'function' && typeof sourceBuffer.prototype.remove === 'function';
  48693. return !!isTypeSupported && !!sourceBufferValidAPI;
  48694. }
  48695. function changeTypeSupported() {
  48696. var _sourceBuffer$prototy;
  48697. var sourceBuffer = getSourceBuffer();
  48698. return typeof (sourceBuffer === null || sourceBuffer === void 0 ? void 0 : (_sourceBuffer$prototy = sourceBuffer.prototype) === null || _sourceBuffer$prototy === void 0 ? void 0 : _sourceBuffer$prototy.changeType) === 'function';
  48699. }
  48700. /***/ }),
  48701. /***/ "./src/loader/date-range.ts":
  48702. /*!**********************************!*\
  48703. !*** ./src/loader/date-range.ts ***!
  48704. \**********************************/
  48705. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  48706. "use strict";
  48707. __webpack_require__.r(__webpack_exports__);
  48708. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  48709. /* harmony export */ "DateRange": () => (/* binding */ DateRange),
  48710. /* harmony export */ "DateRangeAttribute": () => (/* binding */ DateRangeAttribute)
  48711. /* harmony export */ });
  48712. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  48713. /* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts");
  48714. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  48715. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  48716. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  48717. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  48718. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  48719. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  48720. var DateRangeAttribute;
  48721. (function (DateRangeAttribute) {
  48722. DateRangeAttribute["ID"] = "ID";
  48723. DateRangeAttribute["CLASS"] = "CLASS";
  48724. DateRangeAttribute["START_DATE"] = "START-DATE";
  48725. DateRangeAttribute["DURATION"] = "DURATION";
  48726. DateRangeAttribute["END_DATE"] = "END-DATE";
  48727. DateRangeAttribute["END_ON_NEXT"] = "END-ON-NEXT";
  48728. DateRangeAttribute["PLANNED_DURATION"] = "PLANNED-DURATION";
  48729. DateRangeAttribute["SCTE35_OUT"] = "SCTE35-OUT";
  48730. DateRangeAttribute["SCTE35_IN"] = "SCTE35-IN";
  48731. })(DateRangeAttribute || (DateRangeAttribute = {}));
  48732. var DateRange = /*#__PURE__*/function () {
  48733. function DateRange(dateRangeAttr, dateRangeWithSameId) {
  48734. this.attr = void 0;
  48735. this._startDate = void 0;
  48736. this._endDate = void 0;
  48737. this._badValueForSameId = void 0;
  48738. if (dateRangeWithSameId) {
  48739. var previousAttr = dateRangeWithSameId.attr;
  48740. for (var key in previousAttr) {
  48741. if (Object.prototype.hasOwnProperty.call(dateRangeAttr, key) && dateRangeAttr[key] !== previousAttr[key]) {
  48742. _utils_logger__WEBPACK_IMPORTED_MODULE_2__.logger.warn("DATERANGE tag attribute: \"" + key + "\" does not match for tags with ID: \"" + dateRangeAttr.ID + "\"");
  48743. this._badValueForSameId = key;
  48744. break;
  48745. }
  48746. }
  48747. // Merge DateRange tags with the same ID
  48748. dateRangeAttr = _extends(new _utils_attr_list__WEBPACK_IMPORTED_MODULE_1__.AttrList({}), previousAttr, dateRangeAttr);
  48749. }
  48750. this.attr = dateRangeAttr;
  48751. this._startDate = new Date(dateRangeAttr[DateRangeAttribute.START_DATE]);
  48752. if (DateRangeAttribute.END_DATE in this.attr) {
  48753. var endDate = new Date(this.attr[DateRangeAttribute.END_DATE]);
  48754. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(endDate.getTime())) {
  48755. this._endDate = endDate;
  48756. }
  48757. }
  48758. }
  48759. _createClass(DateRange, [{
  48760. key: "id",
  48761. get: function get() {
  48762. return this.attr.ID;
  48763. }
  48764. }, {
  48765. key: "class",
  48766. get: function get() {
  48767. return this.attr.CLASS;
  48768. }
  48769. }, {
  48770. key: "startDate",
  48771. get: function get() {
  48772. return this._startDate;
  48773. }
  48774. }, {
  48775. key: "endDate",
  48776. get: function get() {
  48777. if (this._endDate) {
  48778. return this._endDate;
  48779. }
  48780. var duration = this.duration;
  48781. if (duration !== null) {
  48782. return new Date(this._startDate.getTime() + duration * 1000);
  48783. }
  48784. return null;
  48785. }
  48786. }, {
  48787. key: "duration",
  48788. get: function get() {
  48789. if (DateRangeAttribute.DURATION in this.attr) {
  48790. var duration = this.attr.decimalFloatingPoint(DateRangeAttribute.DURATION);
  48791. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(duration)) {
  48792. return duration;
  48793. }
  48794. } else if (this._endDate) {
  48795. return (this._endDate.getTime() - this._startDate.getTime()) / 1000;
  48796. }
  48797. return null;
  48798. }
  48799. }, {
  48800. key: "plannedDuration",
  48801. get: function get() {
  48802. if (DateRangeAttribute.PLANNED_DURATION in this.attr) {
  48803. return this.attr.decimalFloatingPoint(DateRangeAttribute.PLANNED_DURATION);
  48804. }
  48805. return null;
  48806. }
  48807. }, {
  48808. key: "endOnNext",
  48809. get: function get() {
  48810. return this.attr.bool(DateRangeAttribute.END_ON_NEXT);
  48811. }
  48812. }, {
  48813. key: "isValid",
  48814. get: function get() {
  48815. return !!this.id && !this._badValueForSameId && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.startDate.getTime()) && (this.duration === null || this.duration >= 0) && (!this.endOnNext || !!this.class);
  48816. }
  48817. }]);
  48818. return DateRange;
  48819. }();
  48820. /***/ }),
  48821. /***/ "./src/loader/fragment-loader.ts":
  48822. /*!***************************************!*\
  48823. !*** ./src/loader/fragment-loader.ts ***!
  48824. \***************************************/
  48825. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  48826. "use strict";
  48827. __webpack_require__.r(__webpack_exports__);
  48828. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  48829. /* harmony export */ "LoadError": () => (/* binding */ LoadError),
  48830. /* harmony export */ "default": () => (/* binding */ FragmentLoader)
  48831. /* harmony export */ });
  48832. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  48833. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  48834. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  48835. function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
  48836. function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
  48837. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
  48838. function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
  48839. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  48840. function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
  48841. var MIN_CHUNK_SIZE = Math.pow(2, 17); // 128kb
  48842. var FragmentLoader = /*#__PURE__*/function () {
  48843. function FragmentLoader(config) {
  48844. this.config = void 0;
  48845. this.loader = null;
  48846. this.partLoadTimeout = -1;
  48847. this.config = config;
  48848. }
  48849. var _proto = FragmentLoader.prototype;
  48850. _proto.destroy = function destroy() {
  48851. if (this.loader) {
  48852. this.loader.destroy();
  48853. this.loader = null;
  48854. }
  48855. };
  48856. _proto.abort = function abort() {
  48857. if (this.loader) {
  48858. // Abort the loader for current fragment. Only one may load at any given time
  48859. this.loader.abort();
  48860. }
  48861. };
  48862. _proto.load = function load(frag, _onProgress) {
  48863. var _this = this;
  48864. var url = frag.url;
  48865. if (!url) {
  48866. return Promise.reject(new LoadError({
  48867. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  48868. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_ERROR,
  48869. fatal: false,
  48870. frag: frag,
  48871. networkDetails: null
  48872. }, "Fragment does not have a " + (url ? 'part list' : 'url')));
  48873. }
  48874. this.abort();
  48875. var config = this.config;
  48876. var FragmentILoader = config.fLoader;
  48877. var DefaultILoader = config.loader;
  48878. return new Promise(function (resolve, reject) {
  48879. if (_this.loader) {
  48880. _this.loader.destroy();
  48881. }
  48882. var loader = _this.loader = frag.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config);
  48883. var loaderContext = createLoaderContext(frag);
  48884. var loaderConfig = {
  48885. timeout: config.fragLoadingTimeOut,
  48886. maxRetry: 0,
  48887. retryDelay: 0,
  48888. maxRetryDelay: config.fragLoadingMaxRetryTimeout,
  48889. highWaterMark: frag.sn === 'initSegment' ? Infinity : MIN_CHUNK_SIZE
  48890. };
  48891. // Assign frag stats to the loader's stats reference
  48892. frag.stats = loader.stats;
  48893. loader.load(loaderContext, loaderConfig, {
  48894. onSuccess: function onSuccess(response, stats, context, networkDetails) {
  48895. _this.resetLoader(frag, loader);
  48896. var payload = response.data;
  48897. if (context.resetIV && frag.decryptdata) {
  48898. frag.decryptdata.iv = new Uint8Array(payload.slice(0, 16));
  48899. payload = payload.slice(16);
  48900. }
  48901. resolve({
  48902. frag: frag,
  48903. part: null,
  48904. payload: payload,
  48905. networkDetails: networkDetails
  48906. });
  48907. },
  48908. onError: function onError(response, context, networkDetails) {
  48909. _this.resetLoader(frag, loader);
  48910. reject(new LoadError({
  48911. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  48912. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_ERROR,
  48913. fatal: false,
  48914. frag: frag,
  48915. response: response,
  48916. networkDetails: networkDetails
  48917. }));
  48918. },
  48919. onAbort: function onAbort(stats, context, networkDetails) {
  48920. _this.resetLoader(frag, loader);
  48921. reject(new LoadError({
  48922. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  48923. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.INTERNAL_ABORTED,
  48924. fatal: false,
  48925. frag: frag,
  48926. networkDetails: networkDetails
  48927. }));
  48928. },
  48929. onTimeout: function onTimeout(response, context, networkDetails) {
  48930. _this.resetLoader(frag, loader);
  48931. reject(new LoadError({
  48932. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  48933. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_TIMEOUT,
  48934. fatal: false,
  48935. frag: frag,
  48936. networkDetails: networkDetails
  48937. }));
  48938. },
  48939. onProgress: function onProgress(stats, context, data, networkDetails) {
  48940. if (_onProgress) {
  48941. _onProgress({
  48942. frag: frag,
  48943. part: null,
  48944. payload: data,
  48945. networkDetails: networkDetails
  48946. });
  48947. }
  48948. }
  48949. });
  48950. });
  48951. };
  48952. _proto.loadPart = function loadPart(frag, part, onProgress) {
  48953. var _this2 = this;
  48954. this.abort();
  48955. var config = this.config;
  48956. var FragmentILoader = config.fLoader;
  48957. var DefaultILoader = config.loader;
  48958. return new Promise(function (resolve, reject) {
  48959. if (_this2.loader) {
  48960. _this2.loader.destroy();
  48961. }
  48962. var loader = _this2.loader = frag.loader = FragmentILoader ? new FragmentILoader(config) : new DefaultILoader(config);
  48963. var loaderContext = createLoaderContext(frag, part);
  48964. var loaderConfig = {
  48965. timeout: config.fragLoadingTimeOut,
  48966. maxRetry: 0,
  48967. retryDelay: 0,
  48968. maxRetryDelay: config.fragLoadingMaxRetryTimeout,
  48969. highWaterMark: MIN_CHUNK_SIZE
  48970. };
  48971. // Assign part stats to the loader's stats reference
  48972. part.stats = loader.stats;
  48973. loader.load(loaderContext, loaderConfig, {
  48974. onSuccess: function onSuccess(response, stats, context, networkDetails) {
  48975. _this2.resetLoader(frag, loader);
  48976. _this2.updateStatsFromPart(frag, part);
  48977. var partLoadedData = {
  48978. frag: frag,
  48979. part: part,
  48980. payload: response.data,
  48981. networkDetails: networkDetails
  48982. };
  48983. onProgress(partLoadedData);
  48984. resolve(partLoadedData);
  48985. },
  48986. onError: function onError(response, context, networkDetails) {
  48987. _this2.resetLoader(frag, loader);
  48988. reject(new LoadError({
  48989. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  48990. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_ERROR,
  48991. fatal: false,
  48992. frag: frag,
  48993. part: part,
  48994. response: response,
  48995. networkDetails: networkDetails
  48996. }));
  48997. },
  48998. onAbort: function onAbort(stats, context, networkDetails) {
  48999. frag.stats.aborted = part.stats.aborted;
  49000. _this2.resetLoader(frag, loader);
  49001. reject(new LoadError({
  49002. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  49003. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.INTERNAL_ABORTED,
  49004. fatal: false,
  49005. frag: frag,
  49006. part: part,
  49007. networkDetails: networkDetails
  49008. }));
  49009. },
  49010. onTimeout: function onTimeout(response, context, networkDetails) {
  49011. _this2.resetLoader(frag, loader);
  49012. reject(new LoadError({
  49013. type: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorTypes.NETWORK_ERROR,
  49014. details: _errors__WEBPACK_IMPORTED_MODULE_1__.ErrorDetails.FRAG_LOAD_TIMEOUT,
  49015. fatal: false,
  49016. frag: frag,
  49017. part: part,
  49018. networkDetails: networkDetails
  49019. }));
  49020. }
  49021. });
  49022. });
  49023. };
  49024. _proto.updateStatsFromPart = function updateStatsFromPart(frag, part) {
  49025. var fragStats = frag.stats;
  49026. var partStats = part.stats;
  49027. var partTotal = partStats.total;
  49028. fragStats.loaded += partStats.loaded;
  49029. if (partTotal) {
  49030. var estTotalParts = Math.round(frag.duration / part.duration);
  49031. var estLoadedParts = Math.min(Math.round(fragStats.loaded / partTotal), estTotalParts);
  49032. var estRemainingParts = estTotalParts - estLoadedParts;
  49033. var estRemainingBytes = estRemainingParts * Math.round(fragStats.loaded / estLoadedParts);
  49034. fragStats.total = fragStats.loaded + estRemainingBytes;
  49035. } else {
  49036. fragStats.total = Math.max(fragStats.loaded, fragStats.total);
  49037. }
  49038. var fragLoading = fragStats.loading;
  49039. var partLoading = partStats.loading;
  49040. if (fragLoading.start) {
  49041. // add to fragment loader latency
  49042. fragLoading.first += partLoading.first - partLoading.start;
  49043. } else {
  49044. fragLoading.start = partLoading.start;
  49045. fragLoading.first = partLoading.first;
  49046. }
  49047. fragLoading.end = partLoading.end;
  49048. };
  49049. _proto.resetLoader = function resetLoader(frag, loader) {
  49050. frag.loader = null;
  49051. if (this.loader === loader) {
  49052. self.clearTimeout(this.partLoadTimeout);
  49053. this.loader = null;
  49054. }
  49055. loader.destroy();
  49056. };
  49057. return FragmentLoader;
  49058. }();
  49059. function createLoaderContext(frag, part) {
  49060. if (part === void 0) {
  49061. part = null;
  49062. }
  49063. var segment = part || frag;
  49064. var loaderContext = {
  49065. frag: frag,
  49066. part: part,
  49067. responseType: 'arraybuffer',
  49068. url: segment.url,
  49069. headers: {},
  49070. rangeStart: 0,
  49071. rangeEnd: 0
  49072. };
  49073. var start = segment.byteRangeStartOffset;
  49074. var end = segment.byteRangeEndOffset;
  49075. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(start) && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(end)) {
  49076. var _frag$decryptdata;
  49077. var byteRangeStart = start;
  49078. var byteRangeEnd = end;
  49079. if (frag.sn === 'initSegment' && ((_frag$decryptdata = frag.decryptdata) === null || _frag$decryptdata === void 0 ? void 0 : _frag$decryptdata.method) === 'AES-128') {
  49080. // MAP segment encrypted with method 'AES-128', when served with HTTP Range,
  49081. // has the unencrypted size specified in the range.
  49082. // Ref: https://tools.ietf.org/html/draft-pantos-hls-rfc8216bis-08#section-6.3.6
  49083. var fragmentLen = end - start;
  49084. if (fragmentLen % 16) {
  49085. byteRangeEnd = end + (16 - fragmentLen % 16);
  49086. }
  49087. if (start !== 0) {
  49088. loaderContext.resetIV = true;
  49089. byteRangeStart = start - 16;
  49090. }
  49091. }
  49092. loaderContext.rangeStart = byteRangeStart;
  49093. loaderContext.rangeEnd = byteRangeEnd;
  49094. }
  49095. return loaderContext;
  49096. }
  49097. var LoadError = /*#__PURE__*/function (_Error) {
  49098. _inheritsLoose(LoadError, _Error);
  49099. function LoadError(data) {
  49100. var _this3;
  49101. for (var _len = arguments.length, params = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  49102. params[_key - 1] = arguments[_key];
  49103. }
  49104. _this3 = _Error.call.apply(_Error, [this].concat(params)) || this;
  49105. _this3.data = void 0;
  49106. _this3.data = data;
  49107. return _this3;
  49108. }
  49109. return LoadError;
  49110. }( /*#__PURE__*/_wrapNativeSuper(Error));
  49111. /***/ }),
  49112. /***/ "./src/loader/fragment.ts":
  49113. /*!********************************!*\
  49114. !*** ./src/loader/fragment.ts ***!
  49115. \********************************/
  49116. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  49117. "use strict";
  49118. __webpack_require__.r(__webpack_exports__);
  49119. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  49120. /* harmony export */ "BaseSegment": () => (/* binding */ BaseSegment),
  49121. /* harmony export */ "ElementaryStreamTypes": () => (/* binding */ ElementaryStreamTypes),
  49122. /* harmony export */ "Fragment": () => (/* binding */ Fragment),
  49123. /* harmony export */ "Part": () => (/* binding */ Part)
  49124. /* harmony export */ });
  49125. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  49126. /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js");
  49127. /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__);
  49128. /* harmony import */ var _load_stats__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./load-stats */ "./src/loader/load-stats.ts");
  49129. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  49130. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  49131. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  49132. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  49133. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  49134. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  49135. var ElementaryStreamTypes;
  49136. (function (ElementaryStreamTypes) {
  49137. ElementaryStreamTypes["AUDIO"] = "audio";
  49138. ElementaryStreamTypes["VIDEO"] = "video";
  49139. ElementaryStreamTypes["AUDIOVIDEO"] = "audiovideo";
  49140. })(ElementaryStreamTypes || (ElementaryStreamTypes = {}));
  49141. var BaseSegment = /*#__PURE__*/function () {
  49142. // baseurl is the URL to the playlist
  49143. // relurl is the portion of the URL that comes from inside the playlist.
  49144. // Holds the types of data this fragment supports
  49145. function BaseSegment(baseurl) {
  49146. var _this$elementaryStrea;
  49147. this._byteRange = null;
  49148. this._url = null;
  49149. this.baseurl = void 0;
  49150. this.relurl = void 0;
  49151. this.elementaryStreams = (_this$elementaryStrea = {}, _this$elementaryStrea[ElementaryStreamTypes.AUDIO] = null, _this$elementaryStrea[ElementaryStreamTypes.VIDEO] = null, _this$elementaryStrea[ElementaryStreamTypes.AUDIOVIDEO] = null, _this$elementaryStrea);
  49152. this.baseurl = baseurl;
  49153. }
  49154. // setByteRange converts a EXT-X-BYTERANGE attribute into a two element array
  49155. var _proto = BaseSegment.prototype;
  49156. _proto.setByteRange = function setByteRange(value, previous) {
  49157. var params = value.split('@', 2);
  49158. var byteRange = [];
  49159. if (params.length === 1) {
  49160. byteRange[0] = previous ? previous.byteRangeEndOffset : 0;
  49161. } else {
  49162. byteRange[0] = parseInt(params[1]);
  49163. }
  49164. byteRange[1] = parseInt(params[0]) + byteRange[0];
  49165. this._byteRange = byteRange;
  49166. };
  49167. _createClass(BaseSegment, [{
  49168. key: "byteRange",
  49169. get: function get() {
  49170. if (!this._byteRange) {
  49171. return [];
  49172. }
  49173. return this._byteRange;
  49174. }
  49175. }, {
  49176. key: "byteRangeStartOffset",
  49177. get: function get() {
  49178. return this.byteRange[0];
  49179. }
  49180. }, {
  49181. key: "byteRangeEndOffset",
  49182. get: function get() {
  49183. return this.byteRange[1];
  49184. }
  49185. }, {
  49186. key: "url",
  49187. get: function get() {
  49188. if (!this._url && this.baseurl && this.relurl) {
  49189. this._url = (0,url_toolkit__WEBPACK_IMPORTED_MODULE_1__.buildAbsoluteURL)(this.baseurl, this.relurl, {
  49190. alwaysNormalize: true
  49191. });
  49192. }
  49193. return this._url || '';
  49194. },
  49195. set: function set(value) {
  49196. this._url = value;
  49197. }
  49198. }]);
  49199. return BaseSegment;
  49200. }();
  49201. var Fragment = /*#__PURE__*/function (_BaseSegment) {
  49202. _inheritsLoose(Fragment, _BaseSegment);
  49203. // EXTINF has to be present for a m3u8 to be considered valid
  49204. // sn notates the sequence number for a segment, and if set to a string can be 'initSegment'
  49205. // levelkeys are the EXT-X-KEY tags that apply to this segment for decryption
  49206. // core difference from the private field _decryptdata is the lack of the initialized IV
  49207. // _decryptdata will set the IV for this segment based on the segment number in the fragment
  49208. // A string representing the fragment type
  49209. // A reference to the loader. Set while the fragment is loading, and removed afterwards. Used to abort fragment loading
  49210. // A reference to the key loader. Set while the key is loading, and removed afterwards. Used to abort key loading
  49211. // The level/track index to which the fragment belongs
  49212. // The continuity counter of the fragment
  49213. // The starting Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.
  49214. // The ending Presentation Time Stamp (PTS) of the fragment. Set after transmux complete.
  49215. // The latest Presentation Time Stamp (PTS) appended to the buffer.
  49216. // The starting Decode Time Stamp (DTS) of the fragment. Set after transmux complete.
  49217. // The ending Decode Time Stamp (DTS) of the fragment. Set after transmux complete.
  49218. // The start time of the fragment, as listed in the manifest. Updated after transmux complete.
  49219. // Set by `updateFragPTSDTS` in level-helper
  49220. // The maximum starting Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.
  49221. // The minimum ending Presentation Time Stamp (audio/video PTS) of the fragment. Set after transmux complete.
  49222. // Load/parse timing information
  49223. // A flag indicating whether the segment was downloaded in order to test bitrate, and was not buffered
  49224. // #EXTINF segment title
  49225. // The Media Initialization Section for this segment
  49226. // Fragment is the last fragment in the media playlist
  49227. function Fragment(type, baseurl) {
  49228. var _this;
  49229. _this = _BaseSegment.call(this, baseurl) || this;
  49230. _this._decryptdata = null;
  49231. _this.rawProgramDateTime = null;
  49232. _this.programDateTime = null;
  49233. _this.tagList = [];
  49234. _this.duration = 0;
  49235. _this.sn = 0;
  49236. _this.levelkeys = void 0;
  49237. _this.type = void 0;
  49238. _this.loader = null;
  49239. _this.keyLoader = null;
  49240. _this.level = -1;
  49241. _this.cc = 0;
  49242. _this.startPTS = void 0;
  49243. _this.endPTS = void 0;
  49244. _this.appendedPTS = void 0;
  49245. _this.startDTS = void 0;
  49246. _this.endDTS = void 0;
  49247. _this.start = 0;
  49248. _this.deltaPTS = void 0;
  49249. _this.maxStartPTS = void 0;
  49250. _this.minEndPTS = void 0;
  49251. _this.stats = new _load_stats__WEBPACK_IMPORTED_MODULE_2__.LoadStats();
  49252. _this.urlId = 0;
  49253. _this.data = void 0;
  49254. _this.bitrateTest = false;
  49255. _this.title = null;
  49256. _this.initSegment = null;
  49257. _this.endList = void 0;
  49258. _this.type = type;
  49259. return _this;
  49260. }
  49261. var _proto2 = Fragment.prototype;
  49262. _proto2.setKeyFormat = function setKeyFormat(keyFormat) {
  49263. if (this.levelkeys) {
  49264. var _key = this.levelkeys[keyFormat];
  49265. if (_key && !this._decryptdata) {
  49266. this._decryptdata = _key.getDecryptData(this.sn);
  49267. }
  49268. }
  49269. };
  49270. _proto2.abortRequests = function abortRequests() {
  49271. var _this$loader, _this$keyLoader;
  49272. (_this$loader = this.loader) === null || _this$loader === void 0 ? void 0 : _this$loader.abort();
  49273. (_this$keyLoader = this.keyLoader) === null || _this$keyLoader === void 0 ? void 0 : _this$keyLoader.abort();
  49274. };
  49275. _proto2.setElementaryStreamInfo = function setElementaryStreamInfo(type, startPTS, endPTS, startDTS, endDTS, partial) {
  49276. if (partial === void 0) {
  49277. partial = false;
  49278. }
  49279. var elementaryStreams = this.elementaryStreams;
  49280. var info = elementaryStreams[type];
  49281. if (!info) {
  49282. elementaryStreams[type] = {
  49283. startPTS: startPTS,
  49284. endPTS: endPTS,
  49285. startDTS: startDTS,
  49286. endDTS: endDTS,
  49287. partial: partial
  49288. };
  49289. return;
  49290. }
  49291. info.startPTS = Math.min(info.startPTS, startPTS);
  49292. info.endPTS = Math.max(info.endPTS, endPTS);
  49293. info.startDTS = Math.min(info.startDTS, startDTS);
  49294. info.endDTS = Math.max(info.endDTS, endDTS);
  49295. };
  49296. _proto2.clearElementaryStreamInfo = function clearElementaryStreamInfo() {
  49297. var elementaryStreams = this.elementaryStreams;
  49298. elementaryStreams[ElementaryStreamTypes.AUDIO] = null;
  49299. elementaryStreams[ElementaryStreamTypes.VIDEO] = null;
  49300. elementaryStreams[ElementaryStreamTypes.AUDIOVIDEO] = null;
  49301. };
  49302. _createClass(Fragment, [{
  49303. key: "decryptdata",
  49304. get: function get() {
  49305. var levelkeys = this.levelkeys;
  49306. if (!levelkeys && !this._decryptdata) {
  49307. return null;
  49308. }
  49309. if (!this._decryptdata && this.levelkeys && !this.levelkeys.NONE) {
  49310. var _key2 = this.levelkeys.identity;
  49311. if (_key2) {
  49312. this._decryptdata = _key2.getDecryptData(this.sn);
  49313. } else {
  49314. var keyFormats = Object.keys(this.levelkeys);
  49315. if (keyFormats.length === 1) {
  49316. return this._decryptdata = this.levelkeys[keyFormats[0]].getDecryptData(this.sn);
  49317. } else {
  49318. // Multiple keys. key-loader to call Fragment.setKeyFormat based on selected key-system.
  49319. }
  49320. }
  49321. }
  49322. return this._decryptdata;
  49323. }
  49324. }, {
  49325. key: "end",
  49326. get: function get() {
  49327. return this.start + this.duration;
  49328. }
  49329. }, {
  49330. key: "endProgramDateTime",
  49331. get: function get() {
  49332. if (this.programDateTime === null) {
  49333. return null;
  49334. }
  49335. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.programDateTime)) {
  49336. return null;
  49337. }
  49338. var duration = !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.duration) ? 0 : this.duration;
  49339. return this.programDateTime + duration * 1000;
  49340. }
  49341. }, {
  49342. key: "encrypted",
  49343. get: function get() {
  49344. var _this$_decryptdata;
  49345. // At the m3u8-parser level we need to add support for manifest signalled keyformats
  49346. // when we want the fragment to start reporting that it is encrypted.
  49347. // Currently, keyFormat will only be set for identity keys
  49348. if ((_this$_decryptdata = this._decryptdata) !== null && _this$_decryptdata !== void 0 && _this$_decryptdata.encrypted) {
  49349. return true;
  49350. } else if (this.levelkeys) {
  49351. var keyFormats = Object.keys(this.levelkeys);
  49352. var len = keyFormats.length;
  49353. if (len > 1 || len === 1 && this.levelkeys[keyFormats[0]].encrypted) {
  49354. return true;
  49355. }
  49356. }
  49357. return false;
  49358. }
  49359. }]);
  49360. return Fragment;
  49361. }(BaseSegment);
  49362. var Part = /*#__PURE__*/function (_BaseSegment2) {
  49363. _inheritsLoose(Part, _BaseSegment2);
  49364. function Part(partAttrs, frag, baseurl, index, previous) {
  49365. var _this2;
  49366. _this2 = _BaseSegment2.call(this, baseurl) || this;
  49367. _this2.fragOffset = 0;
  49368. _this2.duration = 0;
  49369. _this2.gap = false;
  49370. _this2.independent = false;
  49371. _this2.relurl = void 0;
  49372. _this2.fragment = void 0;
  49373. _this2.index = void 0;
  49374. _this2.stats = new _load_stats__WEBPACK_IMPORTED_MODULE_2__.LoadStats();
  49375. _this2.duration = partAttrs.decimalFloatingPoint('DURATION');
  49376. _this2.gap = partAttrs.bool('GAP');
  49377. _this2.independent = partAttrs.bool('INDEPENDENT');
  49378. _this2.relurl = partAttrs.enumeratedString('URI');
  49379. _this2.fragment = frag;
  49380. _this2.index = index;
  49381. var byteRange = partAttrs.enumeratedString('BYTERANGE');
  49382. if (byteRange) {
  49383. _this2.setByteRange(byteRange, previous);
  49384. }
  49385. if (previous) {
  49386. _this2.fragOffset = previous.fragOffset + previous.duration;
  49387. }
  49388. return _this2;
  49389. }
  49390. _createClass(Part, [{
  49391. key: "start",
  49392. get: function get() {
  49393. return this.fragment.start + this.fragOffset;
  49394. }
  49395. }, {
  49396. key: "end",
  49397. get: function get() {
  49398. return this.start + this.duration;
  49399. }
  49400. }, {
  49401. key: "loaded",
  49402. get: function get() {
  49403. var elementaryStreams = this.elementaryStreams;
  49404. return !!(elementaryStreams.audio || elementaryStreams.video || elementaryStreams.audiovideo);
  49405. }
  49406. }]);
  49407. return Part;
  49408. }(BaseSegment);
  49409. /***/ }),
  49410. /***/ "./src/loader/key-loader.ts":
  49411. /*!**********************************!*\
  49412. !*** ./src/loader/key-loader.ts ***!
  49413. \**********************************/
  49414. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  49415. "use strict";
  49416. __webpack_require__.r(__webpack_exports__);
  49417. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  49418. /* harmony export */ "default": () => (/* binding */ KeyLoader)
  49419. /* harmony export */ });
  49420. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  49421. /* harmony import */ var _fragment_loader__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./fragment-loader */ "./src/loader/fragment-loader.ts");
  49422. var KeyLoader = /*#__PURE__*/function () {
  49423. function KeyLoader(config) {
  49424. this.config = void 0;
  49425. this.keyUriToKeyInfo = {};
  49426. this.emeController = null;
  49427. this.config = config;
  49428. }
  49429. var _proto = KeyLoader.prototype;
  49430. _proto.abort = function abort() {
  49431. for (var uri in this.keyUriToKeyInfo) {
  49432. var loader = this.keyUriToKeyInfo[uri].loader;
  49433. if (loader) {
  49434. loader.abort();
  49435. }
  49436. }
  49437. };
  49438. _proto.detach = function detach() {
  49439. for (var uri in this.keyUriToKeyInfo) {
  49440. var keyInfo = this.keyUriToKeyInfo[uri];
  49441. // Remove cached EME keys on detach
  49442. if (keyInfo.mediaKeySessionContext || keyInfo.decryptdata.isCommonEncryption) {
  49443. delete this.keyUriToKeyInfo[uri];
  49444. }
  49445. }
  49446. };
  49447. _proto.destroy = function destroy() {
  49448. this.detach();
  49449. for (var uri in this.keyUriToKeyInfo) {
  49450. var loader = this.keyUriToKeyInfo[uri].loader;
  49451. if (loader) {
  49452. loader.destroy();
  49453. }
  49454. }
  49455. this.keyUriToKeyInfo = {};
  49456. };
  49457. _proto.createKeyLoadError = function createKeyLoadError(frag, details, networkDetails, message) {
  49458. if (details === void 0) {
  49459. details = _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR;
  49460. }
  49461. return new _fragment_loader__WEBPACK_IMPORTED_MODULE_1__.LoadError({
  49462. type: _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorTypes.NETWORK_ERROR,
  49463. details: details,
  49464. fatal: false,
  49465. frag: frag,
  49466. networkDetails: networkDetails
  49467. });
  49468. };
  49469. _proto.loadClear = function loadClear(loadingFrag, encryptedFragments) {
  49470. var _this = this;
  49471. if (this.emeController && this.config.emeEnabled) {
  49472. // access key-system with nearest key on start (loaidng frag is unencrypted)
  49473. var sn = loadingFrag.sn,
  49474. cc = loadingFrag.cc;
  49475. var _loop = function _loop(i) {
  49476. var frag = encryptedFragments[i];
  49477. if (cc <= frag.cc && (sn === 'initSegment' || sn < frag.sn)) {
  49478. _this.emeController.selectKeySystemFormat(frag).then(function (keySystemFormat) {
  49479. frag.setKeyFormat(keySystemFormat);
  49480. });
  49481. return "break";
  49482. }
  49483. };
  49484. for (var i = 0; i < encryptedFragments.length; i++) {
  49485. var _ret = _loop(i);
  49486. if (_ret === "break") break;
  49487. }
  49488. }
  49489. };
  49490. _proto.load = function load(frag) {
  49491. var _this2 = this;
  49492. if (!frag.decryptdata && frag.encrypted && this.emeController) {
  49493. // Multiple keys, but none selected, resolve in eme-controller
  49494. return this.emeController.selectKeySystemFormat(frag).then(function (keySystemFormat) {
  49495. return _this2.loadInternal(frag, keySystemFormat);
  49496. });
  49497. }
  49498. return this.loadInternal(frag);
  49499. };
  49500. _proto.loadInternal = function loadInternal(frag, keySystemFormat) {
  49501. var _keyInfo, _keyInfo2;
  49502. if (keySystemFormat) {
  49503. frag.setKeyFormat(keySystemFormat);
  49504. }
  49505. var decryptdata = frag.decryptdata;
  49506. if (!decryptdata) {
  49507. var errorMessage = keySystemFormat ? "Expected frag.decryptdata to be defined after setting format " + keySystemFormat : 'Missing decryption data on fragment in onKeyLoading';
  49508. return Promise.reject(this.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR, null, errorMessage));
  49509. }
  49510. var uri = decryptdata.uri;
  49511. if (!uri) {
  49512. return Promise.reject(this.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR, null, "Invalid key URI: \"" + uri + "\""));
  49513. }
  49514. var keyInfo = this.keyUriToKeyInfo[uri];
  49515. if ((_keyInfo = keyInfo) !== null && _keyInfo !== void 0 && _keyInfo.decryptdata.key) {
  49516. decryptdata.key = keyInfo.decryptdata.key;
  49517. return Promise.resolve({
  49518. frag: frag,
  49519. keyInfo: keyInfo
  49520. });
  49521. }
  49522. // Return key load promise as long as it does not have a mediakey session with an unusable key status
  49523. if ((_keyInfo2 = keyInfo) !== null && _keyInfo2 !== void 0 && _keyInfo2.keyLoadPromise) {
  49524. var _keyInfo$mediaKeySess;
  49525. switch ((_keyInfo$mediaKeySess = keyInfo.mediaKeySessionContext) === null || _keyInfo$mediaKeySess === void 0 ? void 0 : _keyInfo$mediaKeySess.keyStatus) {
  49526. case undefined:
  49527. case 'status-pending':
  49528. case 'usable':
  49529. case 'usable-in-future':
  49530. return keyInfo.keyLoadPromise.then(function (keyLoadedData) {
  49531. // Return the correct fragment with updated decryptdata key and loaded keyInfo
  49532. decryptdata.key = keyLoadedData.keyInfo.decryptdata.key;
  49533. return {
  49534. frag: frag,
  49535. keyInfo: keyInfo
  49536. };
  49537. });
  49538. }
  49539. // If we have a key session and status and it is not pending or usable, continue
  49540. // This will go back to the eme-controller for expired keys to get a new keyLoadPromise
  49541. }
  49542. // Load the key or return the loading promise
  49543. keyInfo = this.keyUriToKeyInfo[uri] = {
  49544. decryptdata: decryptdata,
  49545. keyLoadPromise: null,
  49546. loader: null,
  49547. mediaKeySessionContext: null
  49548. };
  49549. switch (decryptdata.method) {
  49550. case 'ISO-23001-7':
  49551. case 'SAMPLE-AES':
  49552. case 'SAMPLE-AES-CENC':
  49553. case 'SAMPLE-AES-CTR':
  49554. if (decryptdata.keyFormat === 'identity') {
  49555. // loadKeyHTTP handles http(s) and data URLs
  49556. return this.loadKeyHTTP(keyInfo, frag);
  49557. }
  49558. return this.loadKeyEME(keyInfo, frag);
  49559. case 'AES-128':
  49560. return this.loadKeyHTTP(keyInfo, frag);
  49561. default:
  49562. return Promise.reject(this.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR, null, "Key supplied with unsupported METHOD: \"" + decryptdata.method + "\""));
  49563. }
  49564. };
  49565. _proto.loadKeyEME = function loadKeyEME(keyInfo, frag) {
  49566. var keyLoadedData = {
  49567. frag: frag,
  49568. keyInfo: keyInfo
  49569. };
  49570. if (this.emeController && this.config.emeEnabled) {
  49571. var keySessionContextPromise = this.emeController.loadKey(keyLoadedData);
  49572. if (keySessionContextPromise) {
  49573. return (keyInfo.keyLoadPromise = keySessionContextPromise.then(function (keySessionContext) {
  49574. keyInfo.mediaKeySessionContext = keySessionContext;
  49575. return keyLoadedData;
  49576. })).catch(function (error) {
  49577. // Remove promise for license renewal or retry
  49578. keyInfo.keyLoadPromise = null;
  49579. throw error;
  49580. });
  49581. }
  49582. }
  49583. return Promise.resolve(keyLoadedData);
  49584. };
  49585. _proto.loadKeyHTTP = function loadKeyHTTP(keyInfo, frag) {
  49586. var _this3 = this;
  49587. var config = this.config;
  49588. var Loader = config.loader;
  49589. var keyLoader = new Loader(config);
  49590. frag.keyLoader = keyInfo.loader = keyLoader;
  49591. return keyInfo.keyLoadPromise = new Promise(function (resolve, reject) {
  49592. var loaderContext = {
  49593. keyInfo: keyInfo,
  49594. frag: frag,
  49595. responseType: 'arraybuffer',
  49596. url: keyInfo.decryptdata.uri
  49597. };
  49598. // maxRetry is 0 so that instead of retrying the same key on the same variant multiple times,
  49599. // key-loader will trigger an error and rely on stream-controller to handle retry logic.
  49600. // this will also align retry logic with fragment-loader
  49601. var loaderConfig = {
  49602. timeout: config.fragLoadingTimeOut,
  49603. maxRetry: 0,
  49604. retryDelay: config.fragLoadingRetryDelay,
  49605. maxRetryDelay: config.fragLoadingMaxRetryTimeout,
  49606. highWaterMark: 0
  49607. };
  49608. var loaderCallbacks = {
  49609. onSuccess: function onSuccess(response, stats, context, networkDetails) {
  49610. var frag = context.frag,
  49611. keyInfo = context.keyInfo,
  49612. uri = context.url;
  49613. if (!frag.decryptdata || keyInfo !== _this3.keyUriToKeyInfo[uri]) {
  49614. return reject(_this3.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR, networkDetails, 'after key load, decryptdata unset or changed'));
  49615. }
  49616. keyInfo.decryptdata.key = frag.decryptdata.key = new Uint8Array(response.data);
  49617. // detach fragment key loader on load success
  49618. frag.keyLoader = null;
  49619. keyInfo.loader = null;
  49620. resolve({
  49621. frag: frag,
  49622. keyInfo: keyInfo
  49623. });
  49624. },
  49625. onError: function onError(error, context, networkDetails) {
  49626. _this3.resetLoader(context);
  49627. reject(_this3.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_ERROR, networkDetails));
  49628. },
  49629. onTimeout: function onTimeout(stats, context, networkDetails) {
  49630. _this3.resetLoader(context);
  49631. reject(_this3.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.KEY_LOAD_TIMEOUT, networkDetails));
  49632. },
  49633. onAbort: function onAbort(stats, context, networkDetails) {
  49634. _this3.resetLoader(context);
  49635. reject(_this3.createKeyLoadError(frag, _errors__WEBPACK_IMPORTED_MODULE_0__.ErrorDetails.INTERNAL_ABORTED, networkDetails));
  49636. }
  49637. };
  49638. keyLoader.load(loaderContext, loaderConfig, loaderCallbacks);
  49639. });
  49640. };
  49641. _proto.resetLoader = function resetLoader(context) {
  49642. var frag = context.frag,
  49643. keyInfo = context.keyInfo,
  49644. uri = context.url;
  49645. var loader = keyInfo.loader;
  49646. if (frag.keyLoader === loader) {
  49647. frag.keyLoader = null;
  49648. keyInfo.loader = null;
  49649. }
  49650. delete this.keyUriToKeyInfo[uri];
  49651. if (loader) {
  49652. loader.destroy();
  49653. }
  49654. };
  49655. return KeyLoader;
  49656. }();
  49657. /***/ }),
  49658. /***/ "./src/loader/level-details.ts":
  49659. /*!*************************************!*\
  49660. !*** ./src/loader/level-details.ts ***!
  49661. \*************************************/
  49662. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  49663. "use strict";
  49664. __webpack_require__.r(__webpack_exports__);
  49665. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  49666. /* harmony export */ "LevelDetails": () => (/* binding */ LevelDetails)
  49667. /* harmony export */ });
  49668. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  49669. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  49670. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  49671. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  49672. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  49673. var DEFAULT_TARGET_DURATION = 10;
  49674. var LevelDetails = /*#__PURE__*/function () {
  49675. // Manifest reload synchronization
  49676. function LevelDetails(baseUrl) {
  49677. this.PTSKnown = false;
  49678. this.alignedSliding = false;
  49679. this.averagetargetduration = void 0;
  49680. this.endCC = 0;
  49681. this.endSN = 0;
  49682. this.fragments = void 0;
  49683. this.fragmentHint = void 0;
  49684. this.partList = null;
  49685. this.dateRanges = void 0;
  49686. this.live = true;
  49687. this.ageHeader = 0;
  49688. this.advancedDateTime = void 0;
  49689. this.updated = true;
  49690. this.advanced = true;
  49691. this.availabilityDelay = void 0;
  49692. this.misses = 0;
  49693. this.startCC = 0;
  49694. this.startSN = 0;
  49695. this.startTimeOffset = null;
  49696. this.targetduration = 0;
  49697. this.totalduration = 0;
  49698. this.type = null;
  49699. this.url = void 0;
  49700. this.m3u8 = '';
  49701. this.version = null;
  49702. this.canBlockReload = false;
  49703. this.canSkipUntil = 0;
  49704. this.canSkipDateRanges = false;
  49705. this.skippedSegments = 0;
  49706. this.recentlyRemovedDateranges = void 0;
  49707. this.partHoldBack = 0;
  49708. this.holdBack = 0;
  49709. this.partTarget = 0;
  49710. this.preloadHint = void 0;
  49711. this.renditionReports = void 0;
  49712. this.tuneInGoal = 0;
  49713. this.deltaUpdateFailed = void 0;
  49714. this.driftStartTime = 0;
  49715. this.driftEndTime = 0;
  49716. this.driftStart = 0;
  49717. this.driftEnd = 0;
  49718. this.encryptedFragments = void 0;
  49719. this.fragments = [];
  49720. this.encryptedFragments = [];
  49721. this.dateRanges = {};
  49722. this.url = baseUrl;
  49723. }
  49724. var _proto = LevelDetails.prototype;
  49725. _proto.reloaded = function reloaded(previous) {
  49726. if (!previous) {
  49727. this.advanced = true;
  49728. this.updated = true;
  49729. return;
  49730. }
  49731. var partSnDiff = this.lastPartSn - previous.lastPartSn;
  49732. var partIndexDiff = this.lastPartIndex - previous.lastPartIndex;
  49733. this.updated = this.endSN !== previous.endSN || !!partIndexDiff || !!partSnDiff;
  49734. this.advanced = this.endSN > previous.endSN || partSnDiff > 0 || partSnDiff === 0 && partIndexDiff > 0;
  49735. if (this.updated || this.advanced) {
  49736. this.misses = Math.floor(previous.misses * 0.6);
  49737. } else {
  49738. this.misses = previous.misses + 1;
  49739. }
  49740. this.availabilityDelay = previous.availabilityDelay;
  49741. };
  49742. _createClass(LevelDetails, [{
  49743. key: "hasProgramDateTime",
  49744. get: function get() {
  49745. if (this.fragments.length) {
  49746. return (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this.fragments[this.fragments.length - 1].programDateTime);
  49747. }
  49748. return false;
  49749. }
  49750. }, {
  49751. key: "levelTargetDuration",
  49752. get: function get() {
  49753. return this.averagetargetduration || this.targetduration || DEFAULT_TARGET_DURATION;
  49754. }
  49755. }, {
  49756. key: "drift",
  49757. get: function get() {
  49758. var runTime = this.driftEndTime - this.driftStartTime;
  49759. if (runTime > 0) {
  49760. var runDuration = this.driftEnd - this.driftStart;
  49761. return runDuration * 1000 / runTime;
  49762. }
  49763. return 1;
  49764. }
  49765. }, {
  49766. key: "edge",
  49767. get: function get() {
  49768. return this.partEnd || this.fragmentEnd;
  49769. }
  49770. }, {
  49771. key: "partEnd",
  49772. get: function get() {
  49773. var _this$partList;
  49774. if ((_this$partList = this.partList) !== null && _this$partList !== void 0 && _this$partList.length) {
  49775. return this.partList[this.partList.length - 1].end;
  49776. }
  49777. return this.fragmentEnd;
  49778. }
  49779. }, {
  49780. key: "fragmentEnd",
  49781. get: function get() {
  49782. var _this$fragments;
  49783. if ((_this$fragments = this.fragments) !== null && _this$fragments !== void 0 && _this$fragments.length) {
  49784. return this.fragments[this.fragments.length - 1].end;
  49785. }
  49786. return 0;
  49787. }
  49788. }, {
  49789. key: "age",
  49790. get: function get() {
  49791. if (this.advancedDateTime) {
  49792. return Math.max(Date.now() - this.advancedDateTime, 0) / 1000;
  49793. }
  49794. return 0;
  49795. }
  49796. }, {
  49797. key: "lastPartIndex",
  49798. get: function get() {
  49799. var _this$partList2;
  49800. if ((_this$partList2 = this.partList) !== null && _this$partList2 !== void 0 && _this$partList2.length) {
  49801. return this.partList[this.partList.length - 1].index;
  49802. }
  49803. return -1;
  49804. }
  49805. }, {
  49806. key: "lastPartSn",
  49807. get: function get() {
  49808. var _this$partList3;
  49809. if ((_this$partList3 = this.partList) !== null && _this$partList3 !== void 0 && _this$partList3.length) {
  49810. return this.partList[this.partList.length - 1].fragment.sn;
  49811. }
  49812. return this.endSN;
  49813. }
  49814. }]);
  49815. return LevelDetails;
  49816. }();
  49817. /***/ }),
  49818. /***/ "./src/loader/level-key.ts":
  49819. /*!*********************************!*\
  49820. !*** ./src/loader/level-key.ts ***!
  49821. \*********************************/
  49822. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  49823. "use strict";
  49824. __webpack_require__.r(__webpack_exports__);
  49825. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  49826. /* harmony export */ "LevelKey": () => (/* binding */ LevelKey)
  49827. /* harmony export */ });
  49828. /* harmony import */ var _utils_keysystem_util__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/keysystem-util */ "./src/utils/keysystem-util.ts");
  49829. /* harmony import */ var _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/mediakeys-helper */ "./src/utils/mediakeys-helper.ts");
  49830. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  49831. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  49832. /* harmony import */ var _utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/numeric-encoding-utils */ "./src/utils/numeric-encoding-utils.ts");
  49833. var keyUriToKeyIdMap = {};
  49834. var LevelKey = /*#__PURE__*/function () {
  49835. LevelKey.clearKeyUriToKeyIdMap = function clearKeyUriToKeyIdMap() {
  49836. keyUriToKeyIdMap = {};
  49837. };
  49838. function LevelKey(method, uri, format, formatversions, iv) {
  49839. if (formatversions === void 0) {
  49840. formatversions = [1];
  49841. }
  49842. if (iv === void 0) {
  49843. iv = null;
  49844. }
  49845. this.uri = void 0;
  49846. this.method = void 0;
  49847. this.keyFormat = void 0;
  49848. this.keyFormatVersions = void 0;
  49849. this.encrypted = void 0;
  49850. this.isCommonEncryption = void 0;
  49851. this.iv = null;
  49852. this.key = null;
  49853. this.keyId = null;
  49854. this.pssh = null;
  49855. this.method = method;
  49856. this.uri = uri;
  49857. this.keyFormat = format;
  49858. this.keyFormatVersions = formatversions;
  49859. this.iv = iv;
  49860. this.encrypted = method ? method !== 'NONE' : false;
  49861. this.isCommonEncryption = this.encrypted && method !== 'AES-128';
  49862. }
  49863. var _proto = LevelKey.prototype;
  49864. _proto.isSupported = function isSupported() {
  49865. // If it's Segment encryption or No encryption, just select that key system
  49866. if (this.method) {
  49867. if (this.method === 'AES-128' || this.method === 'NONE') {
  49868. return true;
  49869. }
  49870. switch (this.keyFormat) {
  49871. case 'identity':
  49872. // Maintain support for clear SAMPLE-AES with MPEG-3 TS
  49873. return this.method === 'SAMPLE-AES';
  49874. case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.FAIRPLAY:
  49875. case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.WIDEVINE:
  49876. case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.PLAYREADY:
  49877. case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.CLEARKEY:
  49878. return ['ISO-23001-7', 'SAMPLE-AES', 'SAMPLE-AES-CENC', 'SAMPLE-AES-CTR'].indexOf(this.method) !== -1;
  49879. }
  49880. }
  49881. return false;
  49882. };
  49883. _proto.getDecryptData = function getDecryptData(sn) {
  49884. if (!this.encrypted || !this.uri) {
  49885. return null;
  49886. }
  49887. if (this.method === 'AES-128' && this.uri && !this.iv) {
  49888. if (typeof sn !== 'number') {
  49889. // We are fetching decryption data for a initialization segment
  49890. // If the segment was encrypted with AES-128
  49891. // It must have an IV defined. We cannot substitute the Segment Number in.
  49892. if (this.method === 'AES-128' && !this.iv) {
  49893. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("missing IV for initialization segment with method=\"" + this.method + "\" - compliance issue");
  49894. }
  49895. // Explicitly set sn to resulting value from implicit conversions 'initSegment' values for IV generation.
  49896. sn = 0;
  49897. }
  49898. var iv = createInitializationVector(sn);
  49899. var decryptdata = new LevelKey(this.method, this.uri, 'identity', this.keyFormatVersions, iv);
  49900. return decryptdata;
  49901. }
  49902. // Initialize keyId if possible
  49903. var keyBytes = (0,_utils_keysystem_util__WEBPACK_IMPORTED_MODULE_0__.convertDataUriToArrayBytes)(this.uri);
  49904. if (keyBytes) {
  49905. switch (this.keyFormat) {
  49906. case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.WIDEVINE:
  49907. this.pssh = keyBytes;
  49908. // In case of widevine keyID is embedded in PSSH box. Read Key ID.
  49909. if (keyBytes.length >= 22) {
  49910. this.keyId = keyBytes.subarray(keyBytes.length - 22, keyBytes.length - 6);
  49911. }
  49912. break;
  49913. case _utils_mediakeys_helper__WEBPACK_IMPORTED_MODULE_1__.KeySystemFormats.PLAYREADY:
  49914. {
  49915. var PlayReadyKeySystemUUID = new Uint8Array([0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86, 0xab, 0x92, 0xe6, 0x5b, 0xe0, 0x88, 0x5f, 0x95]);
  49916. this.pssh = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.mp4pssh)(PlayReadyKeySystemUUID, null, keyBytes);
  49917. var keyBytesUtf16 = new Uint16Array(keyBytes.buffer, keyBytes.byteOffset, keyBytes.byteLength / 2);
  49918. var keyByteStr = String.fromCharCode.apply(null, Array.from(keyBytesUtf16));
  49919. // Parse Playready WRMHeader XML
  49920. var xmlKeyBytes = keyByteStr.substring(keyByteStr.indexOf('<'), keyByteStr.length);
  49921. var parser = new DOMParser();
  49922. var xmlDoc = parser.parseFromString(xmlKeyBytes, 'text/xml');
  49923. var keyData = xmlDoc.getElementsByTagName('KID')[0];
  49924. if (keyData) {
  49925. var keyId = keyData.childNodes[0] ? keyData.childNodes[0].nodeValue : keyData.getAttribute('VALUE');
  49926. if (keyId) {
  49927. var keyIdArray = (0,_utils_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_4__.base64Decode)(keyId).subarray(0, 16);
  49928. // KID value in PRO is a base64-encoded little endian GUID interpretation of UUID
  49929. // KID value in ‘tenc’ is a big endian UUID GUID interpretation of UUID
  49930. (0,_utils_keysystem_util__WEBPACK_IMPORTED_MODULE_0__.changeEndianness)(keyIdArray);
  49931. this.keyId = keyIdArray;
  49932. }
  49933. }
  49934. break;
  49935. }
  49936. default:
  49937. {
  49938. var keydata = keyBytes.subarray(0, 16);
  49939. if (keydata.length !== 16) {
  49940. var padded = new Uint8Array(16);
  49941. padded.set(keydata, 16 - keydata.length);
  49942. keydata = padded;
  49943. }
  49944. this.keyId = keydata;
  49945. break;
  49946. }
  49947. }
  49948. }
  49949. // Default behavior: assign a new keyId for each uri
  49950. if (!this.keyId || this.keyId.byteLength !== 16) {
  49951. var _keyId = keyUriToKeyIdMap[this.uri];
  49952. if (!_keyId) {
  49953. var val = Object.keys(keyUriToKeyIdMap).length % Number.MAX_SAFE_INTEGER;
  49954. _keyId = new Uint8Array(16);
  49955. var dv = new DataView(_keyId.buffer, 12, 4); // Just set the last 4 bytes
  49956. dv.setUint32(0, val);
  49957. keyUriToKeyIdMap[this.uri] = _keyId;
  49958. }
  49959. this.keyId = _keyId;
  49960. }
  49961. return this;
  49962. };
  49963. return LevelKey;
  49964. }();
  49965. function createInitializationVector(segmentNumber) {
  49966. var uint8View = new Uint8Array(16);
  49967. for (var i = 12; i < 16; i++) {
  49968. uint8View[i] = segmentNumber >> 8 * (15 - i) & 0xff;
  49969. }
  49970. return uint8View;
  49971. }
  49972. /***/ }),
  49973. /***/ "./src/loader/load-stats.ts":
  49974. /*!**********************************!*\
  49975. !*** ./src/loader/load-stats.ts ***!
  49976. \**********************************/
  49977. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  49978. "use strict";
  49979. __webpack_require__.r(__webpack_exports__);
  49980. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  49981. /* harmony export */ "LoadStats": () => (/* binding */ LoadStats)
  49982. /* harmony export */ });
  49983. var LoadStats = function LoadStats() {
  49984. this.aborted = false;
  49985. this.loaded = 0;
  49986. this.retry = 0;
  49987. this.total = 0;
  49988. this.chunkCount = 0;
  49989. this.bwEstimate = 0;
  49990. this.loading = {
  49991. start: 0,
  49992. first: 0,
  49993. end: 0
  49994. };
  49995. this.parsing = {
  49996. start: 0,
  49997. end: 0
  49998. };
  49999. this.buffering = {
  50000. start: 0,
  50001. first: 0,
  50002. end: 0
  50003. };
  50004. };
  50005. /***/ }),
  50006. /***/ "./src/loader/m3u8-parser.ts":
  50007. /*!***********************************!*\
  50008. !*** ./src/loader/m3u8-parser.ts ***!
  50009. \***********************************/
  50010. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  50011. "use strict";
  50012. __webpack_require__.r(__webpack_exports__);
  50013. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  50014. /* harmony export */ "default": () => (/* binding */ M3U8Parser)
  50015. /* harmony export */ });
  50016. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  50017. /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! url-toolkit */ "./node_modules/url-toolkit/src/url-toolkit.js");
  50018. /* harmony import */ var url_toolkit__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(url_toolkit__WEBPACK_IMPORTED_MODULE_1__);
  50019. /* harmony import */ var _date_range__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./date-range */ "./src/loader/date-range.ts");
  50020. /* harmony import */ var _fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./fragment */ "./src/loader/fragment.ts");
  50021. /* harmony import */ var _level_details__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./level-details */ "./src/loader/level-details.ts");
  50022. /* harmony import */ var _level_key__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./level-key */ "./src/loader/level-key.ts");
  50023. /* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts");
  50024. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  50025. /* harmony import */ var _utils_codecs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/codecs */ "./src/utils/codecs.ts");
  50026. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  50027. // https://regex101.com is your friend
  50028. var MASTER_PLAYLIST_REGEX = /#EXT-X-STREAM-INF:([^\r\n]*)(?:[\r\n](?:#[^\r\n]*)?)*([^\r\n]+)|#EXT-X-SESSION-DATA:([^\r\n]*)[\r\n]+|#EXT-X-SESSION-KEY:([^\n\r]*)[\r\n]+/g;
  50029. var MASTER_PLAYLIST_MEDIA_REGEX = /#EXT-X-MEDIA:(.*)/g;
  50030. var LEVEL_PLAYLIST_REGEX_FAST = new RegExp([/#EXTINF:\s*(\d*(?:\.\d+)?)(?:,(.*)\s+)?/.source,
  50031. // duration (#EXTINF:<duration>,<title>), group 1 => duration, group 2 => title
  50032. /(?!#) *(\S[\S ]*)/.source,
  50033. // segment URI, group 3 => the URI (note newline is not eaten)
  50034. /#EXT-X-BYTERANGE:*(.+)/.source,
  50035. // next segment's byterange, group 4 => range spec (x@y)
  50036. /#EXT-X-PROGRAM-DATE-TIME:(.+)/.source,
  50037. // next segment's program date/time group 5 => the datetime spec
  50038. /#.*/.source // All other non-segment oriented tags will match with all groups empty
  50039. ].join('|'), 'g');
  50040. var LEVEL_PLAYLIST_REGEX_SLOW = new RegExp([/#(EXTM3U)/.source, /#EXT-X-(DATERANGE|KEY|MAP|PART|PART-INF|PLAYLIST-TYPE|PRELOAD-HINT|RENDITION-REPORT|SERVER-CONTROL|SKIP|START):(.+)/.source, /#EXT-X-(BITRATE|DISCONTINUITY-SEQUENCE|MEDIA-SEQUENCE|TARGETDURATION|VERSION): *(\d+)/.source, /#EXT-X-(DISCONTINUITY|ENDLIST|GAP)/.source, /(#)([^:]*):(.*)/.source, /(#)(.*)(?:.*)\r?\n?/.source].join('|'));
  50041. var M3U8Parser = /*#__PURE__*/function () {
  50042. function M3U8Parser() {}
  50043. M3U8Parser.findGroup = function findGroup(groups, mediaGroupId) {
  50044. for (var i = 0; i < groups.length; i++) {
  50045. var group = groups[i];
  50046. if (group.id === mediaGroupId) {
  50047. return group;
  50048. }
  50049. }
  50050. };
  50051. M3U8Parser.convertAVC1ToAVCOTI = function convertAVC1ToAVCOTI(codec) {
  50052. // Convert avc1 codec string from RFC-4281 to RFC-6381 for MediaSource.isTypeSupported
  50053. var avcdata = codec.split('.');
  50054. if (avcdata.length > 2) {
  50055. var result = avcdata.shift() + '.';
  50056. result += parseInt(avcdata.shift()).toString(16);
  50057. result += ('000' + parseInt(avcdata.shift()).toString(16)).slice(-4);
  50058. return result;
  50059. }
  50060. return codec;
  50061. };
  50062. M3U8Parser.resolve = function resolve(url, baseUrl) {
  50063. return (0,url_toolkit__WEBPACK_IMPORTED_MODULE_1__.buildAbsoluteURL)(baseUrl, url, {
  50064. alwaysNormalize: true
  50065. });
  50066. };
  50067. M3U8Parser.parseMasterPlaylist = function parseMasterPlaylist(string, baseurl) {
  50068. var levels = [];
  50069. var levelsWithKnownCodecs = [];
  50070. var sessionData = {};
  50071. var sessionKeys = [];
  50072. var hasSessionData = false;
  50073. MASTER_PLAYLIST_REGEX.lastIndex = 0;
  50074. var result;
  50075. while ((result = MASTER_PLAYLIST_REGEX.exec(string)) != null) {
  50076. if (result[1]) {
  50077. var _level$unknownCodecs;
  50078. // '#EXT-X-STREAM-INF' is found, parse level tag in group 1
  50079. var attrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(result[1]);
  50080. var level = {
  50081. attrs: attrs,
  50082. bitrate: attrs.decimalInteger('AVERAGE-BANDWIDTH') || attrs.decimalInteger('BANDWIDTH'),
  50083. name: attrs.NAME,
  50084. url: M3U8Parser.resolve(result[2], baseurl)
  50085. };
  50086. var resolution = attrs.decimalResolution('RESOLUTION');
  50087. if (resolution) {
  50088. level.width = resolution.width;
  50089. level.height = resolution.height;
  50090. }
  50091. setCodecs((attrs.CODECS || '').split(/[ ,]+/).filter(function (c) {
  50092. return c;
  50093. }), level);
  50094. if (level.videoCodec && level.videoCodec.indexOf('avc1') !== -1) {
  50095. level.videoCodec = M3U8Parser.convertAVC1ToAVCOTI(level.videoCodec);
  50096. }
  50097. if (!((_level$unknownCodecs = level.unknownCodecs) !== null && _level$unknownCodecs !== void 0 && _level$unknownCodecs.length)) {
  50098. levelsWithKnownCodecs.push(level);
  50099. }
  50100. levels.push(level);
  50101. } else if (result[3]) {
  50102. // '#EXT-X-SESSION-DATA' is found, parse session data in group 3
  50103. var sessionAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(result[3]);
  50104. if (sessionAttrs['DATA-ID']) {
  50105. hasSessionData = true;
  50106. sessionData[sessionAttrs['DATA-ID']] = sessionAttrs;
  50107. }
  50108. } else if (result[4]) {
  50109. // '#EXT-X-SESSION-KEY' is found
  50110. var keyTag = result[4];
  50111. var sessionKey = parseKey(keyTag, baseurl);
  50112. if (sessionKey.encrypted && sessionKey.isSupported()) {
  50113. sessionKeys.push(sessionKey);
  50114. } else {
  50115. _utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("[Keys] Ignoring invalid EXT-X-SESSION-KEY tag: \"" + keyTag + "\"");
  50116. }
  50117. }
  50118. }
  50119. // Filter out levels with unknown codecs if it does not remove all levels
  50120. var stripUnknownCodecLevels = levelsWithKnownCodecs.length > 0 && levelsWithKnownCodecs.length < levels.length;
  50121. return {
  50122. levels: stripUnknownCodecLevels ? levelsWithKnownCodecs : levels,
  50123. sessionData: hasSessionData ? sessionData : null,
  50124. sessionKeys: sessionKeys.length ? sessionKeys : null
  50125. };
  50126. };
  50127. M3U8Parser.parseMasterPlaylistMedia = function parseMasterPlaylistMedia(string, baseurl, type, groups) {
  50128. if (groups === void 0) {
  50129. groups = [];
  50130. }
  50131. var result;
  50132. var medias = [];
  50133. var id = 0;
  50134. MASTER_PLAYLIST_MEDIA_REGEX.lastIndex = 0;
  50135. while ((result = MASTER_PLAYLIST_MEDIA_REGEX.exec(string)) !== null) {
  50136. var attrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(result[1]);
  50137. if (attrs.TYPE === type) {
  50138. var media = {
  50139. attrs: attrs,
  50140. bitrate: 0,
  50141. id: id++,
  50142. groupId: attrs['GROUP-ID'],
  50143. instreamId: attrs['INSTREAM-ID'],
  50144. name: attrs.NAME || attrs.LANGUAGE || '',
  50145. type: type,
  50146. default: attrs.bool('DEFAULT'),
  50147. autoselect: attrs.bool('AUTOSELECT'),
  50148. forced: attrs.bool('FORCED'),
  50149. lang: attrs.LANGUAGE,
  50150. url: attrs.URI ? M3U8Parser.resolve(attrs.URI, baseurl) : ''
  50151. };
  50152. if (groups.length) {
  50153. // If there are audio or text groups signalled in the manifest, let's look for a matching codec string for this track
  50154. // If we don't find the track signalled, lets use the first audio groups codec we have
  50155. // Acting as a best guess
  50156. var groupCodec = M3U8Parser.findGroup(groups, media.groupId) || groups[0];
  50157. assignCodec(media, groupCodec, 'audioCodec');
  50158. assignCodec(media, groupCodec, 'textCodec');
  50159. }
  50160. medias.push(media);
  50161. }
  50162. }
  50163. return medias;
  50164. };
  50165. M3U8Parser.parseLevelPlaylist = function parseLevelPlaylist(string, baseurl, id, type, levelUrlId) {
  50166. var level = new _level_details__WEBPACK_IMPORTED_MODULE_4__.LevelDetails(baseurl);
  50167. var fragments = level.fragments;
  50168. // The most recent init segment seen (applies to all subsequent segments)
  50169. var currentInitSegment = null;
  50170. var currentSN = 0;
  50171. var currentPart = 0;
  50172. var totalduration = 0;
  50173. var discontinuityCounter = 0;
  50174. var prevFrag = null;
  50175. var frag = new _fragment__WEBPACK_IMPORTED_MODULE_3__.Fragment(type, baseurl);
  50176. var result;
  50177. var i;
  50178. var levelkeys;
  50179. var firstPdtIndex = -1;
  50180. var createNextFrag = false;
  50181. LEVEL_PLAYLIST_REGEX_FAST.lastIndex = 0;
  50182. level.m3u8 = string;
  50183. while ((result = LEVEL_PLAYLIST_REGEX_FAST.exec(string)) !== null) {
  50184. if (createNextFrag) {
  50185. createNextFrag = false;
  50186. frag = new _fragment__WEBPACK_IMPORTED_MODULE_3__.Fragment(type, baseurl);
  50187. // setup the next fragment for part loading
  50188. frag.start = totalduration;
  50189. frag.sn = currentSN;
  50190. frag.cc = discontinuityCounter;
  50191. frag.level = id;
  50192. if (currentInitSegment) {
  50193. frag.initSegment = currentInitSegment;
  50194. frag.rawProgramDateTime = currentInitSegment.rawProgramDateTime;
  50195. currentInitSegment.rawProgramDateTime = null;
  50196. }
  50197. }
  50198. var duration = result[1];
  50199. if (duration) {
  50200. // INF
  50201. frag.duration = parseFloat(duration);
  50202. // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
  50203. var title = (' ' + result[2]).slice(1);
  50204. frag.title = title || null;
  50205. frag.tagList.push(title ? ['INF', duration, title] : ['INF', duration]);
  50206. } else if (result[3]) {
  50207. // url
  50208. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.duration)) {
  50209. frag.start = totalduration;
  50210. if (levelkeys) {
  50211. setFragLevelKeys(frag, levelkeys, level);
  50212. }
  50213. frag.sn = currentSN;
  50214. frag.level = id;
  50215. frag.cc = discontinuityCounter;
  50216. frag.urlId = levelUrlId;
  50217. fragments.push(frag);
  50218. // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
  50219. frag.relurl = (' ' + result[3]).slice(1);
  50220. assignProgramDateTime(frag, prevFrag);
  50221. prevFrag = frag;
  50222. totalduration += frag.duration;
  50223. currentSN++;
  50224. currentPart = 0;
  50225. createNextFrag = true;
  50226. }
  50227. } else if (result[4]) {
  50228. // X-BYTERANGE
  50229. var data = (' ' + result[4]).slice(1);
  50230. if (prevFrag) {
  50231. frag.setByteRange(data, prevFrag);
  50232. } else {
  50233. frag.setByteRange(data);
  50234. }
  50235. } else if (result[5]) {
  50236. // PROGRAM-DATE-TIME
  50237. // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
  50238. frag.rawProgramDateTime = (' ' + result[5]).slice(1);
  50239. frag.tagList.push(['PROGRAM-DATE-TIME', frag.rawProgramDateTime]);
  50240. if (firstPdtIndex === -1) {
  50241. firstPdtIndex = fragments.length;
  50242. }
  50243. } else {
  50244. result = result[0].match(LEVEL_PLAYLIST_REGEX_SLOW);
  50245. if (!result) {
  50246. _utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn('No matches on slow regex match for level playlist!');
  50247. continue;
  50248. }
  50249. for (i = 1; i < result.length; i++) {
  50250. if (typeof result[i] !== 'undefined') {
  50251. break;
  50252. }
  50253. }
  50254. // avoid sliced strings https://github.com/video-dev/hls.js/issues/939
  50255. var tag = (' ' + result[i]).slice(1);
  50256. var value1 = (' ' + result[i + 1]).slice(1);
  50257. var value2 = result[i + 2] ? (' ' + result[i + 2]).slice(1) : '';
  50258. switch (tag) {
  50259. case 'PLAYLIST-TYPE':
  50260. level.type = value1.toUpperCase();
  50261. break;
  50262. case 'MEDIA-SEQUENCE':
  50263. currentSN = level.startSN = parseInt(value1);
  50264. break;
  50265. case 'SKIP':
  50266. {
  50267. var skipAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50268. var skippedSegments = skipAttrs.decimalInteger('SKIPPED-SEGMENTS');
  50269. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(skippedSegments)) {
  50270. level.skippedSegments = skippedSegments;
  50271. // This will result in fragments[] containing undefined values, which we will fill in with `mergeDetails`
  50272. for (var _i = skippedSegments; _i--;) {
  50273. fragments.unshift(null);
  50274. }
  50275. currentSN += skippedSegments;
  50276. }
  50277. var recentlyRemovedDateranges = skipAttrs.enumeratedString('RECENTLY-REMOVED-DATERANGES');
  50278. if (recentlyRemovedDateranges) {
  50279. level.recentlyRemovedDateranges = recentlyRemovedDateranges.split('\t');
  50280. }
  50281. break;
  50282. }
  50283. case 'TARGETDURATION':
  50284. level.targetduration = parseFloat(value1);
  50285. break;
  50286. case 'VERSION':
  50287. level.version = parseInt(value1);
  50288. break;
  50289. case 'EXTM3U':
  50290. break;
  50291. case 'ENDLIST':
  50292. level.live = false;
  50293. break;
  50294. case '#':
  50295. if (value1 || value2) {
  50296. frag.tagList.push(value2 ? [value1, value2] : [value1]);
  50297. }
  50298. break;
  50299. case 'DISCONTINUITY':
  50300. discontinuityCounter++;
  50301. frag.tagList.push(['DIS']);
  50302. break;
  50303. case 'GAP':
  50304. frag.tagList.push([tag]);
  50305. break;
  50306. case 'BITRATE':
  50307. frag.tagList.push([tag, value1]);
  50308. break;
  50309. case 'DATERANGE':
  50310. {
  50311. var dateRangeAttr = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50312. var dateRange = new _date_range__WEBPACK_IMPORTED_MODULE_2__.DateRange(dateRangeAttr, level.dateRanges[dateRangeAttr.ID]);
  50313. if (dateRange.isValid || level.skippedSegments) {
  50314. level.dateRanges[dateRange.id] = dateRange;
  50315. } else {
  50316. _utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("Ignoring invalid DATERANGE tag: \"" + value1 + "\"");
  50317. }
  50318. // Add to fragment tag list for backwards compatibility (< v1.2.0)
  50319. frag.tagList.push(['EXT-X-DATERANGE', value1]);
  50320. break;
  50321. }
  50322. case 'DISCONTINUITY-SEQUENCE':
  50323. discontinuityCounter = parseInt(value1);
  50324. break;
  50325. case 'KEY':
  50326. {
  50327. var levelKey = parseKey(value1, baseurl);
  50328. if (levelKey.isSupported()) {
  50329. if (levelKey.method === 'NONE') {
  50330. levelkeys = undefined;
  50331. break;
  50332. }
  50333. if (!levelkeys) {
  50334. levelkeys = {};
  50335. }
  50336. if (levelkeys[levelKey.keyFormat]) {
  50337. levelkeys = _extends({}, levelkeys);
  50338. }
  50339. levelkeys[levelKey.keyFormat] = levelKey;
  50340. } else {
  50341. _utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("[Keys] Ignoring invalid EXT-X-KEY tag: \"" + value1 + "\"");
  50342. }
  50343. break;
  50344. }
  50345. case 'START':
  50346. {
  50347. var startAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50348. var startTimeOffset = startAttrs.decimalFloatingPoint('TIME-OFFSET');
  50349. // TIME-OFFSET can be 0
  50350. if ((0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(startTimeOffset)) {
  50351. level.startTimeOffset = startTimeOffset;
  50352. }
  50353. break;
  50354. }
  50355. case 'MAP':
  50356. {
  50357. var mapAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50358. if (frag.duration) {
  50359. // Initial segment tag is after segment duration tag.
  50360. // #EXTINF: 6.0
  50361. // #EXT-X-MAP:URI="init.mp4
  50362. var init = new _fragment__WEBPACK_IMPORTED_MODULE_3__.Fragment(type, baseurl);
  50363. setInitSegment(init, mapAttrs, id, levelkeys);
  50364. currentInitSegment = init;
  50365. frag.initSegment = currentInitSegment;
  50366. if (currentInitSegment.rawProgramDateTime && !frag.rawProgramDateTime) {
  50367. frag.rawProgramDateTime = currentInitSegment.rawProgramDateTime;
  50368. }
  50369. } else {
  50370. // Initial segment tag is before segment duration tag
  50371. setInitSegment(frag, mapAttrs, id, levelkeys);
  50372. currentInitSegment = frag;
  50373. createNextFrag = true;
  50374. }
  50375. break;
  50376. }
  50377. case 'SERVER-CONTROL':
  50378. {
  50379. var serverControlAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50380. level.canBlockReload = serverControlAttrs.bool('CAN-BLOCK-RELOAD');
  50381. level.canSkipUntil = serverControlAttrs.optionalFloat('CAN-SKIP-UNTIL', 0);
  50382. level.canSkipDateRanges = level.canSkipUntil > 0 && serverControlAttrs.bool('CAN-SKIP-DATERANGES');
  50383. level.partHoldBack = serverControlAttrs.optionalFloat('PART-HOLD-BACK', 0);
  50384. level.holdBack = serverControlAttrs.optionalFloat('HOLD-BACK', 0);
  50385. break;
  50386. }
  50387. case 'PART-INF':
  50388. {
  50389. var partInfAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50390. level.partTarget = partInfAttrs.decimalFloatingPoint('PART-TARGET');
  50391. break;
  50392. }
  50393. case 'PART':
  50394. {
  50395. var partList = level.partList;
  50396. if (!partList) {
  50397. partList = level.partList = [];
  50398. }
  50399. var previousFragmentPart = currentPart > 0 ? partList[partList.length - 1] : undefined;
  50400. var index = currentPart++;
  50401. var part = new _fragment__WEBPACK_IMPORTED_MODULE_3__.Part(new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1), frag, baseurl, index, previousFragmentPart);
  50402. partList.push(part);
  50403. frag.duration += part.duration;
  50404. break;
  50405. }
  50406. case 'PRELOAD-HINT':
  50407. {
  50408. var preloadHintAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50409. level.preloadHint = preloadHintAttrs;
  50410. break;
  50411. }
  50412. case 'RENDITION-REPORT':
  50413. {
  50414. var renditionReportAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(value1);
  50415. level.renditionReports = level.renditionReports || [];
  50416. level.renditionReports.push(renditionReportAttrs);
  50417. break;
  50418. }
  50419. default:
  50420. _utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.warn("line parsed but not handled: " + result);
  50421. break;
  50422. }
  50423. }
  50424. }
  50425. if (prevFrag && !prevFrag.relurl) {
  50426. fragments.pop();
  50427. totalduration -= prevFrag.duration;
  50428. if (level.partList) {
  50429. level.fragmentHint = prevFrag;
  50430. }
  50431. } else if (level.partList) {
  50432. assignProgramDateTime(frag, prevFrag);
  50433. frag.cc = discontinuityCounter;
  50434. level.fragmentHint = frag;
  50435. if (levelkeys) {
  50436. setFragLevelKeys(frag, levelkeys, level);
  50437. }
  50438. }
  50439. var fragmentLength = fragments.length;
  50440. var firstFragment = fragments[0];
  50441. var lastFragment = fragments[fragmentLength - 1];
  50442. totalduration += level.skippedSegments * level.targetduration;
  50443. if (totalduration > 0 && fragmentLength && lastFragment) {
  50444. level.averagetargetduration = totalduration / fragmentLength;
  50445. var lastSn = lastFragment.sn;
  50446. level.endSN = lastSn !== 'initSegment' ? lastSn : 0;
  50447. if (!level.live) {
  50448. lastFragment.endList = true;
  50449. }
  50450. if (firstFragment) {
  50451. level.startCC = firstFragment.cc;
  50452. }
  50453. } else {
  50454. level.endSN = 0;
  50455. level.startCC = 0;
  50456. }
  50457. if (level.fragmentHint) {
  50458. totalduration += level.fragmentHint.duration;
  50459. }
  50460. level.totalduration = totalduration;
  50461. level.endCC = discontinuityCounter;
  50462. /**
  50463. * Backfill any missing PDT values
  50464. * "If the first EXT-X-PROGRAM-DATE-TIME tag in a Playlist appears after
  50465. * one or more Media Segment URIs, the client SHOULD extrapolate
  50466. * backward from that tag (using EXTINF durations and/or media
  50467. * timestamps) to associate dates with those segments."
  50468. * We have already extrapolated forward, but all fragments up to the first instance of PDT do not have their PDTs
  50469. * computed.
  50470. */
  50471. if (firstPdtIndex > 0) {
  50472. backfillProgramDateTimes(fragments, firstPdtIndex);
  50473. }
  50474. return level;
  50475. };
  50476. return M3U8Parser;
  50477. }();
  50478. function parseKey(keyTag, baseurl) {
  50479. var _keyAttrs$enumeratedS, _keyAttrs$enumeratedS2;
  50480. // https://tools.ietf.org/html/rfc8216#section-4.3.2.4
  50481. var keyAttrs = new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList(keyTag);
  50482. var decryptmethod = (_keyAttrs$enumeratedS = keyAttrs.enumeratedString('METHOD')) != null ? _keyAttrs$enumeratedS : '';
  50483. var decrypturi = keyAttrs.URI;
  50484. var decryptiv = keyAttrs.hexadecimalInteger('IV');
  50485. var decryptkeyformatversions = keyAttrs.enumeratedString('KEYFORMATVERSIONS');
  50486. // From RFC: This attribute is OPTIONAL; its absence indicates an implicit value of "identity".
  50487. var decryptkeyformat = (_keyAttrs$enumeratedS2 = keyAttrs.enumeratedString('KEYFORMAT')) != null ? _keyAttrs$enumeratedS2 : 'identity';
  50488. if (decrypturi && keyAttrs.IV && !decryptiv) {
  50489. _utils_logger__WEBPACK_IMPORTED_MODULE_7__.logger.error("Invalid IV: " + keyAttrs.IV);
  50490. }
  50491. // If decrypturi is a URI with a scheme, then baseurl will be ignored
  50492. // No uri is allowed when METHOD is NONE
  50493. var resolvedUri = decrypturi ? M3U8Parser.resolve(decrypturi, baseurl) : '';
  50494. var keyFormatVersions = (decryptkeyformatversions ? decryptkeyformatversions : '1').split('/').map(Number).filter(Number.isFinite);
  50495. return new _level_key__WEBPACK_IMPORTED_MODULE_5__.LevelKey(decryptmethod, resolvedUri, decryptkeyformat, keyFormatVersions, decryptiv);
  50496. }
  50497. function setCodecs(codecs, level) {
  50498. ['video', 'audio', 'text'].forEach(function (type) {
  50499. var filtered = codecs.filter(function (codec) {
  50500. return (0,_utils_codecs__WEBPACK_IMPORTED_MODULE_8__.isCodecType)(codec, type);
  50501. });
  50502. if (filtered.length) {
  50503. var preferred = filtered.filter(function (codec) {
  50504. return codec.lastIndexOf('avc1', 0) === 0 || codec.lastIndexOf('mp4a', 0) === 0;
  50505. });
  50506. level[type + "Codec"] = preferred.length > 0 ? preferred[0] : filtered[0];
  50507. // remove from list
  50508. codecs = codecs.filter(function (codec) {
  50509. return filtered.indexOf(codec) === -1;
  50510. });
  50511. }
  50512. });
  50513. level.unknownCodecs = codecs;
  50514. }
  50515. function assignCodec(media, groupItem, codecProperty) {
  50516. var codecValue = groupItem[codecProperty];
  50517. if (codecValue) {
  50518. media[codecProperty] = codecValue;
  50519. }
  50520. }
  50521. function backfillProgramDateTimes(fragments, firstPdtIndex) {
  50522. var fragPrev = fragments[firstPdtIndex];
  50523. for (var i = firstPdtIndex; i--;) {
  50524. var frag = fragments[i];
  50525. // Exit on delta-playlist skipped segments
  50526. if (!frag) {
  50527. return;
  50528. }
  50529. frag.programDateTime = fragPrev.programDateTime - frag.duration * 1000;
  50530. fragPrev = frag;
  50531. }
  50532. }
  50533. function assignProgramDateTime(frag, prevFrag) {
  50534. if (frag.rawProgramDateTime) {
  50535. frag.programDateTime = Date.parse(frag.rawProgramDateTime);
  50536. } else if (prevFrag !== null && prevFrag !== void 0 && prevFrag.programDateTime) {
  50537. frag.programDateTime = prevFrag.endProgramDateTime;
  50538. }
  50539. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(frag.programDateTime)) {
  50540. frag.programDateTime = null;
  50541. frag.rawProgramDateTime = null;
  50542. }
  50543. }
  50544. function setInitSegment(frag, mapAttrs, id, levelkeys) {
  50545. frag.relurl = mapAttrs.URI;
  50546. if (mapAttrs.BYTERANGE) {
  50547. frag.setByteRange(mapAttrs.BYTERANGE);
  50548. }
  50549. frag.level = id;
  50550. frag.sn = 'initSegment';
  50551. if (levelkeys) {
  50552. frag.levelkeys = levelkeys;
  50553. }
  50554. frag.initSegment = null;
  50555. }
  50556. function setFragLevelKeys(frag, levelkeys, level) {
  50557. frag.levelkeys = levelkeys;
  50558. var encryptedFragments = level.encryptedFragments;
  50559. if ((!encryptedFragments.length || encryptedFragments[encryptedFragments.length - 1].levelkeys !== levelkeys) && Object.keys(levelkeys).some(function (format) {
  50560. return levelkeys[format].isCommonEncryption;
  50561. })) {
  50562. encryptedFragments.push(frag);
  50563. }
  50564. }
  50565. /***/ }),
  50566. /***/ "./src/loader/playlist-loader.ts":
  50567. /*!***************************************!*\
  50568. !*** ./src/loader/playlist-loader.ts ***!
  50569. \***************************************/
  50570. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  50571. "use strict";
  50572. __webpack_require__.r(__webpack_exports__);
  50573. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  50574. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  50575. /* harmony export */ });
  50576. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  50577. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  50578. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  50579. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  50580. /* harmony import */ var _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./m3u8-parser */ "./src/loader/m3u8-parser.ts");
  50581. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  50582. /* harmony import */ var _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/attr-list */ "./src/utils/attr-list.ts");
  50583. /**
  50584. * PlaylistLoader - delegate for media manifest/playlist loading tasks. Takes care of parsing media to internal data-models.
  50585. *
  50586. * Once loaded, dispatches events with parsed data-models of manifest/levels/audio/subtitle tracks.
  50587. *
  50588. * Uses loader(s) set in config to do actual internal loading of resource tasks.
  50589. *
  50590. * @module
  50591. *
  50592. */
  50593. function mapContextToLevelType(context) {
  50594. var type = context.type;
  50595. switch (type) {
  50596. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:
  50597. return _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistLevelType.AUDIO;
  50598. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:
  50599. return _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistLevelType.SUBTITLE;
  50600. default:
  50601. return _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistLevelType.MAIN;
  50602. }
  50603. }
  50604. function getResponseUrl(response, context) {
  50605. var url = response.url;
  50606. // responseURL not supported on some browsers (it is used to detect URL redirection)
  50607. // data-uri mode also not supported (but no need to detect redirection)
  50608. if (url === undefined || url.indexOf('data:') === 0) {
  50609. // fallback to initial URL
  50610. url = context.url;
  50611. }
  50612. return url;
  50613. }
  50614. var PlaylistLoader = /*#__PURE__*/function () {
  50615. function PlaylistLoader(hls) {
  50616. this.hls = void 0;
  50617. this.loaders = Object.create(null);
  50618. this.hls = hls;
  50619. this.registerListeners();
  50620. }
  50621. var _proto = PlaylistLoader.prototype;
  50622. _proto.startLoad = function startLoad(startPosition) {};
  50623. _proto.stopLoad = function stopLoad() {
  50624. this.destroyInternalLoaders();
  50625. };
  50626. _proto.registerListeners = function registerListeners() {
  50627. var hls = this.hls;
  50628. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  50629. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  50630. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
  50631. hls.on(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
  50632. };
  50633. _proto.unregisterListeners = function unregisterListeners() {
  50634. var hls = this.hls;
  50635. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADING, this.onManifestLoading, this);
  50636. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADING, this.onLevelLoading, this);
  50637. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_LOADING, this.onAudioTrackLoading, this);
  50638. hls.off(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACK_LOADING, this.onSubtitleTrackLoading, this);
  50639. }
  50640. /**
  50641. * Returns defaults or configured loader-type overloads (pLoader and loader config params)
  50642. */;
  50643. _proto.createInternalLoader = function createInternalLoader(context) {
  50644. var config = this.hls.config;
  50645. var PLoader = config.pLoader;
  50646. var Loader = config.loader;
  50647. var InternalLoader = PLoader || Loader;
  50648. var loader = new InternalLoader(config);
  50649. context.loader = loader;
  50650. this.loaders[context.type] = loader;
  50651. return loader;
  50652. };
  50653. _proto.getInternalLoader = function getInternalLoader(context) {
  50654. return this.loaders[context.type];
  50655. };
  50656. _proto.resetInternalLoader = function resetInternalLoader(contextType) {
  50657. if (this.loaders[contextType]) {
  50658. delete this.loaders[contextType];
  50659. }
  50660. }
  50661. /**
  50662. * Call `destroy` on all internal loader instances mapped (one per context type)
  50663. */;
  50664. _proto.destroyInternalLoaders = function destroyInternalLoaders() {
  50665. for (var contextType in this.loaders) {
  50666. var loader = this.loaders[contextType];
  50667. if (loader) {
  50668. loader.destroy();
  50669. }
  50670. this.resetInternalLoader(contextType);
  50671. }
  50672. };
  50673. _proto.destroy = function destroy() {
  50674. this.unregisterListeners();
  50675. this.destroyInternalLoaders();
  50676. };
  50677. _proto.onManifestLoading = function onManifestLoading(event, data) {
  50678. var url = data.url;
  50679. this.load({
  50680. id: null,
  50681. groupId: null,
  50682. level: 0,
  50683. responseType: 'text',
  50684. type: _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST,
  50685. url: url,
  50686. deliveryDirectives: null
  50687. });
  50688. };
  50689. _proto.onLevelLoading = function onLevelLoading(event, data) {
  50690. var id = data.id,
  50691. level = data.level,
  50692. url = data.url,
  50693. deliveryDirectives = data.deliveryDirectives;
  50694. this.load({
  50695. id: id,
  50696. groupId: null,
  50697. level: level,
  50698. responseType: 'text',
  50699. type: _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL,
  50700. url: url,
  50701. deliveryDirectives: deliveryDirectives
  50702. });
  50703. };
  50704. _proto.onAudioTrackLoading = function onAudioTrackLoading(event, data) {
  50705. var id = data.id,
  50706. groupId = data.groupId,
  50707. url = data.url,
  50708. deliveryDirectives = data.deliveryDirectives;
  50709. this.load({
  50710. id: id,
  50711. groupId: groupId,
  50712. level: null,
  50713. responseType: 'text',
  50714. type: _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK,
  50715. url: url,
  50716. deliveryDirectives: deliveryDirectives
  50717. });
  50718. };
  50719. _proto.onSubtitleTrackLoading = function onSubtitleTrackLoading(event, data) {
  50720. var id = data.id,
  50721. groupId = data.groupId,
  50722. url = data.url,
  50723. deliveryDirectives = data.deliveryDirectives;
  50724. this.load({
  50725. id: id,
  50726. groupId: groupId,
  50727. level: null,
  50728. responseType: 'text',
  50729. type: _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK,
  50730. url: url,
  50731. deliveryDirectives: deliveryDirectives
  50732. });
  50733. };
  50734. _proto.load = function load(context) {
  50735. var _context$deliveryDire;
  50736. var config = this.hls.config;
  50737. // logger.debug(`[playlist-loader]: Loading playlist of type ${context.type}, level: ${context.level}, id: ${context.id}`);
  50738. // Check if a loader for this context already exists
  50739. var loader = this.getInternalLoader(context);
  50740. if (loader) {
  50741. var loaderContext = loader.context;
  50742. if (loaderContext && loaderContext.url === context.url) {
  50743. // same URL can't overlap
  50744. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.trace('[playlist-loader]: playlist request ongoing');
  50745. return;
  50746. }
  50747. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[playlist-loader]: aborting previous loader for type: " + context.type);
  50748. loader.abort();
  50749. }
  50750. var maxRetry;
  50751. var timeout;
  50752. var retryDelay;
  50753. var maxRetryDelay;
  50754. // apply different configs for retries depending on
  50755. // context (manifest, level, audio/subs playlist)
  50756. switch (context.type) {
  50757. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST:
  50758. maxRetry = config.manifestLoadingMaxRetry;
  50759. timeout = config.manifestLoadingTimeOut;
  50760. retryDelay = config.manifestLoadingRetryDelay;
  50761. maxRetryDelay = config.manifestLoadingMaxRetryTimeout;
  50762. break;
  50763. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL:
  50764. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:
  50765. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:
  50766. // Manage retries in Level/Track Controller
  50767. maxRetry = 0;
  50768. timeout = config.levelLoadingTimeOut;
  50769. break;
  50770. default:
  50771. maxRetry = config.levelLoadingMaxRetry;
  50772. timeout = config.levelLoadingTimeOut;
  50773. retryDelay = config.levelLoadingRetryDelay;
  50774. maxRetryDelay = config.levelLoadingMaxRetryTimeout;
  50775. break;
  50776. }
  50777. loader = this.createInternalLoader(context);
  50778. // Override level/track timeout for LL-HLS requests
  50779. // (the default of 10000ms is counter productive to blocking playlist reload requests)
  50780. if ((_context$deliveryDire = context.deliveryDirectives) !== null && _context$deliveryDire !== void 0 && _context$deliveryDire.part) {
  50781. var levelDetails;
  50782. if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL && context.level !== null) {
  50783. levelDetails = this.hls.levels[context.level].details;
  50784. } else if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK && context.id !== null) {
  50785. levelDetails = this.hls.audioTracks[context.id].details;
  50786. } else if (context.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK && context.id !== null) {
  50787. levelDetails = this.hls.subtitleTracks[context.id].details;
  50788. }
  50789. if (levelDetails) {
  50790. var partTarget = levelDetails.partTarget;
  50791. var targetDuration = levelDetails.targetduration;
  50792. if (partTarget && targetDuration) {
  50793. timeout = Math.min(Math.max(partTarget * 3, targetDuration * 0.8) * 1000, timeout);
  50794. }
  50795. }
  50796. }
  50797. var loaderConfig = {
  50798. timeout: timeout,
  50799. maxRetry: maxRetry,
  50800. retryDelay: retryDelay,
  50801. maxRetryDelay: maxRetryDelay,
  50802. highWaterMark: 0
  50803. };
  50804. var loaderCallbacks = {
  50805. onSuccess: this.loadsuccess.bind(this),
  50806. onError: this.loaderror.bind(this),
  50807. onTimeout: this.loadtimeout.bind(this)
  50808. };
  50809. // logger.debug(`[playlist-loader]: Calling internal loader delegate for URL: ${context.url}`);
  50810. loader.load(context, loaderConfig, loaderCallbacks);
  50811. };
  50812. _proto.loadsuccess = function loadsuccess(response, stats, context, networkDetails) {
  50813. if (networkDetails === void 0) {
  50814. networkDetails = null;
  50815. }
  50816. this.resetInternalLoader(context.type);
  50817. var string = response.data;
  50818. // Validate if it is an M3U8 at all
  50819. if (string.indexOf('#EXTM3U') !== 0) {
  50820. this.handleManifestParsingError(response, context, 'no EXTM3U delimiter', networkDetails);
  50821. return;
  50822. }
  50823. stats.parsing.start = performance.now();
  50824. // Check if chunk-list or master. handle empty chunk list case (first EXTINF not signaled, but TARGETDURATION present)
  50825. if (string.indexOf('#EXTINF:') > 0 || string.indexOf('#EXT-X-TARGETDURATION:') > 0) {
  50826. this.handleTrackOrLevelPlaylist(response, stats, context, networkDetails);
  50827. } else {
  50828. this.handleMasterPlaylist(response, stats, context, networkDetails);
  50829. }
  50830. };
  50831. _proto.loaderror = function loaderror(response, context, networkDetails) {
  50832. if (networkDetails === void 0) {
  50833. networkDetails = null;
  50834. }
  50835. this.handleNetworkError(context, networkDetails, false, response);
  50836. };
  50837. _proto.loadtimeout = function loadtimeout(stats, context, networkDetails) {
  50838. if (networkDetails === void 0) {
  50839. networkDetails = null;
  50840. }
  50841. this.handleNetworkError(context, networkDetails, true);
  50842. };
  50843. _proto.handleMasterPlaylist = function handleMasterPlaylist(response, stats, context, networkDetails) {
  50844. var hls = this.hls;
  50845. var string = response.data;
  50846. var url = getResponseUrl(response, context);
  50847. var _M3U8Parser$parseMast = _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylist(string, url),
  50848. levels = _M3U8Parser$parseMast.levels,
  50849. sessionData = _M3U8Parser$parseMast.sessionData,
  50850. sessionKeys = _M3U8Parser$parseMast.sessionKeys;
  50851. if (!levels.length) {
  50852. this.handleManifestParsingError(response, context, 'no level found in manifest', networkDetails);
  50853. return;
  50854. }
  50855. // multi level playlist, parse level info
  50856. var audioGroups = levels.map(function (level) {
  50857. return {
  50858. id: level.attrs.AUDIO,
  50859. audioCodec: level.audioCodec
  50860. };
  50861. });
  50862. var subtitleGroups = levels.map(function (level) {
  50863. return {
  50864. id: level.attrs.SUBTITLES,
  50865. textCodec: level.textCodec
  50866. };
  50867. });
  50868. var audioTracks = _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylistMedia(string, url, 'AUDIO', audioGroups);
  50869. var subtitles = _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylistMedia(string, url, 'SUBTITLES', subtitleGroups);
  50870. var captions = _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseMasterPlaylistMedia(string, url, 'CLOSED-CAPTIONS');
  50871. if (audioTracks.length) {
  50872. // check if we have found an audio track embedded in main playlist (audio track without URI attribute)
  50873. var embeddedAudioFound = audioTracks.some(function (audioTrack) {
  50874. return !audioTrack.url;
  50875. });
  50876. // if no embedded audio track defined, but audio codec signaled in quality level,
  50877. // we need to signal this main audio track this could happen with playlists with
  50878. // alt audio rendition in which quality levels (main)
  50879. // contains both audio+video. but with mixed audio track not signaled
  50880. if (!embeddedAudioFound && levels[0].audioCodec && !levels[0].attrs.AUDIO) {
  50881. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log('[playlist-loader]: audio codec signaled in quality level, but no embedded audio track signaled, create one');
  50882. audioTracks.unshift({
  50883. type: 'main',
  50884. name: 'main',
  50885. default: false,
  50886. autoselect: false,
  50887. forced: false,
  50888. id: -1,
  50889. attrs: new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList({}),
  50890. bitrate: 0,
  50891. url: ''
  50892. });
  50893. }
  50894. }
  50895. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED, {
  50896. levels: levels,
  50897. audioTracks: audioTracks,
  50898. subtitles: subtitles,
  50899. captions: captions,
  50900. url: url,
  50901. stats: stats,
  50902. networkDetails: networkDetails,
  50903. sessionData: sessionData,
  50904. sessionKeys: sessionKeys
  50905. });
  50906. };
  50907. _proto.handleTrackOrLevelPlaylist = function handleTrackOrLevelPlaylist(response, stats, context, networkDetails) {
  50908. var hls = this.hls;
  50909. var id = context.id,
  50910. level = context.level,
  50911. type = context.type;
  50912. var url = getResponseUrl(response, context);
  50913. var levelUrlId = (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(id) ? id : 0;
  50914. var levelId = (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(level) ? level : levelUrlId;
  50915. var levelType = mapContextToLevelType(context);
  50916. var levelDetails = _m3u8_parser__WEBPACK_IMPORTED_MODULE_4__["default"].parseLevelPlaylist(response.data, url, levelId, levelType, levelUrlId);
  50917. if (!levelDetails.fragments.length) {
  50918. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  50919. type: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.NETWORK_ERROR,
  50920. details: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_EMPTY_ERROR,
  50921. fatal: false,
  50922. url: url,
  50923. reason: 'no fragments found in level',
  50924. level: typeof context.level === 'number' ? context.level : undefined
  50925. });
  50926. return;
  50927. }
  50928. // We have done our first request (Manifest-type) and receive
  50929. // not a master playlist but a chunk-list (track/level)
  50930. // We fire the manifest-loaded event anyway with the parsed level-details
  50931. // by creating a single-level structure for it.
  50932. if (type === _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST) {
  50933. var singleLevel = {
  50934. attrs: new _utils_attr_list__WEBPACK_IMPORTED_MODULE_6__.AttrList({}),
  50935. bitrate: 0,
  50936. details: levelDetails,
  50937. name: '',
  50938. url: url
  50939. };
  50940. hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.MANIFEST_LOADED, {
  50941. levels: [singleLevel],
  50942. audioTracks: [],
  50943. url: url,
  50944. stats: stats,
  50945. networkDetails: networkDetails,
  50946. sessionData: null,
  50947. sessionKeys: null
  50948. });
  50949. }
  50950. // save parsing time
  50951. stats.parsing.end = performance.now();
  50952. // extend the context with the new levelDetails property
  50953. context.levelDetails = levelDetails;
  50954. this.handlePlaylistLoaded(response, stats, context, networkDetails);
  50955. };
  50956. _proto.handleManifestParsingError = function handleManifestParsingError(response, context, reason, networkDetails) {
  50957. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, {
  50958. type: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.NETWORK_ERROR,
  50959. details: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_PARSING_ERROR,
  50960. fatal: context.type === _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST,
  50961. url: response.url,
  50962. reason: reason,
  50963. response: response,
  50964. context: context,
  50965. networkDetails: networkDetails
  50966. });
  50967. };
  50968. _proto.handleNetworkError = function handleNetworkError(context, networkDetails, timeout, response) {
  50969. if (timeout === void 0) {
  50970. timeout = false;
  50971. }
  50972. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.warn("[playlist-loader]: A network " + (timeout ? 'timeout' : 'error') + " occurred while loading " + context.type + " level: " + context.level + " id: " + context.id + " group-id: \"" + context.groupId + "\"");
  50973. var details = _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.UNKNOWN;
  50974. var fatal = false;
  50975. var loader = this.getInternalLoader(context);
  50976. switch (context.type) {
  50977. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST:
  50978. details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.MANIFEST_LOAD_ERROR;
  50979. fatal = true;
  50980. break;
  50981. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL:
  50982. details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.LEVEL_LOAD_ERROR;
  50983. fatal = false;
  50984. break;
  50985. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:
  50986. details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.AUDIO_TRACK_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.AUDIO_TRACK_LOAD_ERROR;
  50987. fatal = false;
  50988. break;
  50989. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:
  50990. details = timeout ? _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.SUBTITLE_TRACK_LOAD_TIMEOUT : _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorDetails.SUBTITLE_LOAD_ERROR;
  50991. fatal = false;
  50992. break;
  50993. }
  50994. if (loader) {
  50995. this.resetInternalLoader(context.type);
  50996. }
  50997. var errorData = {
  50998. type: _errors__WEBPACK_IMPORTED_MODULE_2__.ErrorTypes.NETWORK_ERROR,
  50999. details: details,
  51000. fatal: fatal,
  51001. url: context.url,
  51002. loader: loader,
  51003. context: context,
  51004. networkDetails: networkDetails
  51005. };
  51006. if (response) {
  51007. errorData.response = response;
  51008. }
  51009. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.ERROR, errorData);
  51010. };
  51011. _proto.handlePlaylistLoaded = function handlePlaylistLoaded(response, stats, context, networkDetails) {
  51012. var type = context.type,
  51013. level = context.level,
  51014. id = context.id,
  51015. groupId = context.groupId,
  51016. loader = context.loader,
  51017. levelDetails = context.levelDetails,
  51018. deliveryDirectives = context.deliveryDirectives;
  51019. if (!(levelDetails !== null && levelDetails !== void 0 && levelDetails.targetduration)) {
  51020. this.handleManifestParsingError(response, context, 'invalid target duration', networkDetails);
  51021. return;
  51022. }
  51023. if (!loader) {
  51024. return;
  51025. }
  51026. if (levelDetails.live) {
  51027. if (loader.getCacheAge) {
  51028. levelDetails.ageHeader = loader.getCacheAge() || 0;
  51029. }
  51030. if (!loader.getCacheAge || isNaN(levelDetails.ageHeader)) {
  51031. levelDetails.ageHeader = 0;
  51032. }
  51033. }
  51034. switch (type) {
  51035. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.MANIFEST:
  51036. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.LEVEL:
  51037. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.LEVEL_LOADED, {
  51038. details: levelDetails,
  51039. level: level || 0,
  51040. id: id || 0,
  51041. stats: stats,
  51042. networkDetails: networkDetails,
  51043. deliveryDirectives: deliveryDirectives
  51044. });
  51045. break;
  51046. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.AUDIO_TRACK:
  51047. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.AUDIO_TRACK_LOADED, {
  51048. details: levelDetails,
  51049. id: id || 0,
  51050. groupId: groupId || '',
  51051. stats: stats,
  51052. networkDetails: networkDetails,
  51053. deliveryDirectives: deliveryDirectives
  51054. });
  51055. break;
  51056. case _types_loader__WEBPACK_IMPORTED_MODULE_5__.PlaylistContextType.SUBTITLE_TRACK:
  51057. this.hls.trigger(_events__WEBPACK_IMPORTED_MODULE_1__.Events.SUBTITLE_TRACK_LOADED, {
  51058. details: levelDetails,
  51059. id: id || 0,
  51060. groupId: groupId || '',
  51061. stats: stats,
  51062. networkDetails: networkDetails,
  51063. deliveryDirectives: deliveryDirectives
  51064. });
  51065. break;
  51066. }
  51067. };
  51068. return PlaylistLoader;
  51069. }();
  51070. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PlaylistLoader);
  51071. /***/ }),
  51072. /***/ "./src/polyfills/number.ts":
  51073. /*!*********************************!*\
  51074. !*** ./src/polyfills/number.ts ***!
  51075. \*********************************/
  51076. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  51077. "use strict";
  51078. __webpack_require__.r(__webpack_exports__);
  51079. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  51080. /* harmony export */ "MAX_SAFE_INTEGER": () => (/* binding */ MAX_SAFE_INTEGER),
  51081. /* harmony export */ "isFiniteNumber": () => (/* binding */ isFiniteNumber)
  51082. /* harmony export */ });
  51083. var isFiniteNumber = Number.isFinite || function (value) {
  51084. return typeof value === 'number' && isFinite(value);
  51085. };
  51086. var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;
  51087. /***/ }),
  51088. /***/ "./src/remux/aac-helper.ts":
  51089. /*!*********************************!*\
  51090. !*** ./src/remux/aac-helper.ts ***!
  51091. \*********************************/
  51092. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  51093. "use strict";
  51094. __webpack_require__.r(__webpack_exports__);
  51095. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  51096. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  51097. /* harmony export */ });
  51098. /**
  51099. * AAC helper
  51100. */
  51101. var AAC = /*#__PURE__*/function () {
  51102. function AAC() {}
  51103. AAC.getSilentFrame = function getSilentFrame(codec, channelCount) {
  51104. switch (codec) {
  51105. case 'mp4a.40.2':
  51106. if (channelCount === 1) {
  51107. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x23, 0x80]);
  51108. } else if (channelCount === 2) {
  51109. return new Uint8Array([0x21, 0x00, 0x49, 0x90, 0x02, 0x19, 0x00, 0x23, 0x80]);
  51110. } else if (channelCount === 3) {
  51111. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x8e]);
  51112. } else if (channelCount === 4) {
  51113. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x80, 0x2c, 0x80, 0x08, 0x02, 0x38]);
  51114. } else if (channelCount === 5) {
  51115. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x38]);
  51116. } else if (channelCount === 6) {
  51117. return new Uint8Array([0x00, 0xc8, 0x00, 0x80, 0x20, 0x84, 0x01, 0x26, 0x40, 0x08, 0x64, 0x00, 0x82, 0x30, 0x04, 0x99, 0x00, 0x21, 0x90, 0x02, 0x00, 0xb2, 0x00, 0x20, 0x08, 0xe0]);
  51118. }
  51119. break;
  51120. // handle HE-AAC below (mp4a.40.5 / mp4a.40.29)
  51121. default:
  51122. if (channelCount === 1) {
  51123. // ffmpeg -y -f lavfi -i "aevalsrc=0:d=0.05" -c:a libfdk_aac -profile:a aac_he -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
  51124. return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x4e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x1c, 0x6, 0xf1, 0xc1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
  51125. } else if (channelCount === 2) {
  51126. // ffmpeg -y -f lavfi -i "aevalsrc=0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
  51127. return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
  51128. } else if (channelCount === 3) {
  51129. // ffmpeg -y -f lavfi -i "aevalsrc=0|0|0:d=0.05" -c:a libfdk_aac -profile:a aac_he_v2 -b:a 4k output.aac && hexdump -v -e '16/1 "0x%x," "\n"' -v output.aac
  51130. return new Uint8Array([0x1, 0x40, 0x22, 0x80, 0xa3, 0x5e, 0xe6, 0x80, 0xba, 0x8, 0x0, 0x0, 0x0, 0x0, 0x95, 0x0, 0x6, 0xf1, 0xa1, 0xa, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5e]);
  51131. }
  51132. break;
  51133. }
  51134. return undefined;
  51135. };
  51136. return AAC;
  51137. }();
  51138. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AAC);
  51139. /***/ }),
  51140. /***/ "./src/remux/mp4-generator.ts":
  51141. /*!************************************!*\
  51142. !*** ./src/remux/mp4-generator.ts ***!
  51143. \************************************/
  51144. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  51145. "use strict";
  51146. __webpack_require__.r(__webpack_exports__);
  51147. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  51148. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  51149. /* harmony export */ });
  51150. /**
  51151. * Generate MP4 Box
  51152. */
  51153. var UINT32_MAX = Math.pow(2, 32) - 1;
  51154. var MP4 = /*#__PURE__*/function () {
  51155. function MP4() {}
  51156. MP4.init = function init() {
  51157. MP4.types = {
  51158. avc1: [],
  51159. // codingname
  51160. avcC: [],
  51161. btrt: [],
  51162. dinf: [],
  51163. dref: [],
  51164. esds: [],
  51165. ftyp: [],
  51166. hdlr: [],
  51167. mdat: [],
  51168. mdhd: [],
  51169. mdia: [],
  51170. mfhd: [],
  51171. minf: [],
  51172. moof: [],
  51173. moov: [],
  51174. mp4a: [],
  51175. '.mp3': [],
  51176. mvex: [],
  51177. mvhd: [],
  51178. pasp: [],
  51179. sdtp: [],
  51180. stbl: [],
  51181. stco: [],
  51182. stsc: [],
  51183. stsd: [],
  51184. stsz: [],
  51185. stts: [],
  51186. tfdt: [],
  51187. tfhd: [],
  51188. traf: [],
  51189. trak: [],
  51190. trun: [],
  51191. trex: [],
  51192. tkhd: [],
  51193. vmhd: [],
  51194. smhd: []
  51195. };
  51196. var i;
  51197. for (i in MP4.types) {
  51198. if (MP4.types.hasOwnProperty(i)) {
  51199. MP4.types[i] = [i.charCodeAt(0), i.charCodeAt(1), i.charCodeAt(2), i.charCodeAt(3)];
  51200. }
  51201. }
  51202. var videoHdlr = new Uint8Array([0x00,
  51203. // version 0
  51204. 0x00, 0x00, 0x00,
  51205. // flags
  51206. 0x00, 0x00, 0x00, 0x00,
  51207. // pre_defined
  51208. 0x76, 0x69, 0x64, 0x65,
  51209. // handler_type: 'vide'
  51210. 0x00, 0x00, 0x00, 0x00,
  51211. // reserved
  51212. 0x00, 0x00, 0x00, 0x00,
  51213. // reserved
  51214. 0x00, 0x00, 0x00, 0x00,
  51215. // reserved
  51216. 0x56, 0x69, 0x64, 0x65, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'VideoHandler'
  51217. ]);
  51218. var audioHdlr = new Uint8Array([0x00,
  51219. // version 0
  51220. 0x00, 0x00, 0x00,
  51221. // flags
  51222. 0x00, 0x00, 0x00, 0x00,
  51223. // pre_defined
  51224. 0x73, 0x6f, 0x75, 0x6e,
  51225. // handler_type: 'soun'
  51226. 0x00, 0x00, 0x00, 0x00,
  51227. // reserved
  51228. 0x00, 0x00, 0x00, 0x00,
  51229. // reserved
  51230. 0x00, 0x00, 0x00, 0x00,
  51231. // reserved
  51232. 0x53, 0x6f, 0x75, 0x6e, 0x64, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x00 // name: 'SoundHandler'
  51233. ]);
  51234. MP4.HDLR_TYPES = {
  51235. video: videoHdlr,
  51236. audio: audioHdlr
  51237. };
  51238. var dref = new Uint8Array([0x00,
  51239. // version 0
  51240. 0x00, 0x00, 0x00,
  51241. // flags
  51242. 0x00, 0x00, 0x00, 0x01,
  51243. // entry_count
  51244. 0x00, 0x00, 0x00, 0x0c,
  51245. // entry_size
  51246. 0x75, 0x72, 0x6c, 0x20,
  51247. // 'url' type
  51248. 0x00,
  51249. // version 0
  51250. 0x00, 0x00, 0x01 // entry_flags
  51251. ]);
  51252. var stco = new Uint8Array([0x00,
  51253. // version
  51254. 0x00, 0x00, 0x00,
  51255. // flags
  51256. 0x00, 0x00, 0x00, 0x00 // entry_count
  51257. ]);
  51258. MP4.STTS = MP4.STSC = MP4.STCO = stco;
  51259. MP4.STSZ = new Uint8Array([0x00,
  51260. // version
  51261. 0x00, 0x00, 0x00,
  51262. // flags
  51263. 0x00, 0x00, 0x00, 0x00,
  51264. // sample_size
  51265. 0x00, 0x00, 0x00, 0x00 // sample_count
  51266. ]);
  51267. MP4.VMHD = new Uint8Array([0x00,
  51268. // version
  51269. 0x00, 0x00, 0x01,
  51270. // flags
  51271. 0x00, 0x00,
  51272. // graphicsmode
  51273. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // opcolor
  51274. ]);
  51275. MP4.SMHD = new Uint8Array([0x00,
  51276. // version
  51277. 0x00, 0x00, 0x00,
  51278. // flags
  51279. 0x00, 0x00,
  51280. // balance
  51281. 0x00, 0x00 // reserved
  51282. ]);
  51283. MP4.STSD = new Uint8Array([0x00,
  51284. // version 0
  51285. 0x00, 0x00, 0x00,
  51286. // flags
  51287. 0x00, 0x00, 0x00, 0x01]); // entry_count
  51288. var majorBrand = new Uint8Array([105, 115, 111, 109]); // isom
  51289. var avc1Brand = new Uint8Array([97, 118, 99, 49]); // avc1
  51290. var minorVersion = new Uint8Array([0, 0, 0, 1]);
  51291. MP4.FTYP = MP4.box(MP4.types.ftyp, majorBrand, minorVersion, majorBrand, avc1Brand);
  51292. MP4.DINF = MP4.box(MP4.types.dinf, MP4.box(MP4.types.dref, dref));
  51293. };
  51294. MP4.box = function box(type) {
  51295. var size = 8;
  51296. for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  51297. payload[_key - 1] = arguments[_key];
  51298. }
  51299. var i = payload.length;
  51300. var len = i;
  51301. // calculate the total size we need to allocate
  51302. while (i--) {
  51303. size += payload[i].byteLength;
  51304. }
  51305. var result = new Uint8Array(size);
  51306. result[0] = size >> 24 & 0xff;
  51307. result[1] = size >> 16 & 0xff;
  51308. result[2] = size >> 8 & 0xff;
  51309. result[3] = size & 0xff;
  51310. result.set(type, 4);
  51311. // copy the payload into the result
  51312. for (i = 0, size = 8; i < len; i++) {
  51313. // copy payload[i] array @ offset size
  51314. result.set(payload[i], size);
  51315. size += payload[i].byteLength;
  51316. }
  51317. return result;
  51318. };
  51319. MP4.hdlr = function hdlr(type) {
  51320. return MP4.box(MP4.types.hdlr, MP4.HDLR_TYPES[type]);
  51321. };
  51322. MP4.mdat = function mdat(data) {
  51323. return MP4.box(MP4.types.mdat, data);
  51324. };
  51325. MP4.mdhd = function mdhd(timescale, duration) {
  51326. duration *= timescale;
  51327. var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
  51328. var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
  51329. return MP4.box(MP4.types.mdhd, new Uint8Array([0x01,
  51330. // version 1
  51331. 0x00, 0x00, 0x00,
  51332. // flags
  51333. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
  51334. // creation_time
  51335. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
  51336. // modification_time
  51337. timescale >> 24 & 0xff, timescale >> 16 & 0xff, timescale >> 8 & 0xff, timescale & 0xff,
  51338. // timescale
  51339. upperWordDuration >> 24, upperWordDuration >> 16 & 0xff, upperWordDuration >> 8 & 0xff, upperWordDuration & 0xff, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xff, lowerWordDuration >> 8 & 0xff, lowerWordDuration & 0xff, 0x55, 0xc4,
  51340. // 'und' language (undetermined)
  51341. 0x00, 0x00]));
  51342. };
  51343. MP4.mdia = function mdia(track) {
  51344. return MP4.box(MP4.types.mdia, MP4.mdhd(track.timescale, track.duration), MP4.hdlr(track.type), MP4.minf(track));
  51345. };
  51346. MP4.mfhd = function mfhd(sequenceNumber) {
  51347. return MP4.box(MP4.types.mfhd, new Uint8Array([0x00, 0x00, 0x00, 0x00,
  51348. // flags
  51349. sequenceNumber >> 24, sequenceNumber >> 16 & 0xff, sequenceNumber >> 8 & 0xff, sequenceNumber & 0xff // sequence_number
  51350. ]));
  51351. };
  51352. MP4.minf = function minf(track) {
  51353. if (track.type === 'audio') {
  51354. return MP4.box(MP4.types.minf, MP4.box(MP4.types.smhd, MP4.SMHD), MP4.DINF, MP4.stbl(track));
  51355. } else {
  51356. return MP4.box(MP4.types.minf, MP4.box(MP4.types.vmhd, MP4.VMHD), MP4.DINF, MP4.stbl(track));
  51357. }
  51358. };
  51359. MP4.moof = function moof(sn, baseMediaDecodeTime, track) {
  51360. return MP4.box(MP4.types.moof, MP4.mfhd(sn), MP4.traf(track, baseMediaDecodeTime));
  51361. }
  51362. /**
  51363. * @param tracks... (optional) {array} the tracks associated with this movie
  51364. */;
  51365. MP4.moov = function moov(tracks) {
  51366. var i = tracks.length;
  51367. var boxes = [];
  51368. while (i--) {
  51369. boxes[i] = MP4.trak(tracks[i]);
  51370. }
  51371. return MP4.box.apply(null, [MP4.types.moov, MP4.mvhd(tracks[0].timescale, tracks[0].duration)].concat(boxes).concat(MP4.mvex(tracks)));
  51372. };
  51373. MP4.mvex = function mvex(tracks) {
  51374. var i = tracks.length;
  51375. var boxes = [];
  51376. while (i--) {
  51377. boxes[i] = MP4.trex(tracks[i]);
  51378. }
  51379. return MP4.box.apply(null, [MP4.types.mvex].concat(boxes));
  51380. };
  51381. MP4.mvhd = function mvhd(timescale, duration) {
  51382. duration *= timescale;
  51383. var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
  51384. var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
  51385. var bytes = new Uint8Array([0x01,
  51386. // version 1
  51387. 0x00, 0x00, 0x00,
  51388. // flags
  51389. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
  51390. // creation_time
  51391. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
  51392. // modification_time
  51393. timescale >> 24 & 0xff, timescale >> 16 & 0xff, timescale >> 8 & 0xff, timescale & 0xff,
  51394. // timescale
  51395. upperWordDuration >> 24, upperWordDuration >> 16 & 0xff, upperWordDuration >> 8 & 0xff, upperWordDuration & 0xff, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xff, lowerWordDuration >> 8 & 0xff, lowerWordDuration & 0xff, 0x00, 0x01, 0x00, 0x00,
  51396. // 1.0 rate
  51397. 0x01, 0x00,
  51398. // 1.0 volume
  51399. 0x00, 0x00,
  51400. // reserved
  51401. 0x00, 0x00, 0x00, 0x00,
  51402. // reserved
  51403. 0x00, 0x00, 0x00, 0x00,
  51404. // reserved
  51405. 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
  51406. // transformation: unity matrix
  51407. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51408. // pre_defined
  51409. 0xff, 0xff, 0xff, 0xff // next_track_ID
  51410. ]);
  51411. return MP4.box(MP4.types.mvhd, bytes);
  51412. };
  51413. MP4.sdtp = function sdtp(track) {
  51414. var samples = track.samples || [];
  51415. var bytes = new Uint8Array(4 + samples.length);
  51416. var i;
  51417. var flags;
  51418. // leave the full box header (4 bytes) all zero
  51419. // write the sample table
  51420. for (i = 0; i < samples.length; i++) {
  51421. flags = samples[i].flags;
  51422. bytes[i + 4] = flags.dependsOn << 4 | flags.isDependedOn << 2 | flags.hasRedundancy;
  51423. }
  51424. return MP4.box(MP4.types.sdtp, bytes);
  51425. };
  51426. MP4.stbl = function stbl(track) {
  51427. return MP4.box(MP4.types.stbl, MP4.stsd(track), MP4.box(MP4.types.stts, MP4.STTS), MP4.box(MP4.types.stsc, MP4.STSC), MP4.box(MP4.types.stsz, MP4.STSZ), MP4.box(MP4.types.stco, MP4.STCO));
  51428. };
  51429. MP4.avc1 = function avc1(track) {
  51430. var sps = [];
  51431. var pps = [];
  51432. var i;
  51433. var data;
  51434. var len;
  51435. // assemble the SPSs
  51436. for (i = 0; i < track.sps.length; i++) {
  51437. data = track.sps[i];
  51438. len = data.byteLength;
  51439. sps.push(len >>> 8 & 0xff);
  51440. sps.push(len & 0xff);
  51441. // SPS
  51442. sps = sps.concat(Array.prototype.slice.call(data));
  51443. }
  51444. // assemble the PPSs
  51445. for (i = 0; i < track.pps.length; i++) {
  51446. data = track.pps[i];
  51447. len = data.byteLength;
  51448. pps.push(len >>> 8 & 0xff);
  51449. pps.push(len & 0xff);
  51450. pps = pps.concat(Array.prototype.slice.call(data));
  51451. }
  51452. var avcc = MP4.box(MP4.types.avcC, new Uint8Array([0x01,
  51453. // version
  51454. sps[3],
  51455. // profile
  51456. sps[4],
  51457. // profile compat
  51458. sps[5],
  51459. // level
  51460. 0xfc | 3,
  51461. // lengthSizeMinusOne, hard-coded to 4 bytes
  51462. 0xe0 | track.sps.length // 3bit reserved (111) + numOfSequenceParameterSets
  51463. ].concat(sps).concat([track.pps.length // numOfPictureParameterSets
  51464. ]).concat(pps))); // "PPS"
  51465. var width = track.width;
  51466. var height = track.height;
  51467. var hSpacing = track.pixelRatio[0];
  51468. var vSpacing = track.pixelRatio[1];
  51469. return MP4.box(MP4.types.avc1, new Uint8Array([0x00, 0x00, 0x00,
  51470. // reserved
  51471. 0x00, 0x00, 0x00,
  51472. // reserved
  51473. 0x00, 0x01,
  51474. // data_reference_index
  51475. 0x00, 0x00,
  51476. // pre_defined
  51477. 0x00, 0x00,
  51478. // reserved
  51479. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51480. // pre_defined
  51481. width >> 8 & 0xff, width & 0xff,
  51482. // width
  51483. height >> 8 & 0xff, height & 0xff,
  51484. // height
  51485. 0x00, 0x48, 0x00, 0x00,
  51486. // horizresolution
  51487. 0x00, 0x48, 0x00, 0x00,
  51488. // vertresolution
  51489. 0x00, 0x00, 0x00, 0x00,
  51490. // reserved
  51491. 0x00, 0x01,
  51492. // frame_count
  51493. 0x12, 0x64, 0x61, 0x69, 0x6c,
  51494. // dailymotion/hls.js
  51495. 0x79, 0x6d, 0x6f, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x68, 0x6c, 0x73, 0x2e, 0x6a, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51496. // compressorname
  51497. 0x00, 0x18,
  51498. // depth = 24
  51499. 0x11, 0x11]),
  51500. // pre_defined = -1
  51501. avcc, MP4.box(MP4.types.btrt, new Uint8Array([0x00, 0x1c, 0x9c, 0x80,
  51502. // bufferSizeDB
  51503. 0x00, 0x2d, 0xc6, 0xc0,
  51504. // maxBitrate
  51505. 0x00, 0x2d, 0xc6, 0xc0])),
  51506. // avgBitrate
  51507. MP4.box(MP4.types.pasp, new Uint8Array([hSpacing >> 24,
  51508. // hSpacing
  51509. hSpacing >> 16 & 0xff, hSpacing >> 8 & 0xff, hSpacing & 0xff, vSpacing >> 24,
  51510. // vSpacing
  51511. vSpacing >> 16 & 0xff, vSpacing >> 8 & 0xff, vSpacing & 0xff])));
  51512. };
  51513. MP4.esds = function esds(track) {
  51514. var configlen = track.config.length;
  51515. return new Uint8Array([0x00,
  51516. // version 0
  51517. 0x00, 0x00, 0x00,
  51518. // flags
  51519. 0x03,
  51520. // descriptor_type
  51521. 0x17 + configlen,
  51522. // length
  51523. 0x00, 0x01,
  51524. // es_id
  51525. 0x00,
  51526. // stream_priority
  51527. 0x04,
  51528. // descriptor_type
  51529. 0x0f + configlen,
  51530. // length
  51531. 0x40,
  51532. // codec : mpeg4_audio
  51533. 0x15,
  51534. // stream_type
  51535. 0x00, 0x00, 0x00,
  51536. // buffer_size
  51537. 0x00, 0x00, 0x00, 0x00,
  51538. // maxBitrate
  51539. 0x00, 0x00, 0x00, 0x00,
  51540. // avgBitrate
  51541. 0x05 // descriptor_type
  51542. ].concat([configlen]).concat(track.config).concat([0x06, 0x01, 0x02])); // GASpecificConfig)); // length + audio config descriptor
  51543. };
  51544. MP4.mp4a = function mp4a(track) {
  51545. var samplerate = track.samplerate;
  51546. return MP4.box(MP4.types.mp4a, new Uint8Array([0x00, 0x00, 0x00,
  51547. // reserved
  51548. 0x00, 0x00, 0x00,
  51549. // reserved
  51550. 0x00, 0x01,
  51551. // data_reference_index
  51552. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51553. // reserved
  51554. 0x00, track.channelCount,
  51555. // channelcount
  51556. 0x00, 0x10,
  51557. // sampleSize:16bits
  51558. 0x00, 0x00, 0x00, 0x00,
  51559. // reserved2
  51560. samplerate >> 8 & 0xff, samplerate & 0xff,
  51561. //
  51562. 0x00, 0x00]), MP4.box(MP4.types.esds, MP4.esds(track)));
  51563. };
  51564. MP4.mp3 = function mp3(track) {
  51565. var samplerate = track.samplerate;
  51566. return MP4.box(MP4.types['.mp3'], new Uint8Array([0x00, 0x00, 0x00,
  51567. // reserved
  51568. 0x00, 0x00, 0x00,
  51569. // reserved
  51570. 0x00, 0x01,
  51571. // data_reference_index
  51572. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51573. // reserved
  51574. 0x00, track.channelCount,
  51575. // channelcount
  51576. 0x00, 0x10,
  51577. // sampleSize:16bits
  51578. 0x00, 0x00, 0x00, 0x00,
  51579. // reserved2
  51580. samplerate >> 8 & 0xff, samplerate & 0xff,
  51581. //
  51582. 0x00, 0x00]));
  51583. };
  51584. MP4.stsd = function stsd(track) {
  51585. if (track.type === 'audio') {
  51586. if (track.segmentCodec === 'mp3' && track.codec === 'mp3') {
  51587. return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp3(track));
  51588. }
  51589. return MP4.box(MP4.types.stsd, MP4.STSD, MP4.mp4a(track));
  51590. } else {
  51591. return MP4.box(MP4.types.stsd, MP4.STSD, MP4.avc1(track));
  51592. }
  51593. };
  51594. MP4.tkhd = function tkhd(track) {
  51595. var id = track.id;
  51596. var duration = track.duration * track.timescale;
  51597. var width = track.width;
  51598. var height = track.height;
  51599. var upperWordDuration = Math.floor(duration / (UINT32_MAX + 1));
  51600. var lowerWordDuration = Math.floor(duration % (UINT32_MAX + 1));
  51601. return MP4.box(MP4.types.tkhd, new Uint8Array([0x01,
  51602. // version 1
  51603. 0x00, 0x00, 0x07,
  51604. // flags
  51605. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
  51606. // creation_time
  51607. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
  51608. // modification_time
  51609. id >> 24 & 0xff, id >> 16 & 0xff, id >> 8 & 0xff, id & 0xff,
  51610. // track_ID
  51611. 0x00, 0x00, 0x00, 0x00,
  51612. // reserved
  51613. upperWordDuration >> 24, upperWordDuration >> 16 & 0xff, upperWordDuration >> 8 & 0xff, upperWordDuration & 0xff, lowerWordDuration >> 24, lowerWordDuration >> 16 & 0xff, lowerWordDuration >> 8 & 0xff, lowerWordDuration & 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  51614. // reserved
  51615. 0x00, 0x00,
  51616. // layer
  51617. 0x00, 0x00,
  51618. // alternate_group
  51619. 0x00, 0x00,
  51620. // non-audio track volume
  51621. 0x00, 0x00,
  51622. // reserved
  51623. 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
  51624. // transformation: unity matrix
  51625. width >> 8 & 0xff, width & 0xff, 0x00, 0x00,
  51626. // width
  51627. height >> 8 & 0xff, height & 0xff, 0x00, 0x00 // height
  51628. ]));
  51629. };
  51630. MP4.traf = function traf(track, baseMediaDecodeTime) {
  51631. var sampleDependencyTable = MP4.sdtp(track);
  51632. var id = track.id;
  51633. var upperWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1));
  51634. var lowerWordBaseMediaDecodeTime = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));
  51635. return MP4.box(MP4.types.traf, MP4.box(MP4.types.tfhd, new Uint8Array([0x00,
  51636. // version 0
  51637. 0x00, 0x00, 0x00,
  51638. // flags
  51639. id >> 24, id >> 16 & 0xff, id >> 8 & 0xff, id & 0xff // track_ID
  51640. ])), MP4.box(MP4.types.tfdt, new Uint8Array([0x01,
  51641. // version 1
  51642. 0x00, 0x00, 0x00,
  51643. // flags
  51644. upperWordBaseMediaDecodeTime >> 24, upperWordBaseMediaDecodeTime >> 16 & 0xff, upperWordBaseMediaDecodeTime >> 8 & 0xff, upperWordBaseMediaDecodeTime & 0xff, lowerWordBaseMediaDecodeTime >> 24, lowerWordBaseMediaDecodeTime >> 16 & 0xff, lowerWordBaseMediaDecodeTime >> 8 & 0xff, lowerWordBaseMediaDecodeTime & 0xff])), MP4.trun(track, sampleDependencyTable.length + 16 +
  51645. // tfhd
  51646. 20 +
  51647. // tfdt
  51648. 8 +
  51649. // traf header
  51650. 16 +
  51651. // mfhd
  51652. 8 +
  51653. // moof header
  51654. 8),
  51655. // mdat header
  51656. sampleDependencyTable);
  51657. }
  51658. /**
  51659. * Generate a track box.
  51660. * @param track {object} a track definition
  51661. * @return {Uint8Array} the track box
  51662. */;
  51663. MP4.trak = function trak(track) {
  51664. track.duration = track.duration || 0xffffffff;
  51665. return MP4.box(MP4.types.trak, MP4.tkhd(track), MP4.mdia(track));
  51666. };
  51667. MP4.trex = function trex(track) {
  51668. var id = track.id;
  51669. return MP4.box(MP4.types.trex, new Uint8Array([0x00,
  51670. // version 0
  51671. 0x00, 0x00, 0x00,
  51672. // flags
  51673. id >> 24, id >> 16 & 0xff, id >> 8 & 0xff, id & 0xff,
  51674. // track_ID
  51675. 0x00, 0x00, 0x00, 0x01,
  51676. // default_sample_description_index
  51677. 0x00, 0x00, 0x00, 0x00,
  51678. // default_sample_duration
  51679. 0x00, 0x00, 0x00, 0x00,
  51680. // default_sample_size
  51681. 0x00, 0x01, 0x00, 0x01 // default_sample_flags
  51682. ]));
  51683. };
  51684. MP4.trun = function trun(track, offset) {
  51685. var samples = track.samples || [];
  51686. var len = samples.length;
  51687. var arraylen = 12 + 16 * len;
  51688. var array = new Uint8Array(arraylen);
  51689. var i;
  51690. var sample;
  51691. var duration;
  51692. var size;
  51693. var flags;
  51694. var cts;
  51695. offset += 8 + arraylen;
  51696. array.set([track.type === 'video' ? 0x01 : 0x00,
  51697. // version 1 for video with signed-int sample_composition_time_offset
  51698. 0x00, 0x0f, 0x01,
  51699. // flags
  51700. len >>> 24 & 0xff, len >>> 16 & 0xff, len >>> 8 & 0xff, len & 0xff,
  51701. // sample_count
  51702. offset >>> 24 & 0xff, offset >>> 16 & 0xff, offset >>> 8 & 0xff, offset & 0xff // data_offset
  51703. ], 0);
  51704. for (i = 0; i < len; i++) {
  51705. sample = samples[i];
  51706. duration = sample.duration;
  51707. size = sample.size;
  51708. flags = sample.flags;
  51709. cts = sample.cts;
  51710. array.set([duration >>> 24 & 0xff, duration >>> 16 & 0xff, duration >>> 8 & 0xff, duration & 0xff,
  51711. // sample_duration
  51712. size >>> 24 & 0xff, size >>> 16 & 0xff, size >>> 8 & 0xff, size & 0xff,
  51713. // sample_size
  51714. flags.isLeading << 2 | flags.dependsOn, flags.isDependedOn << 6 | flags.hasRedundancy << 4 | flags.paddingValue << 1 | flags.isNonSync, flags.degradPrio & 0xf0 << 8, flags.degradPrio & 0x0f,
  51715. // sample_flags
  51716. cts >>> 24 & 0xff, cts >>> 16 & 0xff, cts >>> 8 & 0xff, cts & 0xff // sample_composition_time_offset
  51717. ], 12 + 16 * i);
  51718. }
  51719. return MP4.box(MP4.types.trun, array);
  51720. };
  51721. MP4.initSegment = function initSegment(tracks) {
  51722. if (!MP4.types) {
  51723. MP4.init();
  51724. }
  51725. var movie = MP4.moov(tracks);
  51726. var result = new Uint8Array(MP4.FTYP.byteLength + movie.byteLength);
  51727. result.set(MP4.FTYP);
  51728. result.set(movie, MP4.FTYP.byteLength);
  51729. return result;
  51730. };
  51731. return MP4;
  51732. }();
  51733. MP4.types = void 0;
  51734. MP4.HDLR_TYPES = void 0;
  51735. MP4.STTS = void 0;
  51736. MP4.STSC = void 0;
  51737. MP4.STCO = void 0;
  51738. MP4.STSZ = void 0;
  51739. MP4.VMHD = void 0;
  51740. MP4.SMHD = void 0;
  51741. MP4.STSD = void 0;
  51742. MP4.FTYP = void 0;
  51743. MP4.DINF = void 0;
  51744. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MP4);
  51745. /***/ }),
  51746. /***/ "./src/remux/mp4-remuxer.ts":
  51747. /*!**********************************!*\
  51748. !*** ./src/remux/mp4-remuxer.ts ***!
  51749. \**********************************/
  51750. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  51751. "use strict";
  51752. __webpack_require__.r(__webpack_exports__);
  51753. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  51754. /* harmony export */ "default": () => (/* binding */ MP4Remuxer),
  51755. /* harmony export */ "flushTextTrackMetadataCueSamples": () => (/* binding */ flushTextTrackMetadataCueSamples),
  51756. /* harmony export */ "flushTextTrackUserdataCueSamples": () => (/* binding */ flushTextTrackUserdataCueSamples),
  51757. /* harmony export */ "normalizePts": () => (/* binding */ normalizePts)
  51758. /* harmony export */ });
  51759. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  51760. /* harmony import */ var _aac_helper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./aac-helper */ "./src/remux/aac-helper.ts");
  51761. /* harmony import */ var _mp4_generator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./mp4-generator */ "./src/remux/mp4-generator.ts");
  51762. /* harmony import */ var _events__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../events */ "./src/events.ts");
  51763. /* harmony import */ var _errors__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../errors */ "./src/errors.ts");
  51764. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  51765. /* harmony import */ var _types_loader__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../types/loader */ "./src/types/loader.ts");
  51766. /* harmony import */ var _utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/timescale-conversion */ "./src/utils/timescale-conversion.ts");
  51767. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  51768. var MAX_SILENT_FRAME_DURATION = 10 * 1000; // 10 seconds
  51769. var AAC_SAMPLES_PER_FRAME = 1024;
  51770. var MPEG_AUDIO_SAMPLE_PER_FRAME = 1152;
  51771. var chromeVersion = null;
  51772. var safariWebkitVersion = null;
  51773. var MP4Remuxer = /*#__PURE__*/function () {
  51774. function MP4Remuxer(observer, config, typeSupported, vendor) {
  51775. if (vendor === void 0) {
  51776. vendor = '';
  51777. }
  51778. this.observer = void 0;
  51779. this.config = void 0;
  51780. this.typeSupported = void 0;
  51781. this.ISGenerated = false;
  51782. this._initPTS = void 0;
  51783. this._initDTS = void 0;
  51784. this.nextAvcDts = null;
  51785. this.nextAudioPts = null;
  51786. this.videoSampleDuration = null;
  51787. this.isAudioContiguous = false;
  51788. this.isVideoContiguous = false;
  51789. this.observer = observer;
  51790. this.config = config;
  51791. this.typeSupported = typeSupported;
  51792. this.ISGenerated = false;
  51793. if (chromeVersion === null) {
  51794. var userAgent = navigator.userAgent || '';
  51795. var result = userAgent.match(/Chrome\/(\d+)/i);
  51796. chromeVersion = result ? parseInt(result[1]) : 0;
  51797. }
  51798. if (safariWebkitVersion === null) {
  51799. var _result = navigator.userAgent.match(/Safari\/(\d+)/i);
  51800. safariWebkitVersion = _result ? parseInt(_result[1]) : 0;
  51801. }
  51802. }
  51803. var _proto = MP4Remuxer.prototype;
  51804. _proto.destroy = function destroy() {};
  51805. _proto.resetTimeStamp = function resetTimeStamp(defaultTimeStamp) {
  51806. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: initPTS & initDTS reset');
  51807. this._initPTS = this._initDTS = defaultTimeStamp;
  51808. };
  51809. _proto.resetNextTimestamp = function resetNextTimestamp() {
  51810. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: reset next timestamp');
  51811. this.isVideoContiguous = false;
  51812. this.isAudioContiguous = false;
  51813. };
  51814. _proto.resetInitSegment = function resetInitSegment() {
  51815. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: ISGenerated flag reset');
  51816. this.ISGenerated = false;
  51817. };
  51818. _proto.getVideoStartPts = function getVideoStartPts(videoSamples) {
  51819. var rolloverDetected = false;
  51820. var startPTS = videoSamples.reduce(function (minPTS, sample) {
  51821. var delta = sample.pts - minPTS;
  51822. if (delta < -4294967296) {
  51823. // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation
  51824. rolloverDetected = true;
  51825. return normalizePts(minPTS, sample.pts);
  51826. } else if (delta > 0) {
  51827. return minPTS;
  51828. } else {
  51829. return sample.pts;
  51830. }
  51831. }, videoSamples[0].pts);
  51832. if (rolloverDetected) {
  51833. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.debug('PTS rollover detected');
  51834. }
  51835. return startPTS;
  51836. };
  51837. _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset, accurateTimeOffset, flush, playlistType) {
  51838. var video;
  51839. var audio;
  51840. var initSegment;
  51841. var text;
  51842. var id3;
  51843. var independent;
  51844. var audioTimeOffset = timeOffset;
  51845. var videoTimeOffset = timeOffset;
  51846. // If we're remuxing audio and video progressively, wait until we've received enough samples for each track before proceeding.
  51847. // This is done to synchronize the audio and video streams. We know if the current segment will have samples if the "pid"
  51848. // parameter is greater than -1. The pid is set when the PMT is parsed, which contains the tracks list.
  51849. // However, if the initSegment has already been generated, or we've reached the end of a segment (flush),
  51850. // then we can remux one track without waiting for the other.
  51851. var hasAudio = audioTrack.pid > -1;
  51852. var hasVideo = videoTrack.pid > -1;
  51853. var length = videoTrack.samples.length;
  51854. var enoughAudioSamples = audioTrack.samples.length > 0;
  51855. var enoughVideoSamples = flush && length > 0 || length > 1;
  51856. var canRemuxAvc = (!hasAudio || enoughAudioSamples) && (!hasVideo || enoughVideoSamples) || this.ISGenerated || flush;
  51857. if (canRemuxAvc) {
  51858. if (!this.ISGenerated) {
  51859. initSegment = this.generateIS(audioTrack, videoTrack, timeOffset);
  51860. }
  51861. var isVideoContiguous = this.isVideoContiguous;
  51862. var firstKeyFrameIndex = -1;
  51863. var firstKeyFramePTS;
  51864. if (enoughVideoSamples) {
  51865. firstKeyFrameIndex = findKeyframeIndex(videoTrack.samples);
  51866. if (!isVideoContiguous && this.config.forceKeyFrameOnDiscontinuity) {
  51867. independent = true;
  51868. if (firstKeyFrameIndex > 0) {
  51869. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("[mp4-remuxer]: Dropped " + firstKeyFrameIndex + " out of " + length + " video samples due to a missing keyframe");
  51870. var startPTS = this.getVideoStartPts(videoTrack.samples);
  51871. videoTrack.samples = videoTrack.samples.slice(firstKeyFrameIndex);
  51872. videoTrack.dropped += firstKeyFrameIndex;
  51873. videoTimeOffset += (videoTrack.samples[0].pts - startPTS) / videoTrack.inputTimeScale;
  51874. firstKeyFramePTS = videoTimeOffset;
  51875. } else if (firstKeyFrameIndex === -1) {
  51876. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("[mp4-remuxer]: No keyframe found out of " + length + " video samples");
  51877. independent = false;
  51878. }
  51879. }
  51880. }
  51881. if (this.ISGenerated) {
  51882. if (enoughAudioSamples && enoughVideoSamples) {
  51883. // timeOffset is expected to be the offset of the first timestamp of this fragment (first DTS)
  51884. // if first audio DTS is not aligned with first video DTS then we need to take that into account
  51885. // when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small
  51886. // drift between audio and video streams
  51887. var _startPTS = this.getVideoStartPts(videoTrack.samples);
  51888. var tsDelta = normalizePts(audioTrack.samples[0].pts, _startPTS) - _startPTS;
  51889. var audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale;
  51890. audioTimeOffset += Math.max(0, audiovideoTimestampDelta);
  51891. videoTimeOffset += Math.max(0, -audiovideoTimestampDelta);
  51892. }
  51893. // Purposefully remuxing audio before video, so that remuxVideo can use nextAudioPts, which is calculated in remuxAudio.
  51894. if (enoughAudioSamples) {
  51895. // if initSegment was generated without audio samples, regenerate it again
  51896. if (!audioTrack.samplerate) {
  51897. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('[mp4-remuxer]: regenerate InitSegment as audio detected');
  51898. initSegment = this.generateIS(audioTrack, videoTrack, timeOffset);
  51899. }
  51900. audio = this.remuxAudio(audioTrack, audioTimeOffset, this.isAudioContiguous, accurateTimeOffset, hasVideo || enoughVideoSamples || playlistType === _types_loader__WEBPACK_IMPORTED_MODULE_6__.PlaylistLevelType.AUDIO ? videoTimeOffset : undefined);
  51901. if (enoughVideoSamples) {
  51902. var audioTrackLength = audio ? audio.endPTS - audio.startPTS : 0;
  51903. // if initSegment was generated without video samples, regenerate it again
  51904. if (!videoTrack.inputTimeScale) {
  51905. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('[mp4-remuxer]: regenerate InitSegment as video detected');
  51906. initSegment = this.generateIS(audioTrack, videoTrack, timeOffset);
  51907. }
  51908. video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, audioTrackLength);
  51909. }
  51910. } else if (enoughVideoSamples) {
  51911. video = this.remuxVideo(videoTrack, videoTimeOffset, isVideoContiguous, 0);
  51912. }
  51913. if (video) {
  51914. video.firstKeyFrame = firstKeyFrameIndex;
  51915. video.independent = firstKeyFrameIndex !== -1;
  51916. video.firstKeyFramePTS = firstKeyFramePTS;
  51917. }
  51918. }
  51919. }
  51920. // Allow ID3 and text to remux, even if more audio/video samples are required
  51921. if (this.ISGenerated) {
  51922. if (id3Track.samples.length) {
  51923. id3 = flushTextTrackMetadataCueSamples(id3Track, timeOffset, this._initPTS, this._initDTS);
  51924. }
  51925. if (textTrack.samples.length) {
  51926. text = flushTextTrackUserdataCueSamples(textTrack, timeOffset, this._initPTS);
  51927. }
  51928. }
  51929. return {
  51930. audio: audio,
  51931. video: video,
  51932. initSegment: initSegment,
  51933. independent: independent,
  51934. text: text,
  51935. id3: id3
  51936. };
  51937. };
  51938. _proto.generateIS = function generateIS(audioTrack, videoTrack, timeOffset) {
  51939. var audioSamples = audioTrack.samples;
  51940. var videoSamples = videoTrack.samples;
  51941. var typeSupported = this.typeSupported;
  51942. var tracks = {};
  51943. var computePTSDTS = !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(this._initPTS);
  51944. var container = 'audio/mp4';
  51945. var initPTS;
  51946. var initDTS;
  51947. var timescale;
  51948. if (computePTSDTS) {
  51949. initPTS = initDTS = Infinity;
  51950. }
  51951. if (audioTrack.config && audioSamples.length) {
  51952. // let's use audio sampling rate as MP4 time scale.
  51953. // rationale is that there is a integer nb of audio frames per audio sample (1024 for AAC)
  51954. // using audio sampling rate here helps having an integer MP4 frame duration
  51955. // this avoids potential rounding issue and AV sync issue
  51956. audioTrack.timescale = audioTrack.samplerate;
  51957. switch (audioTrack.segmentCodec) {
  51958. case 'mp3':
  51959. if (typeSupported.mpeg) {
  51960. // Chrome and Safari
  51961. container = 'audio/mpeg';
  51962. audioTrack.codec = '';
  51963. } else if (typeSupported.mp3) {
  51964. // Firefox
  51965. audioTrack.codec = 'mp3';
  51966. }
  51967. break;
  51968. }
  51969. tracks.audio = {
  51970. id: 'audio',
  51971. container: container,
  51972. codec: audioTrack.codec,
  51973. initSegment: audioTrack.segmentCodec === 'mp3' && typeSupported.mpeg ? new Uint8Array(0) : _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([audioTrack]),
  51974. metadata: {
  51975. channelCount: audioTrack.channelCount
  51976. }
  51977. };
  51978. if (computePTSDTS) {
  51979. timescale = audioTrack.inputTimeScale;
  51980. // remember first PTS of this demuxing context. for audio, PTS = DTS
  51981. initPTS = initDTS = audioSamples[0].pts - Math.round(timescale * timeOffset);
  51982. }
  51983. }
  51984. if (videoTrack.sps && videoTrack.pps && videoSamples.length) {
  51985. // let's use input time scale as MP4 video timescale
  51986. // we use input time scale straight away to avoid rounding issues on frame duration / cts computation
  51987. videoTrack.timescale = videoTrack.inputTimeScale;
  51988. tracks.video = {
  51989. id: 'main',
  51990. container: 'video/mp4',
  51991. codec: videoTrack.codec,
  51992. initSegment: _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].initSegment([videoTrack]),
  51993. metadata: {
  51994. width: videoTrack.width,
  51995. height: videoTrack.height
  51996. }
  51997. };
  51998. if (computePTSDTS) {
  51999. timescale = videoTrack.inputTimeScale;
  52000. var startPTS = this.getVideoStartPts(videoSamples);
  52001. var startOffset = Math.round(timescale * timeOffset);
  52002. initDTS = Math.min(initDTS, normalizePts(videoSamples[0].dts, startPTS) - startOffset);
  52003. initPTS = Math.min(initPTS, startPTS - startOffset);
  52004. }
  52005. }
  52006. if (Object.keys(tracks).length) {
  52007. this.ISGenerated = true;
  52008. if (computePTSDTS) {
  52009. this._initPTS = initPTS;
  52010. this._initDTS = initDTS;
  52011. }
  52012. return {
  52013. tracks: tracks,
  52014. initPTS: initPTS,
  52015. timescale: timescale
  52016. };
  52017. }
  52018. };
  52019. _proto.remuxVideo = function remuxVideo(track, timeOffset, contiguous, audioTrackLength) {
  52020. var timeScale = track.inputTimeScale;
  52021. var inputSamples = track.samples;
  52022. var outputSamples = [];
  52023. var nbSamples = inputSamples.length;
  52024. var initPTS = this._initPTS;
  52025. var nextAvcDts = this.nextAvcDts;
  52026. var offset = 8;
  52027. var mp4SampleDuration = this.videoSampleDuration;
  52028. var firstDTS;
  52029. var lastDTS;
  52030. var minPTS = Number.POSITIVE_INFINITY;
  52031. var maxPTS = Number.NEGATIVE_INFINITY;
  52032. var sortSamples = false;
  52033. // if parsed fragment is contiguous with last one, let's use last DTS value as reference
  52034. if (!contiguous || nextAvcDts === null) {
  52035. var pts = timeOffset * timeScale;
  52036. var cts = inputSamples[0].pts - normalizePts(inputSamples[0].dts, inputSamples[0].pts);
  52037. // if not contiguous, let's use target timeOffset
  52038. nextAvcDts = pts - cts;
  52039. }
  52040. // PTS is coded on 33bits, and can loop from -2^32 to 2^32
  52041. // PTSNormalize will make PTS/DTS value monotonic, we use last known DTS value as reference value
  52042. for (var i = 0; i < nbSamples; i++) {
  52043. var sample = inputSamples[i];
  52044. sample.pts = normalizePts(sample.pts - initPTS, nextAvcDts);
  52045. sample.dts = normalizePts(sample.dts - initPTS, nextAvcDts);
  52046. if (sample.dts < inputSamples[i > 0 ? i - 1 : i].dts) {
  52047. sortSamples = true;
  52048. }
  52049. }
  52050. // sort video samples by DTS then PTS then demux id order
  52051. if (sortSamples) {
  52052. inputSamples.sort(function (a, b) {
  52053. var deltadts = a.dts - b.dts;
  52054. var deltapts = a.pts - b.pts;
  52055. return deltadts || deltapts;
  52056. });
  52057. }
  52058. // Get first/last DTS
  52059. firstDTS = inputSamples[0].dts;
  52060. lastDTS = inputSamples[inputSamples.length - 1].dts;
  52061. // Sample duration (as expected by trun MP4 boxes), should be the delta between sample DTS
  52062. // set this constant duration as being the avg delta between consecutive DTS.
  52063. var inputDuration = lastDTS - firstDTS;
  52064. var averageSampleDuration = inputDuration ? Math.round(inputDuration / (nbSamples - 1)) : mp4SampleDuration || track.inputTimeScale / 30;
  52065. // if fragment are contiguous, detect hole/overlapping between fragments
  52066. if (contiguous) {
  52067. // check timestamp continuity across consecutive fragments (this is to remove inter-fragment gap/hole)
  52068. var delta = firstDTS - nextAvcDts;
  52069. var foundHole = delta > averageSampleDuration;
  52070. var foundOverlap = delta < -1;
  52071. if (foundHole || foundOverlap) {
  52072. if (foundHole) {
  52073. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("AVC: " + (0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(delta, true) + " ms (" + delta + "dts) hole between fragments detected, filling it");
  52074. } else {
  52075. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("AVC: " + (0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(-delta, true) + " ms (" + delta + "dts) overlapping between fragments detected");
  52076. }
  52077. if (!foundOverlap || nextAvcDts > inputSamples[0].pts) {
  52078. firstDTS = nextAvcDts;
  52079. var firstPTS = inputSamples[0].pts - delta;
  52080. inputSamples[0].dts = firstDTS;
  52081. inputSamples[0].pts = firstPTS;
  52082. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log("Video: First PTS/DTS adjusted: " + (0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(firstPTS, true) + "/" + (0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(firstDTS, true) + ", delta: " + (0,_utils_timescale_conversion__WEBPACK_IMPORTED_MODULE_7__.toMsFromMpegTsClock)(delta, true) + " ms");
  52083. }
  52084. }
  52085. }
  52086. firstDTS = Math.max(0, firstDTS);
  52087. var nbNalu = 0;
  52088. var naluLen = 0;
  52089. for (var _i = 0; _i < nbSamples; _i++) {
  52090. // compute total/avc sample length and nb of NAL units
  52091. var _sample = inputSamples[_i];
  52092. var units = _sample.units;
  52093. var nbUnits = units.length;
  52094. var sampleLen = 0;
  52095. for (var j = 0; j < nbUnits; j++) {
  52096. sampleLen += units[j].data.length;
  52097. }
  52098. naluLen += sampleLen;
  52099. nbNalu += nbUnits;
  52100. _sample.length = sampleLen;
  52101. // ensure sample monotonic DTS
  52102. _sample.dts = Math.max(_sample.dts, firstDTS);
  52103. minPTS = Math.min(_sample.pts, minPTS);
  52104. maxPTS = Math.max(_sample.pts, maxPTS);
  52105. }
  52106. lastDTS = inputSamples[nbSamples - 1].dts;
  52107. /* concatenate the video data and construct the mdat in place
  52108. (need 8 more bytes to fill length and mpdat type) */
  52109. var mdatSize = naluLen + 4 * nbNalu + 8;
  52110. var mdat;
  52111. try {
  52112. mdat = new Uint8Array(mdatSize);
  52113. } catch (err) {
  52114. this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR, _events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR, {
  52115. type: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MUX_ERROR,
  52116. details: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.REMUX_ALLOC_ERROR,
  52117. fatal: false,
  52118. bytes: mdatSize,
  52119. reason: "fail allocating video mdat " + mdatSize
  52120. });
  52121. return;
  52122. }
  52123. var view = new DataView(mdat.buffer);
  52124. view.setUint32(0, mdatSize);
  52125. mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat, 4);
  52126. var stretchedLastFrame = false;
  52127. var minDtsDelta = Number.POSITIVE_INFINITY;
  52128. var minPtsDelta = Number.POSITIVE_INFINITY;
  52129. var maxDtsDelta = Number.NEGATIVE_INFINITY;
  52130. var maxPtsDelta = Number.NEGATIVE_INFINITY;
  52131. for (var _i2 = 0; _i2 < nbSamples; _i2++) {
  52132. var avcSample = inputSamples[_i2];
  52133. var avcSampleUnits = avcSample.units;
  52134. var mp4SampleLength = 0;
  52135. // convert NALU bitstream to MP4 format (prepend NALU with size field)
  52136. for (var _j = 0, _nbUnits = avcSampleUnits.length; _j < _nbUnits; _j++) {
  52137. var unit = avcSampleUnits[_j];
  52138. var unitData = unit.data;
  52139. var unitDataLen = unit.data.byteLength;
  52140. view.setUint32(offset, unitDataLen);
  52141. offset += 4;
  52142. mdat.set(unitData, offset);
  52143. offset += unitDataLen;
  52144. mp4SampleLength += 4 + unitDataLen;
  52145. }
  52146. // expected sample duration is the Decoding Timestamp diff of consecutive samples
  52147. var ptsDelta = void 0;
  52148. if (_i2 < nbSamples - 1) {
  52149. mp4SampleDuration = inputSamples[_i2 + 1].dts - avcSample.dts;
  52150. ptsDelta = inputSamples[_i2 + 1].pts - avcSample.pts;
  52151. } else {
  52152. var config = this.config;
  52153. var lastFrameDuration = _i2 > 0 ? avcSample.dts - inputSamples[_i2 - 1].dts : averageSampleDuration;
  52154. ptsDelta = _i2 > 0 ? avcSample.pts - inputSamples[_i2 - 1].pts : averageSampleDuration;
  52155. if (config.stretchShortVideoTrack && this.nextAudioPts !== null) {
  52156. // In some cases, a segment's audio track duration may exceed the video track duration.
  52157. // Since we've already remuxed audio, and we know how long the audio track is, we look to
  52158. // see if the delta to the next segment is longer than maxBufferHole.
  52159. // If so, playback would potentially get stuck, so we artificially inflate
  52160. // the duration of the last frame to minimize any potential gap between segments.
  52161. var gapTolerance = Math.floor(config.maxBufferHole * timeScale);
  52162. var deltaToFrameEnd = (audioTrackLength ? minPTS + audioTrackLength * timeScale : this.nextAudioPts) - avcSample.pts;
  52163. if (deltaToFrameEnd > gapTolerance) {
  52164. // We subtract lastFrameDuration from deltaToFrameEnd to try to prevent any video
  52165. // frame overlap. maxBufferHole should be >> lastFrameDuration anyway.
  52166. mp4SampleDuration = deltaToFrameEnd - lastFrameDuration;
  52167. if (mp4SampleDuration < 0) {
  52168. mp4SampleDuration = lastFrameDuration;
  52169. } else {
  52170. stretchedLastFrame = true;
  52171. }
  52172. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log("[mp4-remuxer]: It is approximately " + deltaToFrameEnd / 90 + " ms to the next segment; using duration " + mp4SampleDuration / 90 + " ms for the last video frame.");
  52173. } else {
  52174. mp4SampleDuration = lastFrameDuration;
  52175. }
  52176. } else {
  52177. mp4SampleDuration = lastFrameDuration;
  52178. }
  52179. }
  52180. var compositionTimeOffset = Math.round(avcSample.pts - avcSample.dts);
  52181. minDtsDelta = Math.min(minDtsDelta, mp4SampleDuration);
  52182. maxDtsDelta = Math.max(maxDtsDelta, mp4SampleDuration);
  52183. minPtsDelta = Math.min(minPtsDelta, ptsDelta);
  52184. maxPtsDelta = Math.max(maxPtsDelta, ptsDelta);
  52185. outputSamples.push(new Mp4Sample(avcSample.key, mp4SampleDuration, mp4SampleLength, compositionTimeOffset));
  52186. }
  52187. if (outputSamples.length) {
  52188. if (chromeVersion) {
  52189. if (chromeVersion < 70) {
  52190. // Chrome workaround, mark first sample as being a Random Access Point (keyframe) to avoid sourcebuffer append issue
  52191. // https://code.google.com/p/chromium/issues/detail?id=229412
  52192. var flags = outputSamples[0].flags;
  52193. flags.dependsOn = 2;
  52194. flags.isNonSync = 0;
  52195. }
  52196. } else if (safariWebkitVersion) {
  52197. // Fix for "CNN special report, with CC" in test-streams (Safari browser only)
  52198. // Ignore DTS when frame durations are irregular. Safari MSE does not handle this leading to gaps.
  52199. if (maxPtsDelta - minPtsDelta < maxDtsDelta - minDtsDelta && averageSampleDuration / maxDtsDelta < 0.025 && outputSamples[0].cts === 0) {
  52200. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('Found irregular gaps in sample duration. Using PTS instead of DTS to determine MP4 sample duration.');
  52201. var dts = firstDTS;
  52202. for (var _i3 = 0, len = outputSamples.length; _i3 < len; _i3++) {
  52203. var nextDts = dts + outputSamples[_i3].duration;
  52204. var _pts = dts + outputSamples[_i3].cts;
  52205. if (_i3 < len - 1) {
  52206. var nextPts = nextDts + outputSamples[_i3 + 1].cts;
  52207. outputSamples[_i3].duration = nextPts - _pts;
  52208. } else {
  52209. outputSamples[_i3].duration = _i3 ? outputSamples[_i3 - 1].duration : averageSampleDuration;
  52210. }
  52211. outputSamples[_i3].cts = 0;
  52212. dts = nextDts;
  52213. }
  52214. }
  52215. }
  52216. }
  52217. console.assert(mp4SampleDuration !== null, 'mp4SampleDuration must be computed');
  52218. // next AVC sample DTS should be equal to last sample DTS + last sample duration (in PES timescale)
  52219. mp4SampleDuration = stretchedLastFrame || !mp4SampleDuration ? averageSampleDuration : mp4SampleDuration;
  52220. this.nextAvcDts = nextAvcDts = lastDTS + mp4SampleDuration;
  52221. this.videoSampleDuration = mp4SampleDuration;
  52222. this.isVideoContiguous = true;
  52223. var moof = _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof(track.sequenceNumber++, firstDTS, _extends({}, track, {
  52224. samples: outputSamples
  52225. }));
  52226. var type = 'video';
  52227. var data = {
  52228. data1: moof,
  52229. data2: mdat,
  52230. startPTS: minPTS / timeScale,
  52231. endPTS: (maxPTS + mp4SampleDuration) / timeScale,
  52232. startDTS: firstDTS / timeScale,
  52233. endDTS: nextAvcDts / timeScale,
  52234. type: type,
  52235. hasAudio: false,
  52236. hasVideo: true,
  52237. nb: outputSamples.length,
  52238. dropped: track.dropped
  52239. };
  52240. track.samples = [];
  52241. track.dropped = 0;
  52242. console.assert(mdat.length, 'MDAT length must not be zero');
  52243. return data;
  52244. };
  52245. _proto.remuxAudio = function remuxAudio(track, timeOffset, contiguous, accurateTimeOffset, videoTimeOffset) {
  52246. var inputTimeScale = track.inputTimeScale;
  52247. var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale;
  52248. var scaleFactor = inputTimeScale / mp4timeScale;
  52249. var mp4SampleDuration = track.segmentCodec === 'aac' ? AAC_SAMPLES_PER_FRAME : MPEG_AUDIO_SAMPLE_PER_FRAME;
  52250. var inputSampleDuration = mp4SampleDuration * scaleFactor;
  52251. var initPTS = this._initPTS;
  52252. var rawMPEG = track.segmentCodec === 'mp3' && this.typeSupported.mpeg;
  52253. var outputSamples = [];
  52254. var alignedWithVideo = videoTimeOffset !== undefined;
  52255. var inputSamples = track.samples;
  52256. var offset = rawMPEG ? 0 : 8;
  52257. var nextAudioPts = this.nextAudioPts || -1;
  52258. // window.audioSamples ? window.audioSamples.push(inputSamples.map(s => s.pts)) : (window.audioSamples = [inputSamples.map(s => s.pts)]);
  52259. // for audio samples, also consider consecutive fragments as being contiguous (even if a level switch occurs),
  52260. // for sake of clarity:
  52261. // consecutive fragments are frags with
  52262. // - less than 100ms gaps between new time offset (if accurate) and next expected PTS OR
  52263. // - less than 20 audio frames distance
  52264. // contiguous fragments are consecutive fragments from same quality level (same level, new SN = old SN + 1)
  52265. // this helps ensuring audio continuity
  52266. // and this also avoids audio glitches/cut when switching quality, or reporting wrong duration on first audio frame
  52267. var timeOffsetMpegTS = timeOffset * inputTimeScale;
  52268. this.isAudioContiguous = contiguous = contiguous || inputSamples.length && nextAudioPts > 0 && (accurateTimeOffset && Math.abs(timeOffsetMpegTS - nextAudioPts) < 9000 || Math.abs(normalizePts(inputSamples[0].pts - initPTS, timeOffsetMpegTS) - nextAudioPts) < 20 * inputSampleDuration);
  52269. // compute normalized PTS
  52270. inputSamples.forEach(function (sample) {
  52271. sample.pts = normalizePts(sample.pts - initPTS, timeOffsetMpegTS);
  52272. });
  52273. if (!contiguous || nextAudioPts < 0) {
  52274. // filter out sample with negative PTS that are not playable anyway
  52275. // if we don't remove these negative samples, they will shift all audio samples forward.
  52276. // leading to audio overlap between current / next fragment
  52277. inputSamples = inputSamples.filter(function (sample) {
  52278. return sample.pts >= 0;
  52279. });
  52280. // in case all samples have negative PTS, and have been filtered out, return now
  52281. if (!inputSamples.length) {
  52282. return;
  52283. }
  52284. if (videoTimeOffset === 0) {
  52285. // Set the start to 0 to match video so that start gaps larger than inputSampleDuration are filled with silence
  52286. nextAudioPts = 0;
  52287. } else if (accurateTimeOffset && !alignedWithVideo) {
  52288. // When not seeking, not live, and LevelDetails.PTSKnown, use fragment start as predicted next audio PTS
  52289. nextAudioPts = Math.max(0, timeOffsetMpegTS);
  52290. } else {
  52291. // if frags are not contiguous and if we cant trust time offset, let's use first sample PTS as next audio PTS
  52292. nextAudioPts = inputSamples[0].pts;
  52293. }
  52294. }
  52295. // If the audio track is missing samples, the frames seem to get "left-shifted" within the
  52296. // resulting mp4 segment, causing sync issues and leaving gaps at the end of the audio segment.
  52297. // In an effort to prevent this from happening, we inject frames here where there are gaps.
  52298. // When possible, we inject a silent frame; when that's not possible, we duplicate the last
  52299. // frame.
  52300. if (track.segmentCodec === 'aac') {
  52301. var maxAudioFramesDrift = this.config.maxAudioFramesDrift;
  52302. for (var i = 0, nextPts = nextAudioPts; i < inputSamples.length; i++) {
  52303. // First, let's see how far off this frame is from where we expect it to be
  52304. var sample = inputSamples[i];
  52305. var pts = sample.pts;
  52306. var delta = pts - nextPts;
  52307. var duration = Math.abs(1000 * delta / inputTimeScale);
  52308. // When remuxing with video, if we're overlapping by more than a duration, drop this sample to stay in sync
  52309. if (delta <= -maxAudioFramesDrift * inputSampleDuration && alignedWithVideo) {
  52310. if (i === 0) {
  52311. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("Audio frame @ " + (pts / inputTimeScale).toFixed(3) + "s overlaps nextAudioPts by " + Math.round(1000 * delta / inputTimeScale) + " ms.");
  52312. this.nextAudioPts = nextAudioPts = nextPts = pts;
  52313. }
  52314. } // eslint-disable-line brace-style
  52315. // Insert missing frames if:
  52316. // 1: We're more than maxAudioFramesDrift frame away
  52317. // 2: Not more than MAX_SILENT_FRAME_DURATION away
  52318. // 3: currentTime (aka nextPtsNorm) is not 0
  52319. // 4: remuxing with video (videoTimeOffset !== undefined)
  52320. else if (delta >= maxAudioFramesDrift * inputSampleDuration && duration < MAX_SILENT_FRAME_DURATION && alignedWithVideo) {
  52321. var missing = Math.round(delta / inputSampleDuration);
  52322. // Adjust nextPts so that silent samples are aligned with media pts. This will prevent media samples from
  52323. // later being shifted if nextPts is based on timeOffset and delta is not a multiple of inputSampleDuration.
  52324. nextPts = pts - missing * inputSampleDuration;
  52325. if (nextPts < 0) {
  52326. missing--;
  52327. nextPts += inputSampleDuration;
  52328. }
  52329. if (i === 0) {
  52330. this.nextAudioPts = nextAudioPts = nextPts;
  52331. }
  52332. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn("[mp4-remuxer]: Injecting " + missing + " audio frame @ " + (nextPts / inputTimeScale).toFixed(3) + "s due to " + Math.round(1000 * delta / inputTimeScale) + " ms gap.");
  52333. for (var j = 0; j < missing; j++) {
  52334. var newStamp = Math.max(nextPts, 0);
  52335. var fillFrame = _aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
  52336. if (!fillFrame) {
  52337. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.log('[mp4-remuxer]: Unable to get silent frame for given audio codec; duplicating last frame instead.');
  52338. fillFrame = sample.unit.subarray();
  52339. }
  52340. inputSamples.splice(i, 0, {
  52341. unit: fillFrame,
  52342. pts: newStamp
  52343. });
  52344. nextPts += inputSampleDuration;
  52345. i++;
  52346. }
  52347. }
  52348. sample.pts = nextPts;
  52349. nextPts += inputSampleDuration;
  52350. }
  52351. }
  52352. var firstPTS = null;
  52353. var lastPTS = null;
  52354. var mdat;
  52355. var mdatSize = 0;
  52356. var sampleLength = inputSamples.length;
  52357. while (sampleLength--) {
  52358. mdatSize += inputSamples[sampleLength].unit.byteLength;
  52359. }
  52360. for (var _j2 = 0, _nbSamples = inputSamples.length; _j2 < _nbSamples; _j2++) {
  52361. var audioSample = inputSamples[_j2];
  52362. var unit = audioSample.unit;
  52363. var _pts2 = audioSample.pts;
  52364. if (lastPTS !== null) {
  52365. // If we have more than one sample, set the duration of the sample to the "real" duration; the PTS diff with
  52366. // the previous sample
  52367. var prevSample = outputSamples[_j2 - 1];
  52368. prevSample.duration = Math.round((_pts2 - lastPTS) / scaleFactor);
  52369. } else {
  52370. if (contiguous && track.segmentCodec === 'aac') {
  52371. // set PTS/DTS to expected PTS/DTS
  52372. _pts2 = nextAudioPts;
  52373. }
  52374. // remember first PTS of our audioSamples
  52375. firstPTS = _pts2;
  52376. if (mdatSize > 0) {
  52377. /* concatenate the audio data and construct the mdat in place
  52378. (need 8 more bytes to fill length and mdat type) */
  52379. mdatSize += offset;
  52380. try {
  52381. mdat = new Uint8Array(mdatSize);
  52382. } catch (err) {
  52383. this.observer.emit(_events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR, _events__WEBPACK_IMPORTED_MODULE_3__.Events.ERROR, {
  52384. type: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorTypes.MUX_ERROR,
  52385. details: _errors__WEBPACK_IMPORTED_MODULE_4__.ErrorDetails.REMUX_ALLOC_ERROR,
  52386. fatal: false,
  52387. bytes: mdatSize,
  52388. reason: "fail allocating audio mdat " + mdatSize
  52389. });
  52390. return;
  52391. }
  52392. if (!rawMPEG) {
  52393. var view = new DataView(mdat.buffer);
  52394. view.setUint32(0, mdatSize);
  52395. mdat.set(_mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].types.mdat, 4);
  52396. }
  52397. } else {
  52398. // no audio samples
  52399. return;
  52400. }
  52401. }
  52402. mdat.set(unit, offset);
  52403. var unitLen = unit.byteLength;
  52404. offset += unitLen;
  52405. // Default the sample's duration to the computed mp4SampleDuration, which will either be 1024 for AAC or 1152 for MPEG
  52406. // In the case that we have 1 sample, this will be the duration. If we have more than one sample, the duration
  52407. // becomes the PTS diff with the previous sample
  52408. outputSamples.push(new Mp4Sample(true, mp4SampleDuration, unitLen, 0));
  52409. lastPTS = _pts2;
  52410. }
  52411. // We could end up with no audio samples if all input samples were overlapping with the previously remuxed ones
  52412. var nbSamples = outputSamples.length;
  52413. if (!nbSamples) {
  52414. return;
  52415. }
  52416. // The next audio sample PTS should be equal to last sample PTS + duration
  52417. var lastSample = outputSamples[outputSamples.length - 1];
  52418. this.nextAudioPts = nextAudioPts = lastPTS + scaleFactor * lastSample.duration;
  52419. // Set the track samples from inputSamples to outputSamples before remuxing
  52420. var moof = rawMPEG ? new Uint8Array(0) : _mp4_generator__WEBPACK_IMPORTED_MODULE_2__["default"].moof(track.sequenceNumber++, firstPTS / scaleFactor, _extends({}, track, {
  52421. samples: outputSamples
  52422. }));
  52423. // Clear the track samples. This also clears the samples array in the demuxer, since the reference is shared
  52424. track.samples = [];
  52425. var start = firstPTS / inputTimeScale;
  52426. var end = nextAudioPts / inputTimeScale;
  52427. var type = 'audio';
  52428. var audioData = {
  52429. data1: moof,
  52430. data2: mdat,
  52431. startPTS: start,
  52432. endPTS: end,
  52433. startDTS: start,
  52434. endDTS: end,
  52435. type: type,
  52436. hasAudio: true,
  52437. hasVideo: false,
  52438. nb: nbSamples
  52439. };
  52440. this.isAudioContiguous = true;
  52441. console.assert(mdat.length, 'MDAT length must not be zero');
  52442. return audioData;
  52443. };
  52444. _proto.remuxEmptyAudio = function remuxEmptyAudio(track, timeOffset, contiguous, videoData) {
  52445. var inputTimeScale = track.inputTimeScale;
  52446. var mp4timeScale = track.samplerate ? track.samplerate : inputTimeScale;
  52447. var scaleFactor = inputTimeScale / mp4timeScale;
  52448. var nextAudioPts = this.nextAudioPts;
  52449. // sync with video's timestamp
  52450. var startDTS = (nextAudioPts !== null ? nextAudioPts : videoData.startDTS * inputTimeScale) + this._initDTS;
  52451. var endDTS = videoData.endDTS * inputTimeScale + this._initDTS;
  52452. // one sample's duration value
  52453. var frameDuration = scaleFactor * AAC_SAMPLES_PER_FRAME;
  52454. // samples count of this segment's duration
  52455. var nbSamples = Math.ceil((endDTS - startDTS) / frameDuration);
  52456. // silent frame
  52457. var silentFrame = _aac_helper__WEBPACK_IMPORTED_MODULE_1__["default"].getSilentFrame(track.manifestCodec || track.codec, track.channelCount);
  52458. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.warn('[mp4-remuxer]: remux empty Audio');
  52459. // Can't remux if we can't generate a silent frame...
  52460. if (!silentFrame) {
  52461. _utils_logger__WEBPACK_IMPORTED_MODULE_5__.logger.trace('[mp4-remuxer]: Unable to remuxEmptyAudio since we were unable to get a silent frame for given audio codec');
  52462. return;
  52463. }
  52464. var samples = [];
  52465. for (var i = 0; i < nbSamples; i++) {
  52466. var stamp = startDTS + i * frameDuration;
  52467. samples.push({
  52468. unit: silentFrame,
  52469. pts: stamp,
  52470. dts: stamp
  52471. });
  52472. }
  52473. track.samples = samples;
  52474. return this.remuxAudio(track, timeOffset, contiguous, false);
  52475. };
  52476. return MP4Remuxer;
  52477. }();
  52478. function normalizePts(value, reference) {
  52479. var offset;
  52480. if (reference === null) {
  52481. return value;
  52482. }
  52483. if (reference < value) {
  52484. // - 2^33
  52485. offset = -8589934592;
  52486. } else {
  52487. // + 2^33
  52488. offset = 8589934592;
  52489. }
  52490. /* PTS is 33bit (from 0 to 2^33 -1)
  52491. if diff between value and reference is bigger than half of the amplitude (2^32) then it means that
  52492. PTS looping occured. fill the gap */
  52493. while (Math.abs(value - reference) > 4294967296) {
  52494. value += offset;
  52495. }
  52496. return value;
  52497. }
  52498. function findKeyframeIndex(samples) {
  52499. for (var i = 0; i < samples.length; i++) {
  52500. if (samples[i].key) {
  52501. return i;
  52502. }
  52503. }
  52504. return -1;
  52505. }
  52506. function flushTextTrackMetadataCueSamples(track, timeOffset, initPTS, initDTS) {
  52507. var length = track.samples.length;
  52508. if (!length) {
  52509. return;
  52510. }
  52511. var inputTimeScale = track.inputTimeScale;
  52512. for (var index = 0; index < length; index++) {
  52513. var sample = track.samples[index];
  52514. // setting id3 pts, dts to relative time
  52515. // using this._initPTS and this._initDTS to calculate relative time
  52516. sample.pts = normalizePts(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale;
  52517. sample.dts = normalizePts(sample.dts - initDTS, timeOffset * inputTimeScale) / inputTimeScale;
  52518. }
  52519. var samples = track.samples;
  52520. track.samples = [];
  52521. return {
  52522. samples: samples
  52523. };
  52524. }
  52525. function flushTextTrackUserdataCueSamples(track, timeOffset, initPTS) {
  52526. var length = track.samples.length;
  52527. if (!length) {
  52528. return;
  52529. }
  52530. var inputTimeScale = track.inputTimeScale;
  52531. for (var index = 0; index < length; index++) {
  52532. var sample = track.samples[index];
  52533. // setting text pts, dts to relative time
  52534. // using this._initPTS and this._initDTS to calculate relative time
  52535. sample.pts = normalizePts(sample.pts - initPTS, timeOffset * inputTimeScale) / inputTimeScale;
  52536. }
  52537. track.samples.sort(function (a, b) {
  52538. return a.pts - b.pts;
  52539. });
  52540. var samples = track.samples;
  52541. track.samples = [];
  52542. return {
  52543. samples: samples
  52544. };
  52545. }
  52546. var Mp4Sample = function Mp4Sample(isKeyframe, duration, size, cts) {
  52547. this.size = void 0;
  52548. this.duration = void 0;
  52549. this.cts = void 0;
  52550. this.flags = void 0;
  52551. this.duration = duration;
  52552. this.size = size;
  52553. this.cts = cts;
  52554. this.flags = new Mp4SampleFlags(isKeyframe);
  52555. };
  52556. var Mp4SampleFlags = function Mp4SampleFlags(isKeyframe) {
  52557. this.isLeading = 0;
  52558. this.isDependedOn = 0;
  52559. this.hasRedundancy = 0;
  52560. this.degradPrio = 0;
  52561. this.dependsOn = 1;
  52562. this.isNonSync = 1;
  52563. this.dependsOn = isKeyframe ? 2 : 1;
  52564. this.isNonSync = isKeyframe ? 0 : 1;
  52565. };
  52566. /***/ }),
  52567. /***/ "./src/remux/passthrough-remuxer.ts":
  52568. /*!******************************************!*\
  52569. !*** ./src/remux/passthrough-remuxer.ts ***!
  52570. \******************************************/
  52571. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  52572. "use strict";
  52573. __webpack_require__.r(__webpack_exports__);
  52574. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  52575. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  52576. /* harmony export */ });
  52577. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  52578. /* harmony import */ var _mp4_remuxer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mp4-remuxer */ "./src/remux/mp4-remuxer.ts");
  52579. /* harmony import */ var _utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/mp4-tools */ "./src/utils/mp4-tools.ts");
  52580. /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts");
  52581. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  52582. var PassThroughRemuxer = /*#__PURE__*/function () {
  52583. function PassThroughRemuxer() {
  52584. this.emitInitSegment = false;
  52585. this.audioCodec = void 0;
  52586. this.videoCodec = void 0;
  52587. this.initData = void 0;
  52588. this.initPTS = void 0;
  52589. this.initTracks = void 0;
  52590. this.lastEndTime = null;
  52591. }
  52592. var _proto = PassThroughRemuxer.prototype;
  52593. _proto.destroy = function destroy() {};
  52594. _proto.resetTimeStamp = function resetTimeStamp(defaultInitPTS) {
  52595. this.initPTS = defaultInitPTS;
  52596. this.lastEndTime = null;
  52597. };
  52598. _proto.resetNextTimestamp = function resetNextTimestamp() {
  52599. this.lastEndTime = null;
  52600. };
  52601. _proto.resetInitSegment = function resetInitSegment(initSegment, audioCodec, videoCodec, decryptdata) {
  52602. this.audioCodec = audioCodec;
  52603. this.videoCodec = videoCodec;
  52604. this.generateInitSegment((0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.patchEncyptionData)(initSegment, decryptdata));
  52605. this.emitInitSegment = true;
  52606. };
  52607. _proto.generateInitSegment = function generateInitSegment(initSegment) {
  52608. var audioCodec = this.audioCodec,
  52609. videoCodec = this.videoCodec;
  52610. if (!initSegment || !initSegment.byteLength) {
  52611. this.initTracks = undefined;
  52612. this.initData = undefined;
  52613. return;
  52614. }
  52615. var initData = this.initData = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.parseInitSegment)(initSegment);
  52616. // Get codec from initSegment or fallback to default
  52617. if (!audioCodec) {
  52618. audioCodec = getParsedTrackCodec(initData.audio, _loader_fragment__WEBPACK_IMPORTED_MODULE_3__.ElementaryStreamTypes.AUDIO);
  52619. }
  52620. if (!videoCodec) {
  52621. videoCodec = getParsedTrackCodec(initData.video, _loader_fragment__WEBPACK_IMPORTED_MODULE_3__.ElementaryStreamTypes.VIDEO);
  52622. }
  52623. var tracks = {};
  52624. if (initData.audio && initData.video) {
  52625. tracks.audiovideo = {
  52626. container: 'video/mp4',
  52627. codec: audioCodec + ',' + videoCodec,
  52628. initSegment: initSegment,
  52629. id: 'main'
  52630. };
  52631. } else if (initData.audio) {
  52632. tracks.audio = {
  52633. container: 'audio/mp4',
  52634. codec: audioCodec,
  52635. initSegment: initSegment,
  52636. id: 'audio'
  52637. };
  52638. } else if (initData.video) {
  52639. tracks.video = {
  52640. container: 'video/mp4',
  52641. codec: videoCodec,
  52642. initSegment: initSegment,
  52643. id: 'main'
  52644. };
  52645. } else {
  52646. _utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn('[passthrough-remuxer.ts]: initSegment does not contain moov or trak boxes.');
  52647. }
  52648. this.initTracks = tracks;
  52649. };
  52650. _proto.remux = function remux(audioTrack, videoTrack, id3Track, textTrack, timeOffset) {
  52651. var _this$initPTS;
  52652. var initPTS = this.initPTS,
  52653. lastEndTime = this.lastEndTime;
  52654. var result = {
  52655. audio: undefined,
  52656. video: undefined,
  52657. text: textTrack,
  52658. id3: id3Track,
  52659. initSegment: undefined
  52660. };
  52661. // If we haven't yet set a lastEndDTS, or it was reset, set it to the provided timeOffset. We want to use the
  52662. // lastEndDTS over timeOffset whenever possible; during progressive playback, the media source will not update
  52663. // the media duration (which is what timeOffset is provided as) before we need to process the next chunk.
  52664. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(lastEndTime)) {
  52665. lastEndTime = this.lastEndTime = timeOffset || 0;
  52666. }
  52667. // The binary segment data is added to the videoTrack in the mp4demuxer. We don't check to see if the data is only
  52668. // audio or video (or both); adding it to video was an arbitrary choice.
  52669. var data = videoTrack.samples;
  52670. if (!data || !data.length) {
  52671. return result;
  52672. }
  52673. var initSegment = {
  52674. initPTS: undefined,
  52675. timescale: 1
  52676. };
  52677. var initData = this.initData;
  52678. if (!initData || !initData.length) {
  52679. this.generateInitSegment(data);
  52680. initData = this.initData;
  52681. }
  52682. if (!initData || !initData.length) {
  52683. // We can't remux if the initSegment could not be generated
  52684. _utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn('[passthrough-remuxer.ts]: Failed to generate initSegment.');
  52685. return result;
  52686. }
  52687. if (this.emitInitSegment) {
  52688. initSegment.tracks = this.initTracks;
  52689. this.emitInitSegment = false;
  52690. }
  52691. var startDTS = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.getStartDTS)(initData, data);
  52692. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(initPTS)) {
  52693. this.initPTS = initSegment.initPTS = initPTS = startDTS - timeOffset;
  52694. }
  52695. var duration = (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.getDuration)(data, initData);
  52696. var startTime = audioTrack ? startDTS - initPTS : lastEndTime;
  52697. var endTime = startTime + duration;
  52698. (0,_utils_mp4_tools__WEBPACK_IMPORTED_MODULE_2__.offsetStartDTS)(initData, data, initPTS);
  52699. if (duration > 0) {
  52700. this.lastEndTime = endTime;
  52701. } else {
  52702. _utils_logger__WEBPACK_IMPORTED_MODULE_4__.logger.warn('Duration parsed from mp4 should be greater than zero');
  52703. this.resetNextTimestamp();
  52704. }
  52705. var hasAudio = !!initData.audio;
  52706. var hasVideo = !!initData.video;
  52707. var type = '';
  52708. if (hasAudio) {
  52709. type += 'audio';
  52710. }
  52711. if (hasVideo) {
  52712. type += 'video';
  52713. }
  52714. var track = {
  52715. data1: data,
  52716. startPTS: startTime,
  52717. startDTS: startTime,
  52718. endPTS: endTime,
  52719. endDTS: endTime,
  52720. type: type,
  52721. hasAudio: hasAudio,
  52722. hasVideo: hasVideo,
  52723. nb: 1,
  52724. dropped: 0
  52725. };
  52726. result.audio = track.type === 'audio' ? track : undefined;
  52727. result.video = track.type !== 'audio' ? track : undefined;
  52728. result.initSegment = initSegment;
  52729. var initPtsNum = (_this$initPTS = this.initPTS) != null ? _this$initPTS : 0;
  52730. result.id3 = (0,_mp4_remuxer__WEBPACK_IMPORTED_MODULE_1__.flushTextTrackMetadataCueSamples)(id3Track, timeOffset, initPtsNum, initPtsNum);
  52731. if (textTrack.samples.length) {
  52732. result.text = (0,_mp4_remuxer__WEBPACK_IMPORTED_MODULE_1__.flushTextTrackUserdataCueSamples)(textTrack, timeOffset, initPtsNum);
  52733. }
  52734. return result;
  52735. };
  52736. return PassThroughRemuxer;
  52737. }();
  52738. function getParsedTrackCodec(track, type) {
  52739. var parsedCodec = track === null || track === void 0 ? void 0 : track.codec;
  52740. if (parsedCodec && parsedCodec.length > 4) {
  52741. return parsedCodec;
  52742. }
  52743. // Since mp4-tools cannot parse full codec string (see 'TODO: Parse codec details'... in mp4-tools)
  52744. // Provide defaults based on codec type
  52745. // This allows for some playback of some fmp4 playlists without CODECS defined in manifest
  52746. if (parsedCodec === 'hvc1' || parsedCodec === 'hev1') {
  52747. return 'hvc1.1.c.L120.90';
  52748. }
  52749. if (parsedCodec === 'av01') {
  52750. return 'av01.0.04M.08';
  52751. }
  52752. if (parsedCodec === 'avc1' || type === _loader_fragment__WEBPACK_IMPORTED_MODULE_3__.ElementaryStreamTypes.VIDEO) {
  52753. return 'avc1.42e01e';
  52754. }
  52755. return 'mp4a.40.5';
  52756. }
  52757. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (PassThroughRemuxer);
  52758. /***/ }),
  52759. /***/ "./src/task-loop.ts":
  52760. /*!**************************!*\
  52761. !*** ./src/task-loop.ts ***!
  52762. \**************************/
  52763. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  52764. "use strict";
  52765. __webpack_require__.r(__webpack_exports__);
  52766. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  52767. /* harmony export */ "default": () => (/* binding */ TaskLoop)
  52768. /* harmony export */ });
  52769. /**
  52770. * Sub-class specialization of EventHandler base class.
  52771. *
  52772. * TaskLoop allows to schedule a task function being called (optionnaly repeatedly) on the main loop,
  52773. * scheduled asynchroneously, avoiding recursive calls in the same tick.
  52774. *
  52775. * The task itself is implemented in `doTick`. It can be requested and called for single execution
  52776. * using the `tick` method.
  52777. *
  52778. * It will be assured that the task execution method (`tick`) only gets called once per main loop "tick",
  52779. * no matter how often it gets requested for execution. Execution in further ticks will be scheduled accordingly.
  52780. *
  52781. * If further execution requests have already been scheduled on the next tick, it can be checked with `hasNextTick`,
  52782. * and cancelled with `clearNextTick`.
  52783. *
  52784. * The task can be scheduled as an interval repeatedly with a period as parameter (see `setInterval`, `clearInterval`).
  52785. *
  52786. * Sub-classes need to implement the `doTick` method which will effectively have the task execution routine.
  52787. *
  52788. * Further explanations:
  52789. *
  52790. * The baseclass has a `tick` method that will schedule the doTick call. It may be called synchroneously
  52791. * only for a stack-depth of one. On re-entrant calls, sub-sequent calls are scheduled for next main loop ticks.
  52792. *
  52793. * When the task execution (`tick` method) is called in re-entrant way this is detected and
  52794. * we are limiting the task execution per call stack to exactly one, but scheduling/post-poning further
  52795. * task processing on the next main loop iteration (also known as "next tick" in the Node/JS runtime lingo).
  52796. */
  52797. var TaskLoop = /*#__PURE__*/function () {
  52798. function TaskLoop() {
  52799. this._boundTick = void 0;
  52800. this._tickTimer = null;
  52801. this._tickInterval = null;
  52802. this._tickCallCount = 0;
  52803. this._boundTick = this.tick.bind(this);
  52804. }
  52805. var _proto = TaskLoop.prototype;
  52806. _proto.destroy = function destroy() {
  52807. this.onHandlerDestroying();
  52808. this.onHandlerDestroyed();
  52809. };
  52810. _proto.onHandlerDestroying = function onHandlerDestroying() {
  52811. // clear all timers before unregistering from event bus
  52812. this.clearNextTick();
  52813. this.clearInterval();
  52814. };
  52815. _proto.onHandlerDestroyed = function onHandlerDestroyed() {}
  52816. /**
  52817. * @returns {boolean}
  52818. */;
  52819. _proto.hasInterval = function hasInterval() {
  52820. return !!this._tickInterval;
  52821. }
  52822. /**
  52823. * @returns {boolean}
  52824. */;
  52825. _proto.hasNextTick = function hasNextTick() {
  52826. return !!this._tickTimer;
  52827. }
  52828. /**
  52829. * @param {number} millis Interval time (ms)
  52830. * @returns {boolean} True when interval has been scheduled, false when already scheduled (no effect)
  52831. */;
  52832. _proto.setInterval = function setInterval(millis) {
  52833. if (!this._tickInterval) {
  52834. this._tickInterval = self.setInterval(this._boundTick, millis);
  52835. return true;
  52836. }
  52837. return false;
  52838. }
  52839. /**
  52840. * @returns {boolean} True when interval was cleared, false when none was set (no effect)
  52841. */;
  52842. _proto.clearInterval = function clearInterval() {
  52843. if (this._tickInterval) {
  52844. self.clearInterval(this._tickInterval);
  52845. this._tickInterval = null;
  52846. return true;
  52847. }
  52848. return false;
  52849. }
  52850. /**
  52851. * @returns {boolean} True when timeout was cleared, false when none was set (no effect)
  52852. */;
  52853. _proto.clearNextTick = function clearNextTick() {
  52854. if (this._tickTimer) {
  52855. self.clearTimeout(this._tickTimer);
  52856. this._tickTimer = null;
  52857. return true;
  52858. }
  52859. return false;
  52860. }
  52861. /**
  52862. * Will call the subclass doTick implementation in this main loop tick
  52863. * or in the next one (via setTimeout(,0)) in case it has already been called
  52864. * in this tick (in case this is a re-entrant call).
  52865. */;
  52866. _proto.tick = function tick() {
  52867. this._tickCallCount++;
  52868. if (this._tickCallCount === 1) {
  52869. this.doTick();
  52870. // re-entrant call to tick from previous doTick call stack
  52871. // -> schedule a call on the next main loop iteration to process this task processing request
  52872. if (this._tickCallCount > 1) {
  52873. // make sure only one timer exists at any time at max
  52874. this.tickImmediate();
  52875. }
  52876. this._tickCallCount = 0;
  52877. }
  52878. };
  52879. _proto.tickImmediate = function tickImmediate() {
  52880. this.clearNextTick();
  52881. this._tickTimer = self.setTimeout(this._boundTick, 0);
  52882. }
  52883. /**
  52884. * For subclass to implement task logic
  52885. * @abstract
  52886. */;
  52887. _proto.doTick = function doTick() {};
  52888. return TaskLoop;
  52889. }();
  52890. /***/ }),
  52891. /***/ "./src/types/cmcd.ts":
  52892. /*!***************************!*\
  52893. !*** ./src/types/cmcd.ts ***!
  52894. \***************************/
  52895. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  52896. "use strict";
  52897. __webpack_require__.r(__webpack_exports__);
  52898. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  52899. /* harmony export */ "CMCDObjectType": () => (/* binding */ CMCDObjectType),
  52900. /* harmony export */ "CMCDStreamType": () => (/* binding */ CMCDStreamType),
  52901. /* harmony export */ "CMCDStreamingFormat": () => (/* binding */ CMCDStreamingFormat),
  52902. /* harmony export */ "CMCDVersion": () => (/* binding */ CMCDVersion)
  52903. /* harmony export */ });
  52904. /**
  52905. * CMCD spec version
  52906. */
  52907. var CMCDVersion = 1;
  52908. /**
  52909. * CMCD Object Type
  52910. */
  52911. var CMCDObjectType;
  52912. /**
  52913. * CMCD Streaming Format
  52914. */
  52915. (function (CMCDObjectType) {
  52916. CMCDObjectType["MANIFEST"] = "m";
  52917. CMCDObjectType["AUDIO"] = "a";
  52918. CMCDObjectType["VIDEO"] = "v";
  52919. CMCDObjectType["MUXED"] = "av";
  52920. CMCDObjectType["INIT"] = "i";
  52921. CMCDObjectType["CAPTION"] = "c";
  52922. CMCDObjectType["TIMED_TEXT"] = "tt";
  52923. CMCDObjectType["KEY"] = "k";
  52924. CMCDObjectType["OTHER"] = "o";
  52925. })(CMCDObjectType || (CMCDObjectType = {}));
  52926. var CMCDStreamingFormat;
  52927. /**
  52928. * CMCD Streaming Type
  52929. */
  52930. (function (CMCDStreamingFormat) {
  52931. CMCDStreamingFormat["DASH"] = "d";
  52932. CMCDStreamingFormat["HLS"] = "h";
  52933. CMCDStreamingFormat["SMOOTH"] = "s";
  52934. CMCDStreamingFormat["OTHER"] = "o";
  52935. })(CMCDStreamingFormat || (CMCDStreamingFormat = {}));
  52936. var CMCDStreamType;
  52937. /**
  52938. * CMCD Headers
  52939. */
  52940. (function (CMCDStreamType) {
  52941. CMCDStreamType["VOD"] = "v";
  52942. CMCDStreamType["LIVE"] = "l";
  52943. })(CMCDStreamType || (CMCDStreamType = {}));
  52944. /***/ }),
  52945. /***/ "./src/types/demuxer.ts":
  52946. /*!******************************!*\
  52947. !*** ./src/types/demuxer.ts ***!
  52948. \******************************/
  52949. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  52950. "use strict";
  52951. __webpack_require__.r(__webpack_exports__);
  52952. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  52953. /* harmony export */ "MetadataSchema": () => (/* binding */ MetadataSchema)
  52954. /* harmony export */ });
  52955. var MetadataSchema;
  52956. (function (MetadataSchema) {
  52957. MetadataSchema["audioId3"] = "org.id3";
  52958. MetadataSchema["dateRange"] = "com.apple.quicktime.HLS";
  52959. MetadataSchema["emsg"] = "https://aomedia.org/emsg/ID3";
  52960. })(MetadataSchema || (MetadataSchema = {}));
  52961. /***/ }),
  52962. /***/ "./src/types/level.ts":
  52963. /*!****************************!*\
  52964. !*** ./src/types/level.ts ***!
  52965. \****************************/
  52966. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  52967. "use strict";
  52968. __webpack_require__.r(__webpack_exports__);
  52969. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  52970. /* harmony export */ "HdcpLevels": () => (/* binding */ HdcpLevels),
  52971. /* harmony export */ "HlsSkip": () => (/* binding */ HlsSkip),
  52972. /* harmony export */ "HlsUrlParameters": () => (/* binding */ HlsUrlParameters),
  52973. /* harmony export */ "Level": () => (/* binding */ Level),
  52974. /* harmony export */ "getSkipValue": () => (/* binding */ getSkipValue)
  52975. /* harmony export */ });
  52976. function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
  52977. function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
  52978. function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
  52979. function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
  52980. var HdcpLevels = ['NONE', 'TYPE-0', 'TYPE-1', 'TYPE-2', null];
  52981. var HlsSkip;
  52982. (function (HlsSkip) {
  52983. HlsSkip["No"] = "";
  52984. HlsSkip["Yes"] = "YES";
  52985. HlsSkip["v2"] = "v2";
  52986. })(HlsSkip || (HlsSkip = {}));
  52987. function getSkipValue(details, msn) {
  52988. var canSkipUntil = details.canSkipUntil,
  52989. canSkipDateRanges = details.canSkipDateRanges,
  52990. endSN = details.endSN;
  52991. var snChangeGoal = msn !== undefined ? msn - endSN : 0;
  52992. if (canSkipUntil && snChangeGoal < canSkipUntil) {
  52993. if (canSkipDateRanges) {
  52994. return HlsSkip.v2;
  52995. }
  52996. return HlsSkip.Yes;
  52997. }
  52998. return HlsSkip.No;
  52999. }
  53000. var HlsUrlParameters = /*#__PURE__*/function () {
  53001. function HlsUrlParameters(msn, part, skip) {
  53002. this.msn = void 0;
  53003. this.part = void 0;
  53004. this.skip = void 0;
  53005. this.msn = msn;
  53006. this.part = part;
  53007. this.skip = skip;
  53008. }
  53009. var _proto = HlsUrlParameters.prototype;
  53010. _proto.addDirectives = function addDirectives(uri) {
  53011. var url = new self.URL(uri);
  53012. if (this.msn !== undefined) {
  53013. url.searchParams.set('_HLS_msn', this.msn.toString());
  53014. }
  53015. if (this.part !== undefined) {
  53016. url.searchParams.set('_HLS_part', this.part.toString());
  53017. }
  53018. if (this.skip) {
  53019. url.searchParams.set('_HLS_skip', this.skip);
  53020. }
  53021. return url.href;
  53022. };
  53023. return HlsUrlParameters;
  53024. }();
  53025. var Level = /*#__PURE__*/function () {
  53026. function Level(data) {
  53027. this.attrs = void 0;
  53028. this.audioCodec = void 0;
  53029. this.bitrate = void 0;
  53030. this.codecSet = void 0;
  53031. this.height = void 0;
  53032. this.id = void 0;
  53033. this.name = void 0;
  53034. this.videoCodec = void 0;
  53035. this.width = void 0;
  53036. this.unknownCodecs = void 0;
  53037. this.audioGroupIds = void 0;
  53038. this.details = void 0;
  53039. this.fragmentError = 0;
  53040. this.loadError = 0;
  53041. this.loaded = void 0;
  53042. this.realBitrate = 0;
  53043. this.textGroupIds = void 0;
  53044. this.url = void 0;
  53045. this._urlId = 0;
  53046. this.url = [data.url];
  53047. this.attrs = data.attrs;
  53048. this.bitrate = data.bitrate;
  53049. if (data.details) {
  53050. this.details = data.details;
  53051. }
  53052. this.id = data.id || 0;
  53053. this.name = data.name;
  53054. this.width = data.width || 0;
  53055. this.height = data.height || 0;
  53056. this.audioCodec = data.audioCodec;
  53057. this.videoCodec = data.videoCodec;
  53058. this.unknownCodecs = data.unknownCodecs;
  53059. this.codecSet = [data.videoCodec, data.audioCodec].filter(function (c) {
  53060. return c;
  53061. }).join(',').replace(/\.[^.,]+/g, '');
  53062. }
  53063. _createClass(Level, [{
  53064. key: "maxBitrate",
  53065. get: function get() {
  53066. return Math.max(this.realBitrate, this.bitrate);
  53067. }
  53068. }, {
  53069. key: "uri",
  53070. get: function get() {
  53071. return this.url[this._urlId] || '';
  53072. }
  53073. }, {
  53074. key: "urlId",
  53075. get: function get() {
  53076. return this._urlId;
  53077. },
  53078. set: function set(value) {
  53079. var newValue = value % this.url.length;
  53080. if (this._urlId !== newValue) {
  53081. this.details = undefined;
  53082. this._urlId = newValue;
  53083. }
  53084. }
  53085. }]);
  53086. return Level;
  53087. }();
  53088. /***/ }),
  53089. /***/ "./src/types/loader.ts":
  53090. /*!*****************************!*\
  53091. !*** ./src/types/loader.ts ***!
  53092. \*****************************/
  53093. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  53094. "use strict";
  53095. __webpack_require__.r(__webpack_exports__);
  53096. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  53097. /* harmony export */ "PlaylistContextType": () => (/* binding */ PlaylistContextType),
  53098. /* harmony export */ "PlaylistLevelType": () => (/* binding */ PlaylistLevelType)
  53099. /* harmony export */ });
  53100. var PlaylistContextType;
  53101. (function (PlaylistContextType) {
  53102. PlaylistContextType["MANIFEST"] = "manifest";
  53103. PlaylistContextType["LEVEL"] = "level";
  53104. PlaylistContextType["AUDIO_TRACK"] = "audioTrack";
  53105. PlaylistContextType["SUBTITLE_TRACK"] = "subtitleTrack";
  53106. })(PlaylistContextType || (PlaylistContextType = {}));
  53107. var PlaylistLevelType;
  53108. (function (PlaylistLevelType) {
  53109. PlaylistLevelType["MAIN"] = "main";
  53110. PlaylistLevelType["AUDIO"] = "audio";
  53111. PlaylistLevelType["SUBTITLE"] = "subtitle";
  53112. })(PlaylistLevelType || (PlaylistLevelType = {}));
  53113. /***/ }),
  53114. /***/ "./src/types/transmuxer.ts":
  53115. /*!*********************************!*\
  53116. !*** ./src/types/transmuxer.ts ***!
  53117. \*********************************/
  53118. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  53119. "use strict";
  53120. __webpack_require__.r(__webpack_exports__);
  53121. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  53122. /* harmony export */ "ChunkMetadata": () => (/* binding */ ChunkMetadata)
  53123. /* harmony export */ });
  53124. var ChunkMetadata = function ChunkMetadata(level, sn, id, size, part, partial) {
  53125. if (size === void 0) {
  53126. size = 0;
  53127. }
  53128. if (part === void 0) {
  53129. part = -1;
  53130. }
  53131. if (partial === void 0) {
  53132. partial = false;
  53133. }
  53134. this.level = void 0;
  53135. this.sn = void 0;
  53136. this.part = void 0;
  53137. this.id = void 0;
  53138. this.size = void 0;
  53139. this.partial = void 0;
  53140. this.transmuxing = getNewPerformanceTiming();
  53141. this.buffering = {
  53142. audio: getNewPerformanceTiming(),
  53143. video: getNewPerformanceTiming(),
  53144. audiovideo: getNewPerformanceTiming()
  53145. };
  53146. this.level = level;
  53147. this.sn = sn;
  53148. this.id = id;
  53149. this.size = size;
  53150. this.part = part;
  53151. this.partial = partial;
  53152. };
  53153. function getNewPerformanceTiming() {
  53154. return {
  53155. start: 0,
  53156. executeStart: 0,
  53157. executeEnd: 0,
  53158. end: 0
  53159. };
  53160. }
  53161. /***/ }),
  53162. /***/ "./src/utils/attr-list.ts":
  53163. /*!********************************!*\
  53164. !*** ./src/utils/attr-list.ts ***!
  53165. \********************************/
  53166. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  53167. "use strict";
  53168. __webpack_require__.r(__webpack_exports__);
  53169. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  53170. /* harmony export */ "AttrList": () => (/* binding */ AttrList)
  53171. /* harmony export */ });
  53172. var DECIMAL_RESOLUTION_REGEX = /^(\d+)x(\d+)$/; // eslint-disable-line no-useless-escape
  53173. var ATTR_LIST_REGEX = /\s*(.+?)\s*=((?:\".*?\")|.*?)(?:,|$)/g; // eslint-disable-line no-useless-escape
  53174. // adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
  53175. var AttrList = /*#__PURE__*/function () {
  53176. function AttrList(attrs) {
  53177. if (typeof attrs === 'string') {
  53178. attrs = AttrList.parseAttrList(attrs);
  53179. }
  53180. for (var attr in attrs) {
  53181. if (attrs.hasOwnProperty(attr)) {
  53182. this[attr] = attrs[attr];
  53183. }
  53184. }
  53185. }
  53186. var _proto = AttrList.prototype;
  53187. _proto.decimalInteger = function decimalInteger(attrName) {
  53188. var intValue = parseInt(this[attrName], 10);
  53189. if (intValue > Number.MAX_SAFE_INTEGER) {
  53190. return Infinity;
  53191. }
  53192. return intValue;
  53193. };
  53194. _proto.hexadecimalInteger = function hexadecimalInteger(attrName) {
  53195. if (this[attrName]) {
  53196. var stringValue = (this[attrName] || '0x').slice(2);
  53197. stringValue = (stringValue.length & 1 ? '0' : '') + stringValue;
  53198. var value = new Uint8Array(stringValue.length / 2);
  53199. for (var i = 0; i < stringValue.length / 2; i++) {
  53200. value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16);
  53201. }
  53202. return value;
  53203. } else {
  53204. return null;
  53205. }
  53206. };
  53207. _proto.hexadecimalIntegerAsNumber = function hexadecimalIntegerAsNumber(attrName) {
  53208. var intValue = parseInt(this[attrName], 16);
  53209. if (intValue > Number.MAX_SAFE_INTEGER) {
  53210. return Infinity;
  53211. }
  53212. return intValue;
  53213. };
  53214. _proto.decimalFloatingPoint = function decimalFloatingPoint(attrName) {
  53215. return parseFloat(this[attrName]);
  53216. };
  53217. _proto.optionalFloat = function optionalFloat(attrName, defaultValue) {
  53218. var value = this[attrName];
  53219. return value ? parseFloat(value) : defaultValue;
  53220. };
  53221. _proto.enumeratedString = function enumeratedString(attrName) {
  53222. return this[attrName];
  53223. };
  53224. _proto.bool = function bool(attrName) {
  53225. return this[attrName] === 'YES';
  53226. };
  53227. _proto.decimalResolution = function decimalResolution(attrName) {
  53228. var res = DECIMAL_RESOLUTION_REGEX.exec(this[attrName]);
  53229. if (res === null) {
  53230. return undefined;
  53231. }
  53232. return {
  53233. width: parseInt(res[1], 10),
  53234. height: parseInt(res[2], 10)
  53235. };
  53236. };
  53237. AttrList.parseAttrList = function parseAttrList(input) {
  53238. var match;
  53239. var attrs = {};
  53240. var quote = '"';
  53241. ATTR_LIST_REGEX.lastIndex = 0;
  53242. while ((match = ATTR_LIST_REGEX.exec(input)) !== null) {
  53243. var value = match[2];
  53244. if (value.indexOf(quote) === 0 && value.lastIndexOf(quote) === value.length - 1) {
  53245. value = value.slice(1, -1);
  53246. }
  53247. attrs[match[1]] = value;
  53248. }
  53249. return attrs;
  53250. };
  53251. return AttrList;
  53252. }();
  53253. /***/ }),
  53254. /***/ "./src/utils/binary-search.ts":
  53255. /*!************************************!*\
  53256. !*** ./src/utils/binary-search.ts ***!
  53257. \************************************/
  53258. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  53259. "use strict";
  53260. __webpack_require__.r(__webpack_exports__);
  53261. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  53262. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  53263. /* harmony export */ });
  53264. var BinarySearch = {
  53265. /**
  53266. * Searches for an item in an array which matches a certain condition.
  53267. * This requires the condition to only match one item in the array,
  53268. * and for the array to be ordered.
  53269. *
  53270. * @param {Array<T>} list The array to search.
  53271. * @param {BinarySearchComparison<T>} comparisonFn
  53272. * Called and provided a candidate item as the first argument.
  53273. * Should return:
  53274. * > -1 if the item should be located at a lower index than the provided item.
  53275. * > 1 if the item should be located at a higher index than the provided item.
  53276. * > 0 if the item is the item you're looking for.
  53277. *
  53278. * @return {T | null} The object if it is found or null otherwise.
  53279. */
  53280. search: function search(list, comparisonFn) {
  53281. var minIndex = 0;
  53282. var maxIndex = list.length - 1;
  53283. var currentIndex = null;
  53284. var currentElement = null;
  53285. while (minIndex <= maxIndex) {
  53286. currentIndex = (minIndex + maxIndex) / 2 | 0;
  53287. currentElement = list[currentIndex];
  53288. var comparisonResult = comparisonFn(currentElement);
  53289. if (comparisonResult > 0) {
  53290. minIndex = currentIndex + 1;
  53291. } else if (comparisonResult < 0) {
  53292. maxIndex = currentIndex - 1;
  53293. } else {
  53294. return currentElement;
  53295. }
  53296. }
  53297. return null;
  53298. }
  53299. };
  53300. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (BinarySearch);
  53301. /***/ }),
  53302. /***/ "./src/utils/buffer-helper.ts":
  53303. /*!************************************!*\
  53304. !*** ./src/utils/buffer-helper.ts ***!
  53305. \************************************/
  53306. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  53307. "use strict";
  53308. __webpack_require__.r(__webpack_exports__);
  53309. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  53310. /* harmony export */ "BufferHelper": () => (/* binding */ BufferHelper)
  53311. /* harmony export */ });
  53312. /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts");
  53313. /**
  53314. * @module BufferHelper
  53315. *
  53316. * Providing methods dealing with buffer length retrieval for example.
  53317. *
  53318. * In general, a helper around HTML5 MediaElement TimeRanges gathered from `buffered` property.
  53319. *
  53320. * Also @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/buffered
  53321. */
  53322. var noopBuffered = {
  53323. length: 0,
  53324. start: function start() {
  53325. return 0;
  53326. },
  53327. end: function end() {
  53328. return 0;
  53329. }
  53330. };
  53331. var BufferHelper = /*#__PURE__*/function () {
  53332. function BufferHelper() {}
  53333. /**
  53334. * Return true if `media`'s buffered include `position`
  53335. * @param {Bufferable} media
  53336. * @param {number} position
  53337. * @returns {boolean}
  53338. */
  53339. BufferHelper.isBuffered = function isBuffered(media, position) {
  53340. try {
  53341. if (media) {
  53342. var buffered = BufferHelper.getBuffered(media);
  53343. for (var i = 0; i < buffered.length; i++) {
  53344. if (position >= buffered.start(i) && position <= buffered.end(i)) {
  53345. return true;
  53346. }
  53347. }
  53348. }
  53349. } catch (error) {
  53350. // this is to catch
  53351. // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
  53352. // This SourceBuffer has been removed from the parent media source
  53353. }
  53354. return false;
  53355. };
  53356. BufferHelper.bufferInfo = function bufferInfo(media, pos, maxHoleDuration) {
  53357. try {
  53358. if (media) {
  53359. var vbuffered = BufferHelper.getBuffered(media);
  53360. var buffered = [];
  53361. var i;
  53362. for (i = 0; i < vbuffered.length; i++) {
  53363. buffered.push({
  53364. start: vbuffered.start(i),
  53365. end: vbuffered.end(i)
  53366. });
  53367. }
  53368. return this.bufferedInfo(buffered, pos, maxHoleDuration);
  53369. }
  53370. } catch (error) {
  53371. // this is to catch
  53372. // InvalidStateError: Failed to read the 'buffered' property from 'SourceBuffer':
  53373. // This SourceBuffer has been removed from the parent media source
  53374. }
  53375. return {
  53376. len: 0,
  53377. start: pos,
  53378. end: pos,
  53379. nextStart: undefined
  53380. };
  53381. };
  53382. BufferHelper.bufferedInfo = function bufferedInfo(buffered, pos, maxHoleDuration) {
  53383. pos = Math.max(0, pos);
  53384. // sort on buffer.start/smaller end (IE does not always return sorted buffered range)
  53385. buffered.sort(function (a, b) {
  53386. var diff = a.start - b.start;
  53387. if (diff) {
  53388. return diff;
  53389. } else {
  53390. return b.end - a.end;
  53391. }
  53392. });
  53393. var buffered2 = [];
  53394. if (maxHoleDuration) {
  53395. // there might be some small holes between buffer time range
  53396. // consider that holes smaller than maxHoleDuration are irrelevant and build another
  53397. // buffer time range representations that discards those holes
  53398. for (var i = 0; i < buffered.length; i++) {
  53399. var buf2len = buffered2.length;
  53400. if (buf2len) {
  53401. var buf2end = buffered2[buf2len - 1].end;
  53402. // if small hole (value between 0 or maxHoleDuration ) or overlapping (negative)
  53403. if (buffered[i].start - buf2end < maxHoleDuration) {
  53404. // merge overlapping time ranges
  53405. // update lastRange.end only if smaller than item.end
  53406. // e.g. [ 1, 15] with [ 2,8] => [ 1,15] (no need to modify lastRange.end)
  53407. // whereas [ 1, 8] with [ 2,15] => [ 1,15] ( lastRange should switch from [1,8] to [1,15])
  53408. if (buffered[i].end > buf2end) {
  53409. buffered2[buf2len - 1].end = buffered[i].end;
  53410. }
  53411. } else {
  53412. // big hole
  53413. buffered2.push(buffered[i]);
  53414. }
  53415. } else {
  53416. // first value
  53417. buffered2.push(buffered[i]);
  53418. }
  53419. }
  53420. } else {
  53421. buffered2 = buffered;
  53422. }
  53423. var bufferLen = 0;
  53424. // bufferStartNext can possibly be undefined based on the conditional logic below
  53425. var bufferStartNext;
  53426. // bufferStart and bufferEnd are buffer boundaries around current video position
  53427. var bufferStart = pos;
  53428. var bufferEnd = pos;
  53429. for (var _i = 0; _i < buffered2.length; _i++) {
  53430. var start = buffered2[_i].start;
  53431. var end = buffered2[_i].end;
  53432. // logger.log('buf start/end:' + buffered.start(i) + '/' + buffered.end(i));
  53433. if (pos + maxHoleDuration >= start && pos < end) {
  53434. // play position is inside this buffer TimeRange, retrieve end of buffer position and buffer length
  53435. bufferStart = start;
  53436. bufferEnd = end;
  53437. bufferLen = bufferEnd - pos;
  53438. } else if (pos + maxHoleDuration < start) {
  53439. bufferStartNext = start;
  53440. break;
  53441. }
  53442. }
  53443. return {
  53444. len: bufferLen,
  53445. start: bufferStart || 0,
  53446. end: bufferEnd || 0,
  53447. nextStart: bufferStartNext
  53448. };
  53449. }
  53450. /**
  53451. * Safe method to get buffered property.
  53452. * SourceBuffer.buffered may throw if SourceBuffer is removed from it's MediaSource
  53453. */;
  53454. BufferHelper.getBuffered = function getBuffered(media) {
  53455. try {
  53456. return media.buffered;
  53457. } catch (e) {
  53458. _logger__WEBPACK_IMPORTED_MODULE_0__.logger.log('failed to get media.buffered', e);
  53459. return noopBuffered;
  53460. }
  53461. };
  53462. return BufferHelper;
  53463. }();
  53464. /***/ }),
  53465. /***/ "./src/utils/cea-608-parser.ts":
  53466. /*!*************************************!*\
  53467. !*** ./src/utils/cea-608-parser.ts ***!
  53468. \*************************************/
  53469. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  53470. "use strict";
  53471. __webpack_require__.r(__webpack_exports__);
  53472. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  53473. /* harmony export */ "CaptionScreen": () => (/* binding */ CaptionScreen),
  53474. /* harmony export */ "Row": () => (/* binding */ Row),
  53475. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  53476. /* harmony export */ });
  53477. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  53478. /**
  53479. *
  53480. * This code was ported from the dash.js project at:
  53481. * https://github.com/Dash-Industry-Forum/dash.js/blob/development/externals/cea608-parser.js
  53482. * https://github.com/Dash-Industry-Forum/dash.js/commit/8269b26a761e0853bb21d78780ed945144ecdd4d#diff-71bc295a2d6b6b7093a1d3290d53a4b2
  53483. *
  53484. * The original copyright appears below:
  53485. *
  53486. * The copyright in this software is being made available under the BSD License,
  53487. * included below. This software may be subject to other third party and contributor
  53488. * rights, including patent rights, and no such rights are granted under this license.
  53489. *
  53490. * Copyright (c) 2015-2016, DASH Industry Forum.
  53491. * All rights reserved.
  53492. *
  53493. * Redistribution and use in source and binary forms, with or without modification,
  53494. * are permitted provided that the following conditions are met:
  53495. * 1. Redistributions of source code must retain the above copyright notice, this
  53496. * list of conditions and the following disclaimer.
  53497. * * Redistributions in binary form must reproduce the above copyright notice,
  53498. * this list of conditions and the following disclaimer in the documentation and/or
  53499. * other materials provided with the distribution.
  53500. * 2. Neither the name of Dash Industry Forum nor the names of its
  53501. * contributors may be used to endorse or promote products derived from this software
  53502. * without specific prior written permission.
  53503. *
  53504. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
  53505. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  53506. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  53507. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  53508. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  53509. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  53510. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  53511. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  53512. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  53513. * POSSIBILITY OF SUCH DAMAGE.
  53514. */
  53515. /**
  53516. * Exceptions from regular ASCII. CodePoints are mapped to UTF-16 codes
  53517. */
  53518. var specialCea608CharsCodes = {
  53519. 0x2a: 0xe1,
  53520. // lowercase a, acute accent
  53521. 0x5c: 0xe9,
  53522. // lowercase e, acute accent
  53523. 0x5e: 0xed,
  53524. // lowercase i, acute accent
  53525. 0x5f: 0xf3,
  53526. // lowercase o, acute accent
  53527. 0x60: 0xfa,
  53528. // lowercase u, acute accent
  53529. 0x7b: 0xe7,
  53530. // lowercase c with cedilla
  53531. 0x7c: 0xf7,
  53532. // division symbol
  53533. 0x7d: 0xd1,
  53534. // uppercase N tilde
  53535. 0x7e: 0xf1,
  53536. // lowercase n tilde
  53537. 0x7f: 0x2588,
  53538. // Full block
  53539. // THIS BLOCK INCLUDES THE 16 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
  53540. // THAT COME FROM HI BYTE=0x11 AND LOW BETWEEN 0x30 AND 0x3F
  53541. // THIS MEANS THAT \x50 MUST BE ADDED TO THE VALUES
  53542. 0x80: 0xae,
  53543. // Registered symbol (R)
  53544. 0x81: 0xb0,
  53545. // degree sign
  53546. 0x82: 0xbd,
  53547. // 1/2 symbol
  53548. 0x83: 0xbf,
  53549. // Inverted (open) question mark
  53550. 0x84: 0x2122,
  53551. // Trademark symbol (TM)
  53552. 0x85: 0xa2,
  53553. // Cents symbol
  53554. 0x86: 0xa3,
  53555. // Pounds sterling
  53556. 0x87: 0x266a,
  53557. // Music 8'th note
  53558. 0x88: 0xe0,
  53559. // lowercase a, grave accent
  53560. 0x89: 0x20,
  53561. // transparent space (regular)
  53562. 0x8a: 0xe8,
  53563. // lowercase e, grave accent
  53564. 0x8b: 0xe2,
  53565. // lowercase a, circumflex accent
  53566. 0x8c: 0xea,
  53567. // lowercase e, circumflex accent
  53568. 0x8d: 0xee,
  53569. // lowercase i, circumflex accent
  53570. 0x8e: 0xf4,
  53571. // lowercase o, circumflex accent
  53572. 0x8f: 0xfb,
  53573. // lowercase u, circumflex accent
  53574. // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
  53575. // THAT COME FROM HI BYTE=0x12 AND LOW BETWEEN 0x20 AND 0x3F
  53576. 0x90: 0xc1,
  53577. // capital letter A with acute
  53578. 0x91: 0xc9,
  53579. // capital letter E with acute
  53580. 0x92: 0xd3,
  53581. // capital letter O with acute
  53582. 0x93: 0xda,
  53583. // capital letter U with acute
  53584. 0x94: 0xdc,
  53585. // capital letter U with diaresis
  53586. 0x95: 0xfc,
  53587. // lowercase letter U with diaeresis
  53588. 0x96: 0x2018,
  53589. // opening single quote
  53590. 0x97: 0xa1,
  53591. // inverted exclamation mark
  53592. 0x98: 0x2a,
  53593. // asterisk
  53594. 0x99: 0x2019,
  53595. // closing single quote
  53596. 0x9a: 0x2501,
  53597. // box drawings heavy horizontal
  53598. 0x9b: 0xa9,
  53599. // copyright sign
  53600. 0x9c: 0x2120,
  53601. // Service mark
  53602. 0x9d: 0x2022,
  53603. // (round) bullet
  53604. 0x9e: 0x201c,
  53605. // Left double quotation mark
  53606. 0x9f: 0x201d,
  53607. // Right double quotation mark
  53608. 0xa0: 0xc0,
  53609. // uppercase A, grave accent
  53610. 0xa1: 0xc2,
  53611. // uppercase A, circumflex
  53612. 0xa2: 0xc7,
  53613. // uppercase C with cedilla
  53614. 0xa3: 0xc8,
  53615. // uppercase E, grave accent
  53616. 0xa4: 0xca,
  53617. // uppercase E, circumflex
  53618. 0xa5: 0xcb,
  53619. // capital letter E with diaresis
  53620. 0xa6: 0xeb,
  53621. // lowercase letter e with diaresis
  53622. 0xa7: 0xce,
  53623. // uppercase I, circumflex
  53624. 0xa8: 0xcf,
  53625. // uppercase I, with diaresis
  53626. 0xa9: 0xef,
  53627. // lowercase i, with diaresis
  53628. 0xaa: 0xd4,
  53629. // uppercase O, circumflex
  53630. 0xab: 0xd9,
  53631. // uppercase U, grave accent
  53632. 0xac: 0xf9,
  53633. // lowercase u, grave accent
  53634. 0xad: 0xdb,
  53635. // uppercase U, circumflex
  53636. 0xae: 0xab,
  53637. // left-pointing double angle quotation mark
  53638. 0xaf: 0xbb,
  53639. // right-pointing double angle quotation mark
  53640. // THIS BLOCK INCLUDES THE 32 EXTENDED (TWO-BYTE) LINE 21 CHARACTERS
  53641. // THAT COME FROM HI BYTE=0x13 AND LOW BETWEEN 0x20 AND 0x3F
  53642. 0xb0: 0xc3,
  53643. // Uppercase A, tilde
  53644. 0xb1: 0xe3,
  53645. // Lowercase a, tilde
  53646. 0xb2: 0xcd,
  53647. // Uppercase I, acute accent
  53648. 0xb3: 0xcc,
  53649. // Uppercase I, grave accent
  53650. 0xb4: 0xec,
  53651. // Lowercase i, grave accent
  53652. 0xb5: 0xd2,
  53653. // Uppercase O, grave accent
  53654. 0xb6: 0xf2,
  53655. // Lowercase o, grave accent
  53656. 0xb7: 0xd5,
  53657. // Uppercase O, tilde
  53658. 0xb8: 0xf5,
  53659. // Lowercase o, tilde
  53660. 0xb9: 0x7b,
  53661. // Open curly brace
  53662. 0xba: 0x7d,
  53663. // Closing curly brace
  53664. 0xbb: 0x5c,
  53665. // Backslash
  53666. 0xbc: 0x5e,
  53667. // Caret
  53668. 0xbd: 0x5f,
  53669. // Underscore
  53670. 0xbe: 0x7c,
  53671. // Pipe (vertical line)
  53672. 0xbf: 0x223c,
  53673. // Tilde operator
  53674. 0xc0: 0xc4,
  53675. // Uppercase A, umlaut
  53676. 0xc1: 0xe4,
  53677. // Lowercase A, umlaut
  53678. 0xc2: 0xd6,
  53679. // Uppercase O, umlaut
  53680. 0xc3: 0xf6,
  53681. // Lowercase o, umlaut
  53682. 0xc4: 0xdf,
  53683. // Esszett (sharp S)
  53684. 0xc5: 0xa5,
  53685. // Yen symbol
  53686. 0xc6: 0xa4,
  53687. // Generic currency sign
  53688. 0xc7: 0x2503,
  53689. // Box drawings heavy vertical
  53690. 0xc8: 0xc5,
  53691. // Uppercase A, ring
  53692. 0xc9: 0xe5,
  53693. // Lowercase A, ring
  53694. 0xca: 0xd8,
  53695. // Uppercase O, stroke
  53696. 0xcb: 0xf8,
  53697. // Lowercase o, strok
  53698. 0xcc: 0x250f,
  53699. // Box drawings heavy down and right
  53700. 0xcd: 0x2513,
  53701. // Box drawings heavy down and left
  53702. 0xce: 0x2517,
  53703. // Box drawings heavy up and right
  53704. 0xcf: 0x251b // Box drawings heavy up and left
  53705. };
  53706. /**
  53707. * Utils
  53708. */
  53709. var getCharForByte = function getCharForByte(_byte) {
  53710. var charCode = _byte;
  53711. if (specialCea608CharsCodes.hasOwnProperty(_byte)) {
  53712. charCode = specialCea608CharsCodes[_byte];
  53713. }
  53714. return String.fromCharCode(charCode);
  53715. };
  53716. var NR_ROWS = 15;
  53717. var NR_COLS = 100;
  53718. // Tables to look up row from PAC data
  53719. var rowsLowCh1 = {
  53720. 0x11: 1,
  53721. 0x12: 3,
  53722. 0x15: 5,
  53723. 0x16: 7,
  53724. 0x17: 9,
  53725. 0x10: 11,
  53726. 0x13: 12,
  53727. 0x14: 14
  53728. };
  53729. var rowsHighCh1 = {
  53730. 0x11: 2,
  53731. 0x12: 4,
  53732. 0x15: 6,
  53733. 0x16: 8,
  53734. 0x17: 10,
  53735. 0x13: 13,
  53736. 0x14: 15
  53737. };
  53738. var rowsLowCh2 = {
  53739. 0x19: 1,
  53740. 0x1a: 3,
  53741. 0x1d: 5,
  53742. 0x1e: 7,
  53743. 0x1f: 9,
  53744. 0x18: 11,
  53745. 0x1b: 12,
  53746. 0x1c: 14
  53747. };
  53748. var rowsHighCh2 = {
  53749. 0x19: 2,
  53750. 0x1a: 4,
  53751. 0x1d: 6,
  53752. 0x1e: 8,
  53753. 0x1f: 10,
  53754. 0x1b: 13,
  53755. 0x1c: 15
  53756. };
  53757. var backgroundColors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'black', 'transparent'];
  53758. var VerboseLevel;
  53759. (function (VerboseLevel) {
  53760. VerboseLevel[VerboseLevel["ERROR"] = 0] = "ERROR";
  53761. VerboseLevel[VerboseLevel["TEXT"] = 1] = "TEXT";
  53762. VerboseLevel[VerboseLevel["WARNING"] = 2] = "WARNING";
  53763. VerboseLevel[VerboseLevel["INFO"] = 2] = "INFO";
  53764. VerboseLevel[VerboseLevel["DEBUG"] = 3] = "DEBUG";
  53765. VerboseLevel[VerboseLevel["DATA"] = 3] = "DATA";
  53766. })(VerboseLevel || (VerboseLevel = {}));
  53767. var CaptionsLogger = /*#__PURE__*/function () {
  53768. function CaptionsLogger() {
  53769. this.time = null;
  53770. this.verboseLevel = VerboseLevel.ERROR;
  53771. }
  53772. var _proto = CaptionsLogger.prototype;
  53773. _proto.log = function log(severity, msg) {
  53774. if (this.verboseLevel >= severity) {
  53775. var m = typeof msg === 'function' ? msg() : msg;
  53776. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.log(this.time + " [" + severity + "] " + m);
  53777. }
  53778. };
  53779. return CaptionsLogger;
  53780. }();
  53781. var numArrayToHexArray = function numArrayToHexArray(numArray) {
  53782. var hexArray = [];
  53783. for (var j = 0; j < numArray.length; j++) {
  53784. hexArray.push(numArray[j].toString(16));
  53785. }
  53786. return hexArray;
  53787. };
  53788. var PenState = /*#__PURE__*/function () {
  53789. function PenState(foreground, underline, italics, background, flash) {
  53790. this.foreground = void 0;
  53791. this.underline = void 0;
  53792. this.italics = void 0;
  53793. this.background = void 0;
  53794. this.flash = void 0;
  53795. this.foreground = foreground || 'white';
  53796. this.underline = underline || false;
  53797. this.italics = italics || false;
  53798. this.background = background || 'black';
  53799. this.flash = flash || false;
  53800. }
  53801. var _proto2 = PenState.prototype;
  53802. _proto2.reset = function reset() {
  53803. this.foreground = 'white';
  53804. this.underline = false;
  53805. this.italics = false;
  53806. this.background = 'black';
  53807. this.flash = false;
  53808. };
  53809. _proto2.setStyles = function setStyles(styles) {
  53810. var attribs = ['foreground', 'underline', 'italics', 'background', 'flash'];
  53811. for (var i = 0; i < attribs.length; i++) {
  53812. var style = attribs[i];
  53813. if (styles.hasOwnProperty(style)) {
  53814. this[style] = styles[style];
  53815. }
  53816. }
  53817. };
  53818. _proto2.isDefault = function isDefault() {
  53819. return this.foreground === 'white' && !this.underline && !this.italics && this.background === 'black' && !this.flash;
  53820. };
  53821. _proto2.equals = function equals(other) {
  53822. return this.foreground === other.foreground && this.underline === other.underline && this.italics === other.italics && this.background === other.background && this.flash === other.flash;
  53823. };
  53824. _proto2.copy = function copy(newPenState) {
  53825. this.foreground = newPenState.foreground;
  53826. this.underline = newPenState.underline;
  53827. this.italics = newPenState.italics;
  53828. this.background = newPenState.background;
  53829. this.flash = newPenState.flash;
  53830. };
  53831. _proto2.toString = function toString() {
  53832. return 'color=' + this.foreground + ', underline=' + this.underline + ', italics=' + this.italics + ', background=' + this.background + ', flash=' + this.flash;
  53833. };
  53834. return PenState;
  53835. }();
  53836. /**
  53837. * Unicode character with styling and background.
  53838. * @constructor
  53839. */
  53840. var StyledUnicodeChar = /*#__PURE__*/function () {
  53841. function StyledUnicodeChar(uchar, foreground, underline, italics, background, flash) {
  53842. this.uchar = void 0;
  53843. this.penState = void 0;
  53844. this.uchar = uchar || ' '; // unicode character
  53845. this.penState = new PenState(foreground, underline, italics, background, flash);
  53846. }
  53847. var _proto3 = StyledUnicodeChar.prototype;
  53848. _proto3.reset = function reset() {
  53849. this.uchar = ' ';
  53850. this.penState.reset();
  53851. };
  53852. _proto3.setChar = function setChar(uchar, newPenState) {
  53853. this.uchar = uchar;
  53854. this.penState.copy(newPenState);
  53855. };
  53856. _proto3.setPenState = function setPenState(newPenState) {
  53857. this.penState.copy(newPenState);
  53858. };
  53859. _proto3.equals = function equals(other) {
  53860. return this.uchar === other.uchar && this.penState.equals(other.penState);
  53861. };
  53862. _proto3.copy = function copy(newChar) {
  53863. this.uchar = newChar.uchar;
  53864. this.penState.copy(newChar.penState);
  53865. };
  53866. _proto3.isEmpty = function isEmpty() {
  53867. return this.uchar === ' ' && this.penState.isDefault();
  53868. };
  53869. return StyledUnicodeChar;
  53870. }();
  53871. /**
  53872. * CEA-608 row consisting of NR_COLS instances of StyledUnicodeChar.
  53873. * @constructor
  53874. */
  53875. var Row = /*#__PURE__*/function () {
  53876. function Row(logger) {
  53877. this.chars = void 0;
  53878. this.pos = void 0;
  53879. this.currPenState = void 0;
  53880. this.cueStartTime = void 0;
  53881. this.logger = void 0;
  53882. this.chars = [];
  53883. for (var i = 0; i < NR_COLS; i++) {
  53884. this.chars.push(new StyledUnicodeChar());
  53885. }
  53886. this.logger = logger;
  53887. this.pos = 0;
  53888. this.currPenState = new PenState();
  53889. }
  53890. var _proto4 = Row.prototype;
  53891. _proto4.equals = function equals(other) {
  53892. var equal = true;
  53893. for (var i = 0; i < NR_COLS; i++) {
  53894. if (!this.chars[i].equals(other.chars[i])) {
  53895. equal = false;
  53896. break;
  53897. }
  53898. }
  53899. return equal;
  53900. };
  53901. _proto4.copy = function copy(other) {
  53902. for (var i = 0; i < NR_COLS; i++) {
  53903. this.chars[i].copy(other.chars[i]);
  53904. }
  53905. };
  53906. _proto4.isEmpty = function isEmpty() {
  53907. var empty = true;
  53908. for (var i = 0; i < NR_COLS; i++) {
  53909. if (!this.chars[i].isEmpty()) {
  53910. empty = false;
  53911. break;
  53912. }
  53913. }
  53914. return empty;
  53915. }
  53916. /**
  53917. * Set the cursor to a valid column.
  53918. */;
  53919. _proto4.setCursor = function setCursor(absPos) {
  53920. if (this.pos !== absPos) {
  53921. this.pos = absPos;
  53922. }
  53923. if (this.pos < 0) {
  53924. this.logger.log(VerboseLevel.DEBUG, 'Negative cursor position ' + this.pos);
  53925. this.pos = 0;
  53926. } else if (this.pos > NR_COLS) {
  53927. this.logger.log(VerboseLevel.DEBUG, 'Too large cursor position ' + this.pos);
  53928. this.pos = NR_COLS;
  53929. }
  53930. }
  53931. /**
  53932. * Move the cursor relative to current position.
  53933. */;
  53934. _proto4.moveCursor = function moveCursor(relPos) {
  53935. var newPos = this.pos + relPos;
  53936. if (relPos > 1) {
  53937. for (var i = this.pos + 1; i < newPos + 1; i++) {
  53938. this.chars[i].setPenState(this.currPenState);
  53939. }
  53940. }
  53941. this.setCursor(newPos);
  53942. }
  53943. /**
  53944. * Backspace, move one step back and clear character.
  53945. */;
  53946. _proto4.backSpace = function backSpace() {
  53947. this.moveCursor(-1);
  53948. this.chars[this.pos].setChar(' ', this.currPenState);
  53949. };
  53950. _proto4.insertChar = function insertChar(_byte2) {
  53951. var _this = this;
  53952. if (_byte2 >= 0x90) {
  53953. // Extended char
  53954. this.backSpace();
  53955. }
  53956. var _char = getCharForByte(_byte2);
  53957. if (this.pos >= NR_COLS) {
  53958. this.logger.log(VerboseLevel.ERROR, function () {
  53959. return 'Cannot insert ' + _byte2.toString(16) + ' (' + _char + ') at position ' + _this.pos + '. Skipping it!';
  53960. });
  53961. return;
  53962. }
  53963. this.chars[this.pos].setChar(_char, this.currPenState);
  53964. this.moveCursor(1);
  53965. };
  53966. _proto4.clearFromPos = function clearFromPos(startPos) {
  53967. var i;
  53968. for (i = startPos; i < NR_COLS; i++) {
  53969. this.chars[i].reset();
  53970. }
  53971. };
  53972. _proto4.clear = function clear() {
  53973. this.clearFromPos(0);
  53974. this.pos = 0;
  53975. this.currPenState.reset();
  53976. };
  53977. _proto4.clearToEndOfRow = function clearToEndOfRow() {
  53978. this.clearFromPos(this.pos);
  53979. };
  53980. _proto4.getTextString = function getTextString() {
  53981. var chars = [];
  53982. var empty = true;
  53983. for (var i = 0; i < NR_COLS; i++) {
  53984. var _char2 = this.chars[i].uchar;
  53985. if (_char2 !== ' ') {
  53986. empty = false;
  53987. }
  53988. chars.push(_char2);
  53989. }
  53990. if (empty) {
  53991. return '';
  53992. } else {
  53993. return chars.join('');
  53994. }
  53995. };
  53996. _proto4.setPenStyles = function setPenStyles(styles) {
  53997. this.currPenState.setStyles(styles);
  53998. var currChar = this.chars[this.pos];
  53999. currChar.setPenState(this.currPenState);
  54000. };
  54001. return Row;
  54002. }();
  54003. /**
  54004. * Keep a CEA-608 screen of 32x15 styled characters
  54005. * @constructor
  54006. */
  54007. var CaptionScreen = /*#__PURE__*/function () {
  54008. function CaptionScreen(logger) {
  54009. this.rows = void 0;
  54010. this.currRow = void 0;
  54011. this.nrRollUpRows = void 0;
  54012. this.lastOutputScreen = void 0;
  54013. this.logger = void 0;
  54014. this.rows = [];
  54015. for (var i = 0; i < NR_ROWS; i++) {
  54016. this.rows.push(new Row(logger));
  54017. } // Note that we use zero-based numbering (0-14)
  54018. this.logger = logger;
  54019. this.currRow = NR_ROWS - 1;
  54020. this.nrRollUpRows = null;
  54021. this.lastOutputScreen = null;
  54022. this.reset();
  54023. }
  54024. var _proto5 = CaptionScreen.prototype;
  54025. _proto5.reset = function reset() {
  54026. for (var i = 0; i < NR_ROWS; i++) {
  54027. this.rows[i].clear();
  54028. }
  54029. this.currRow = NR_ROWS - 1;
  54030. };
  54031. _proto5.equals = function equals(other) {
  54032. var equal = true;
  54033. for (var i = 0; i < NR_ROWS; i++) {
  54034. if (!this.rows[i].equals(other.rows[i])) {
  54035. equal = false;
  54036. break;
  54037. }
  54038. }
  54039. return equal;
  54040. };
  54041. _proto5.copy = function copy(other) {
  54042. for (var i = 0; i < NR_ROWS; i++) {
  54043. this.rows[i].copy(other.rows[i]);
  54044. }
  54045. };
  54046. _proto5.isEmpty = function isEmpty() {
  54047. var empty = true;
  54048. for (var i = 0; i < NR_ROWS; i++) {
  54049. if (!this.rows[i].isEmpty()) {
  54050. empty = false;
  54051. break;
  54052. }
  54053. }
  54054. return empty;
  54055. };
  54056. _proto5.backSpace = function backSpace() {
  54057. var row = this.rows[this.currRow];
  54058. row.backSpace();
  54059. };
  54060. _proto5.clearToEndOfRow = function clearToEndOfRow() {
  54061. var row = this.rows[this.currRow];
  54062. row.clearToEndOfRow();
  54063. }
  54064. /**
  54065. * Insert a character (without styling) in the current row.
  54066. */;
  54067. _proto5.insertChar = function insertChar(_char3) {
  54068. var row = this.rows[this.currRow];
  54069. row.insertChar(_char3);
  54070. };
  54071. _proto5.setPen = function setPen(styles) {
  54072. var row = this.rows[this.currRow];
  54073. row.setPenStyles(styles);
  54074. };
  54075. _proto5.moveCursor = function moveCursor(relPos) {
  54076. var row = this.rows[this.currRow];
  54077. row.moveCursor(relPos);
  54078. };
  54079. _proto5.setCursor = function setCursor(absPos) {
  54080. this.logger.log(VerboseLevel.INFO, 'setCursor: ' + absPos);
  54081. var row = this.rows[this.currRow];
  54082. row.setCursor(absPos);
  54083. };
  54084. _proto5.setPAC = function setPAC(pacData) {
  54085. this.logger.log(VerboseLevel.INFO, function () {
  54086. return 'pacData = ' + JSON.stringify(pacData);
  54087. });
  54088. var newRow = pacData.row - 1;
  54089. if (this.nrRollUpRows && newRow < this.nrRollUpRows - 1) {
  54090. newRow = this.nrRollUpRows - 1;
  54091. }
  54092. // Make sure this only affects Roll-up Captions by checking this.nrRollUpRows
  54093. if (this.nrRollUpRows && this.currRow !== newRow) {
  54094. // clear all rows first
  54095. for (var i = 0; i < NR_ROWS; i++) {
  54096. this.rows[i].clear();
  54097. }
  54098. // Copy this.nrRollUpRows rows from lastOutputScreen and place it in the newRow location
  54099. // topRowIndex - the start of rows to copy (inclusive index)
  54100. var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
  54101. // We only copy if the last position was already shown.
  54102. // We use the cueStartTime value to check this.
  54103. var lastOutputScreen = this.lastOutputScreen;
  54104. if (lastOutputScreen) {
  54105. var prevLineTime = lastOutputScreen.rows[topRowIndex].cueStartTime;
  54106. var time = this.logger.time;
  54107. if (prevLineTime && time !== null && prevLineTime < time) {
  54108. for (var _i = 0; _i < this.nrRollUpRows; _i++) {
  54109. this.rows[newRow - this.nrRollUpRows + _i + 1].copy(lastOutputScreen.rows[topRowIndex + _i]);
  54110. }
  54111. }
  54112. }
  54113. }
  54114. this.currRow = newRow;
  54115. var row = this.rows[this.currRow];
  54116. if (pacData.indent !== null) {
  54117. var indent = pacData.indent;
  54118. var prevPos = Math.max(indent - 1, 0);
  54119. row.setCursor(pacData.indent);
  54120. pacData.color = row.chars[prevPos].penState.foreground;
  54121. }
  54122. var styles = {
  54123. foreground: pacData.color,
  54124. underline: pacData.underline,
  54125. italics: pacData.italics,
  54126. background: 'black',
  54127. flash: false
  54128. };
  54129. this.setPen(styles);
  54130. }
  54131. /**
  54132. * Set background/extra foreground, but first do back_space, and then insert space (backwards compatibility).
  54133. */;
  54134. _proto5.setBkgData = function setBkgData(bkgData) {
  54135. this.logger.log(VerboseLevel.INFO, function () {
  54136. return 'bkgData = ' + JSON.stringify(bkgData);
  54137. });
  54138. this.backSpace();
  54139. this.setPen(bkgData);
  54140. this.insertChar(0x20); // Space
  54141. };
  54142. _proto5.setRollUpRows = function setRollUpRows(nrRows) {
  54143. this.nrRollUpRows = nrRows;
  54144. };
  54145. _proto5.rollUp = function rollUp() {
  54146. var _this2 = this;
  54147. if (this.nrRollUpRows === null) {
  54148. this.logger.log(VerboseLevel.DEBUG, 'roll_up but nrRollUpRows not set yet');
  54149. return; // Not properly setup
  54150. }
  54151. this.logger.log(VerboseLevel.TEXT, function () {
  54152. return _this2.getDisplayText();
  54153. });
  54154. var topRowIndex = this.currRow + 1 - this.nrRollUpRows;
  54155. var topRow = this.rows.splice(topRowIndex, 1)[0];
  54156. topRow.clear();
  54157. this.rows.splice(this.currRow, 0, topRow);
  54158. this.logger.log(VerboseLevel.INFO, 'Rolling up');
  54159. // this.logger.log(VerboseLevel.TEXT, this.get_display_text())
  54160. }
  54161. /**
  54162. * Get all non-empty rows with as unicode text.
  54163. */;
  54164. _proto5.getDisplayText = function getDisplayText(asOneRow) {
  54165. asOneRow = asOneRow || false;
  54166. var displayText = [];
  54167. var text = '';
  54168. var rowNr = -1;
  54169. for (var i = 0; i < NR_ROWS; i++) {
  54170. var rowText = this.rows[i].getTextString();
  54171. if (rowText) {
  54172. rowNr = i + 1;
  54173. if (asOneRow) {
  54174. displayText.push('Row ' + rowNr + ": '" + rowText + "'");
  54175. } else {
  54176. displayText.push(rowText.trim());
  54177. }
  54178. }
  54179. }
  54180. if (displayText.length > 0) {
  54181. if (asOneRow) {
  54182. text = '[' + displayText.join(' | ') + ']';
  54183. } else {
  54184. text = displayText.join('\n');
  54185. }
  54186. }
  54187. return text;
  54188. };
  54189. _proto5.getTextAndFormat = function getTextAndFormat() {
  54190. return this.rows;
  54191. };
  54192. return CaptionScreen;
  54193. }();
  54194. // var modes = ['MODE_ROLL-UP', 'MODE_POP-ON', 'MODE_PAINT-ON', 'MODE_TEXT'];
  54195. var Cea608Channel = /*#__PURE__*/function () {
  54196. function Cea608Channel(channelNumber, outputFilter, logger) {
  54197. this.chNr = void 0;
  54198. this.outputFilter = void 0;
  54199. this.mode = void 0;
  54200. this.verbose = void 0;
  54201. this.displayedMemory = void 0;
  54202. this.nonDisplayedMemory = void 0;
  54203. this.lastOutputScreen = void 0;
  54204. this.currRollUpRow = void 0;
  54205. this.writeScreen = void 0;
  54206. this.cueStartTime = void 0;
  54207. this.logger = void 0;
  54208. this.chNr = channelNumber;
  54209. this.outputFilter = outputFilter;
  54210. this.mode = null;
  54211. this.verbose = 0;
  54212. this.displayedMemory = new CaptionScreen(logger);
  54213. this.nonDisplayedMemory = new CaptionScreen(logger);
  54214. this.lastOutputScreen = new CaptionScreen(logger);
  54215. this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];
  54216. this.writeScreen = this.displayedMemory;
  54217. this.mode = null;
  54218. this.cueStartTime = null; // Keeps track of where a cue started.
  54219. this.logger = logger;
  54220. }
  54221. var _proto6 = Cea608Channel.prototype;
  54222. _proto6.reset = function reset() {
  54223. this.mode = null;
  54224. this.displayedMemory.reset();
  54225. this.nonDisplayedMemory.reset();
  54226. this.lastOutputScreen.reset();
  54227. this.outputFilter.reset();
  54228. this.currRollUpRow = this.displayedMemory.rows[NR_ROWS - 1];
  54229. this.writeScreen = this.displayedMemory;
  54230. this.mode = null;
  54231. this.cueStartTime = null;
  54232. };
  54233. _proto6.getHandler = function getHandler() {
  54234. return this.outputFilter;
  54235. };
  54236. _proto6.setHandler = function setHandler(newHandler) {
  54237. this.outputFilter = newHandler;
  54238. };
  54239. _proto6.setPAC = function setPAC(pacData) {
  54240. this.writeScreen.setPAC(pacData);
  54241. };
  54242. _proto6.setBkgData = function setBkgData(bkgData) {
  54243. this.writeScreen.setBkgData(bkgData);
  54244. };
  54245. _proto6.setMode = function setMode(newMode) {
  54246. if (newMode === this.mode) {
  54247. return;
  54248. }
  54249. this.mode = newMode;
  54250. this.logger.log(VerboseLevel.INFO, function () {
  54251. return 'MODE=' + newMode;
  54252. });
  54253. if (this.mode === 'MODE_POP-ON') {
  54254. this.writeScreen = this.nonDisplayedMemory;
  54255. } else {
  54256. this.writeScreen = this.displayedMemory;
  54257. this.writeScreen.reset();
  54258. }
  54259. if (this.mode !== 'MODE_ROLL-UP') {
  54260. this.displayedMemory.nrRollUpRows = null;
  54261. this.nonDisplayedMemory.nrRollUpRows = null;
  54262. }
  54263. this.mode = newMode;
  54264. };
  54265. _proto6.insertChars = function insertChars(chars) {
  54266. var _this3 = this;
  54267. for (var i = 0; i < chars.length; i++) {
  54268. this.writeScreen.insertChar(chars[i]);
  54269. }
  54270. var screen = this.writeScreen === this.displayedMemory ? 'DISP' : 'NON_DISP';
  54271. this.logger.log(VerboseLevel.INFO, function () {
  54272. return screen + ': ' + _this3.writeScreen.getDisplayText(true);
  54273. });
  54274. if (this.mode === 'MODE_PAINT-ON' || this.mode === 'MODE_ROLL-UP') {
  54275. this.logger.log(VerboseLevel.TEXT, function () {
  54276. return 'DISPLAYED: ' + _this3.displayedMemory.getDisplayText(true);
  54277. });
  54278. this.outputDataUpdate();
  54279. }
  54280. };
  54281. _proto6.ccRCL = function ccRCL() {
  54282. // Resume Caption Loading (switch mode to Pop On)
  54283. this.logger.log(VerboseLevel.INFO, 'RCL - Resume Caption Loading');
  54284. this.setMode('MODE_POP-ON');
  54285. };
  54286. _proto6.ccBS = function ccBS() {
  54287. // BackSpace
  54288. this.logger.log(VerboseLevel.INFO, 'BS - BackSpace');
  54289. if (this.mode === 'MODE_TEXT') {
  54290. return;
  54291. }
  54292. this.writeScreen.backSpace();
  54293. if (this.writeScreen === this.displayedMemory) {
  54294. this.outputDataUpdate();
  54295. }
  54296. };
  54297. _proto6.ccAOF = function ccAOF() {
  54298. // Reserved (formerly Alarm Off)
  54299. };
  54300. _proto6.ccAON = function ccAON() {
  54301. // Reserved (formerly Alarm On)
  54302. };
  54303. _proto6.ccDER = function ccDER() {
  54304. // Delete to End of Row
  54305. this.logger.log(VerboseLevel.INFO, 'DER- Delete to End of Row');
  54306. this.writeScreen.clearToEndOfRow();
  54307. this.outputDataUpdate();
  54308. };
  54309. _proto6.ccRU = function ccRU(nrRows) {
  54310. // Roll-Up Captions-2,3,or 4 Rows
  54311. this.logger.log(VerboseLevel.INFO, 'RU(' + nrRows + ') - Roll Up');
  54312. this.writeScreen = this.displayedMemory;
  54313. this.setMode('MODE_ROLL-UP');
  54314. this.writeScreen.setRollUpRows(nrRows);
  54315. };
  54316. _proto6.ccFON = function ccFON() {
  54317. // Flash On
  54318. this.logger.log(VerboseLevel.INFO, 'FON - Flash On');
  54319. this.writeScreen.setPen({
  54320. flash: true
  54321. });
  54322. };
  54323. _proto6.ccRDC = function ccRDC() {
  54324. // Resume Direct Captioning (switch mode to PaintOn)
  54325. this.logger.log(VerboseLevel.INFO, 'RDC - Resume Direct Captioning');
  54326. this.setMode('MODE_PAINT-ON');
  54327. };
  54328. _proto6.ccTR = function ccTR() {
  54329. // Text Restart in text mode (not supported, however)
  54330. this.logger.log(VerboseLevel.INFO, 'TR');
  54331. this.setMode('MODE_TEXT');
  54332. };
  54333. _proto6.ccRTD = function ccRTD() {
  54334. // Resume Text Display in Text mode (not supported, however)
  54335. this.logger.log(VerboseLevel.INFO, 'RTD');
  54336. this.setMode('MODE_TEXT');
  54337. };
  54338. _proto6.ccEDM = function ccEDM() {
  54339. // Erase Displayed Memory
  54340. this.logger.log(VerboseLevel.INFO, 'EDM - Erase Displayed Memory');
  54341. this.displayedMemory.reset();
  54342. this.outputDataUpdate(true);
  54343. };
  54344. _proto6.ccCR = function ccCR() {
  54345. // Carriage Return
  54346. this.logger.log(VerboseLevel.INFO, 'CR - Carriage Return');
  54347. this.writeScreen.rollUp();
  54348. this.outputDataUpdate(true);
  54349. };
  54350. _proto6.ccENM = function ccENM() {
  54351. // Erase Non-Displayed Memory
  54352. this.logger.log(VerboseLevel.INFO, 'ENM - Erase Non-displayed Memory');
  54353. this.nonDisplayedMemory.reset();
  54354. };
  54355. _proto6.ccEOC = function ccEOC() {
  54356. var _this4 = this;
  54357. // End of Caption (Flip Memories)
  54358. this.logger.log(VerboseLevel.INFO, 'EOC - End Of Caption');
  54359. if (this.mode === 'MODE_POP-ON') {
  54360. var tmp = this.displayedMemory;
  54361. this.displayedMemory = this.nonDisplayedMemory;
  54362. this.nonDisplayedMemory = tmp;
  54363. this.writeScreen = this.nonDisplayedMemory;
  54364. this.logger.log(VerboseLevel.TEXT, function () {
  54365. return 'DISP: ' + _this4.displayedMemory.getDisplayText();
  54366. });
  54367. }
  54368. this.outputDataUpdate(true);
  54369. };
  54370. _proto6.ccTO = function ccTO(nrCols) {
  54371. // Tab Offset 1,2, or 3 columns
  54372. this.logger.log(VerboseLevel.INFO, 'TO(' + nrCols + ') - Tab Offset');
  54373. this.writeScreen.moveCursor(nrCols);
  54374. };
  54375. _proto6.ccMIDROW = function ccMIDROW(secondByte) {
  54376. // Parse MIDROW command
  54377. var styles = {
  54378. flash: false
  54379. };
  54380. styles.underline = secondByte % 2 === 1;
  54381. styles.italics = secondByte >= 0x2e;
  54382. if (!styles.italics) {
  54383. var colorIndex = Math.floor(secondByte / 2) - 0x10;
  54384. var colors = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta'];
  54385. styles.foreground = colors[colorIndex];
  54386. } else {
  54387. styles.foreground = 'white';
  54388. }
  54389. this.logger.log(VerboseLevel.INFO, 'MIDROW: ' + JSON.stringify(styles));
  54390. this.writeScreen.setPen(styles);
  54391. };
  54392. _proto6.outputDataUpdate = function outputDataUpdate(dispatch) {
  54393. if (dispatch === void 0) {
  54394. dispatch = false;
  54395. }
  54396. var time = this.logger.time;
  54397. if (time === null) {
  54398. return;
  54399. }
  54400. if (this.outputFilter) {
  54401. if (this.cueStartTime === null && !this.displayedMemory.isEmpty()) {
  54402. // Start of a new cue
  54403. this.cueStartTime = time;
  54404. } else {
  54405. if (!this.displayedMemory.equals(this.lastOutputScreen)) {
  54406. this.outputFilter.newCue(this.cueStartTime, time, this.lastOutputScreen);
  54407. if (dispatch && this.outputFilter.dispatchCue) {
  54408. this.outputFilter.dispatchCue();
  54409. }
  54410. this.cueStartTime = this.displayedMemory.isEmpty() ? null : time;
  54411. }
  54412. }
  54413. this.lastOutputScreen.copy(this.displayedMemory);
  54414. }
  54415. };
  54416. _proto6.cueSplitAtTime = function cueSplitAtTime(t) {
  54417. if (this.outputFilter) {
  54418. if (!this.displayedMemory.isEmpty()) {
  54419. if (this.outputFilter.newCue) {
  54420. this.outputFilter.newCue(this.cueStartTime, t, this.displayedMemory);
  54421. }
  54422. this.cueStartTime = t;
  54423. }
  54424. }
  54425. };
  54426. return Cea608Channel;
  54427. }();
  54428. var Cea608Parser = /*#__PURE__*/function () {
  54429. function Cea608Parser(field, out1, out2) {
  54430. this.channels = void 0;
  54431. this.currentChannel = 0;
  54432. this.cmdHistory = void 0;
  54433. this.logger = void 0;
  54434. var logger = new CaptionsLogger();
  54435. this.channels = [null, new Cea608Channel(field, out1, logger), new Cea608Channel(field + 1, out2, logger)];
  54436. this.cmdHistory = createCmdHistory();
  54437. this.logger = logger;
  54438. }
  54439. var _proto7 = Cea608Parser.prototype;
  54440. _proto7.getHandler = function getHandler(channel) {
  54441. return this.channels[channel].getHandler();
  54442. };
  54443. _proto7.setHandler = function setHandler(channel, newHandler) {
  54444. this.channels[channel].setHandler(newHandler);
  54445. }
  54446. /**
  54447. * Add data for time t in forms of list of bytes (unsigned ints). The bytes are treated as pairs.
  54448. */;
  54449. _proto7.addData = function addData(time, byteList) {
  54450. var cmdFound;
  54451. var a;
  54452. var b;
  54453. var charsFound = false;
  54454. this.logger.time = time;
  54455. for (var i = 0; i < byteList.length; i += 2) {
  54456. a = byteList[i] & 0x7f;
  54457. b = byteList[i + 1] & 0x7f;
  54458. if (a === 0 && b === 0) {
  54459. continue;
  54460. } else {
  54461. this.logger.log(VerboseLevel.DATA, '[' + numArrayToHexArray([byteList[i], byteList[i + 1]]) + '] -> (' + numArrayToHexArray([a, b]) + ')');
  54462. }
  54463. cmdFound = this.parseCmd(a, b);
  54464. if (!cmdFound) {
  54465. cmdFound = this.parseMidrow(a, b);
  54466. }
  54467. if (!cmdFound) {
  54468. cmdFound = this.parsePAC(a, b);
  54469. }
  54470. if (!cmdFound) {
  54471. cmdFound = this.parseBackgroundAttributes(a, b);
  54472. }
  54473. if (!cmdFound) {
  54474. charsFound = this.parseChars(a, b);
  54475. if (charsFound) {
  54476. var currChNr = this.currentChannel;
  54477. if (currChNr && currChNr > 0) {
  54478. var channel = this.channels[currChNr];
  54479. channel.insertChars(charsFound);
  54480. } else {
  54481. this.logger.log(VerboseLevel.WARNING, 'No channel found yet. TEXT-MODE?');
  54482. }
  54483. }
  54484. }
  54485. if (!cmdFound && !charsFound) {
  54486. this.logger.log(VerboseLevel.WARNING, "Couldn't parse cleaned data " + numArrayToHexArray([a, b]) + ' orig: ' + numArrayToHexArray([byteList[i], byteList[i + 1]]));
  54487. }
  54488. }
  54489. }
  54490. /**
  54491. * Parse Command.
  54492. * @returns {Boolean} Tells if a command was found
  54493. */;
  54494. _proto7.parseCmd = function parseCmd(a, b) {
  54495. var cmdHistory = this.cmdHistory;
  54496. var cond1 = (a === 0x14 || a === 0x1c || a === 0x15 || a === 0x1d) && b >= 0x20 && b <= 0x2f;
  54497. var cond2 = (a === 0x17 || a === 0x1f) && b >= 0x21 && b <= 0x23;
  54498. if (!(cond1 || cond2)) {
  54499. return false;
  54500. }
  54501. if (hasCmdRepeated(a, b, cmdHistory)) {
  54502. setLastCmd(null, null, cmdHistory);
  54503. this.logger.log(VerboseLevel.DEBUG, 'Repeated command (' + numArrayToHexArray([a, b]) + ') is dropped');
  54504. return true;
  54505. }
  54506. var chNr = a === 0x14 || a === 0x15 || a === 0x17 ? 1 : 2;
  54507. var channel = this.channels[chNr];
  54508. if (a === 0x14 || a === 0x15 || a === 0x1c || a === 0x1d) {
  54509. if (b === 0x20) {
  54510. channel.ccRCL();
  54511. } else if (b === 0x21) {
  54512. channel.ccBS();
  54513. } else if (b === 0x22) {
  54514. channel.ccAOF();
  54515. } else if (b === 0x23) {
  54516. channel.ccAON();
  54517. } else if (b === 0x24) {
  54518. channel.ccDER();
  54519. } else if (b === 0x25) {
  54520. channel.ccRU(2);
  54521. } else if (b === 0x26) {
  54522. channel.ccRU(3);
  54523. } else if (b === 0x27) {
  54524. channel.ccRU(4);
  54525. } else if (b === 0x28) {
  54526. channel.ccFON();
  54527. } else if (b === 0x29) {
  54528. channel.ccRDC();
  54529. } else if (b === 0x2a) {
  54530. channel.ccTR();
  54531. } else if (b === 0x2b) {
  54532. channel.ccRTD();
  54533. } else if (b === 0x2c) {
  54534. channel.ccEDM();
  54535. } else if (b === 0x2d) {
  54536. channel.ccCR();
  54537. } else if (b === 0x2e) {
  54538. channel.ccENM();
  54539. } else if (b === 0x2f) {
  54540. channel.ccEOC();
  54541. }
  54542. } else {
  54543. // a == 0x17 || a == 0x1F
  54544. channel.ccTO(b - 0x20);
  54545. }
  54546. setLastCmd(a, b, cmdHistory);
  54547. this.currentChannel = chNr;
  54548. return true;
  54549. }
  54550. /**
  54551. * Parse midrow styling command
  54552. * @returns {Boolean}
  54553. */;
  54554. _proto7.parseMidrow = function parseMidrow(a, b) {
  54555. var chNr = 0;
  54556. if ((a === 0x11 || a === 0x19) && b >= 0x20 && b <= 0x2f) {
  54557. if (a === 0x11) {
  54558. chNr = 1;
  54559. } else {
  54560. chNr = 2;
  54561. }
  54562. if (chNr !== this.currentChannel) {
  54563. this.logger.log(VerboseLevel.ERROR, 'Mismatch channel in midrow parsing');
  54564. return false;
  54565. }
  54566. var channel = this.channels[chNr];
  54567. if (!channel) {
  54568. return false;
  54569. }
  54570. channel.ccMIDROW(b);
  54571. this.logger.log(VerboseLevel.DEBUG, 'MIDROW (' + numArrayToHexArray([a, b]) + ')');
  54572. return true;
  54573. }
  54574. return false;
  54575. }
  54576. /**
  54577. * Parse Preable Access Codes (Table 53).
  54578. * @returns {Boolean} Tells if PAC found
  54579. */;
  54580. _proto7.parsePAC = function parsePAC(a, b) {
  54581. var row;
  54582. var cmdHistory = this.cmdHistory;
  54583. var case1 = (a >= 0x11 && a <= 0x17 || a >= 0x19 && a <= 0x1f) && b >= 0x40 && b <= 0x7f;
  54584. var case2 = (a === 0x10 || a === 0x18) && b >= 0x40 && b <= 0x5f;
  54585. if (!(case1 || case2)) {
  54586. return false;
  54587. }
  54588. if (hasCmdRepeated(a, b, cmdHistory)) {
  54589. setLastCmd(null, null, cmdHistory);
  54590. return true; // Repeated commands are dropped (once)
  54591. }
  54592. var chNr = a <= 0x17 ? 1 : 2;
  54593. if (b >= 0x40 && b <= 0x5f) {
  54594. row = chNr === 1 ? rowsLowCh1[a] : rowsLowCh2[a];
  54595. } else {
  54596. // 0x60 <= b <= 0x7F
  54597. row = chNr === 1 ? rowsHighCh1[a] : rowsHighCh2[a];
  54598. }
  54599. var channel = this.channels[chNr];
  54600. if (!channel) {
  54601. return false;
  54602. }
  54603. channel.setPAC(this.interpretPAC(row, b));
  54604. setLastCmd(a, b, cmdHistory);
  54605. this.currentChannel = chNr;
  54606. return true;
  54607. }
  54608. /**
  54609. * Interpret the second byte of the pac, and return the information.
  54610. * @returns {Object} pacData with style parameters.
  54611. */;
  54612. _proto7.interpretPAC = function interpretPAC(row, _byte3) {
  54613. var pacIndex;
  54614. var pacData = {
  54615. color: null,
  54616. italics: false,
  54617. indent: null,
  54618. underline: false,
  54619. row: row
  54620. };
  54621. if (_byte3 > 0x5f) {
  54622. pacIndex = _byte3 - 0x60;
  54623. } else {
  54624. pacIndex = _byte3 - 0x40;
  54625. }
  54626. pacData.underline = (pacIndex & 1) === 1;
  54627. if (pacIndex <= 0xd) {
  54628. pacData.color = ['white', 'green', 'blue', 'cyan', 'red', 'yellow', 'magenta', 'white'][Math.floor(pacIndex / 2)];
  54629. } else if (pacIndex <= 0xf) {
  54630. pacData.italics = true;
  54631. pacData.color = 'white';
  54632. } else {
  54633. pacData.indent = Math.floor((pacIndex - 0x10) / 2) * 4;
  54634. }
  54635. return pacData; // Note that row has zero offset. The spec uses 1.
  54636. }
  54637. /**
  54638. * Parse characters.
  54639. * @returns An array with 1 to 2 codes corresponding to chars, if found. null otherwise.
  54640. */;
  54641. _proto7.parseChars = function parseChars(a, b) {
  54642. var channelNr;
  54643. var charCodes = null;
  54644. var charCode1 = null;
  54645. if (a >= 0x19) {
  54646. channelNr = 2;
  54647. charCode1 = a - 8;
  54648. } else {
  54649. channelNr = 1;
  54650. charCode1 = a;
  54651. }
  54652. if (charCode1 >= 0x11 && charCode1 <= 0x13) {
  54653. // Special character
  54654. var oneCode;
  54655. if (charCode1 === 0x11) {
  54656. oneCode = b + 0x50;
  54657. } else if (charCode1 === 0x12) {
  54658. oneCode = b + 0x70;
  54659. } else {
  54660. oneCode = b + 0x90;
  54661. }
  54662. this.logger.log(VerboseLevel.INFO, "Special char '" + getCharForByte(oneCode) + "' in channel " + channelNr);
  54663. charCodes = [oneCode];
  54664. } else if (a >= 0x20 && a <= 0x7f) {
  54665. charCodes = b === 0 ? [a] : [a, b];
  54666. }
  54667. if (charCodes) {
  54668. var hexCodes = numArrayToHexArray(charCodes);
  54669. this.logger.log(VerboseLevel.DEBUG, 'Char codes = ' + hexCodes.join(','));
  54670. setLastCmd(a, b, this.cmdHistory);
  54671. }
  54672. return charCodes;
  54673. }
  54674. /**
  54675. * Parse extended background attributes as well as new foreground color black.
  54676. * @returns {Boolean} Tells if background attributes are found
  54677. */;
  54678. _proto7.parseBackgroundAttributes = function parseBackgroundAttributes(a, b) {
  54679. var case1 = (a === 0x10 || a === 0x18) && b >= 0x20 && b <= 0x2f;
  54680. var case2 = (a === 0x17 || a === 0x1f) && b >= 0x2d && b <= 0x2f;
  54681. if (!(case1 || case2)) {
  54682. return false;
  54683. }
  54684. var index;
  54685. var bkgData = {};
  54686. if (a === 0x10 || a === 0x18) {
  54687. index = Math.floor((b - 0x20) / 2);
  54688. bkgData.background = backgroundColors[index];
  54689. if (b % 2 === 1) {
  54690. bkgData.background = bkgData.background + '_semi';
  54691. }
  54692. } else if (b === 0x2d) {
  54693. bkgData.background = 'transparent';
  54694. } else {
  54695. bkgData.foreground = 'black';
  54696. if (b === 0x2f) {
  54697. bkgData.underline = true;
  54698. }
  54699. }
  54700. var chNr = a <= 0x17 ? 1 : 2;
  54701. var channel = this.channels[chNr];
  54702. channel.setBkgData(bkgData);
  54703. setLastCmd(a, b, this.cmdHistory);
  54704. return true;
  54705. }
  54706. /**
  54707. * Reset state of parser and its channels.
  54708. */;
  54709. _proto7.reset = function reset() {
  54710. for (var i = 0; i < Object.keys(this.channels).length; i++) {
  54711. var channel = this.channels[i];
  54712. if (channel) {
  54713. channel.reset();
  54714. }
  54715. }
  54716. this.cmdHistory = createCmdHistory();
  54717. }
  54718. /**
  54719. * Trigger the generation of a cue, and the start of a new one if displayScreens are not empty.
  54720. */;
  54721. _proto7.cueSplitAtTime = function cueSplitAtTime(t) {
  54722. for (var i = 0; i < this.channels.length; i++) {
  54723. var channel = this.channels[i];
  54724. if (channel) {
  54725. channel.cueSplitAtTime(t);
  54726. }
  54727. }
  54728. };
  54729. return Cea608Parser;
  54730. }();
  54731. function setLastCmd(a, b, cmdHistory) {
  54732. cmdHistory.a = a;
  54733. cmdHistory.b = b;
  54734. }
  54735. function hasCmdRepeated(a, b, cmdHistory) {
  54736. return cmdHistory.a === a && cmdHistory.b === b;
  54737. }
  54738. function createCmdHistory() {
  54739. return {
  54740. a: null,
  54741. b: null
  54742. };
  54743. }
  54744. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Cea608Parser);
  54745. /***/ }),
  54746. /***/ "./src/utils/codecs.ts":
  54747. /*!*****************************!*\
  54748. !*** ./src/utils/codecs.ts ***!
  54749. \*****************************/
  54750. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  54751. "use strict";
  54752. __webpack_require__.r(__webpack_exports__);
  54753. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  54754. /* harmony export */ "isCodecSupportedInMp4": () => (/* binding */ isCodecSupportedInMp4),
  54755. /* harmony export */ "isCodecType": () => (/* binding */ isCodecType)
  54756. /* harmony export */ });
  54757. // from http://mp4ra.org/codecs.html
  54758. var sampleEntryCodesISO = {
  54759. audio: {
  54760. a3ds: true,
  54761. 'ac-3': true,
  54762. 'ac-4': true,
  54763. alac: true,
  54764. alaw: true,
  54765. dra1: true,
  54766. 'dts+': true,
  54767. 'dts-': true,
  54768. dtsc: true,
  54769. dtse: true,
  54770. dtsh: true,
  54771. 'ec-3': true,
  54772. enca: true,
  54773. g719: true,
  54774. g726: true,
  54775. m4ae: true,
  54776. mha1: true,
  54777. mha2: true,
  54778. mhm1: true,
  54779. mhm2: true,
  54780. mlpa: true,
  54781. mp4a: true,
  54782. 'raw ': true,
  54783. Opus: true,
  54784. opus: true,
  54785. // browsers expect this to be lowercase despite MP4RA says 'Opus'
  54786. samr: true,
  54787. sawb: true,
  54788. sawp: true,
  54789. sevc: true,
  54790. sqcp: true,
  54791. ssmv: true,
  54792. twos: true,
  54793. ulaw: true
  54794. },
  54795. video: {
  54796. avc1: true,
  54797. avc2: true,
  54798. avc3: true,
  54799. avc4: true,
  54800. avcp: true,
  54801. av01: true,
  54802. drac: true,
  54803. dva1: true,
  54804. dvav: true,
  54805. dvh1: true,
  54806. dvhe: true,
  54807. encv: true,
  54808. hev1: true,
  54809. hvc1: true,
  54810. mjp2: true,
  54811. mp4v: true,
  54812. mvc1: true,
  54813. mvc2: true,
  54814. mvc3: true,
  54815. mvc4: true,
  54816. resv: true,
  54817. rv60: true,
  54818. s263: true,
  54819. svc1: true,
  54820. svc2: true,
  54821. 'vc-1': true,
  54822. vp08: true,
  54823. vp09: true
  54824. },
  54825. text: {
  54826. stpp: true,
  54827. wvtt: true
  54828. }
  54829. };
  54830. function isCodecType(codec, type) {
  54831. var typeCodes = sampleEntryCodesISO[type];
  54832. return !!typeCodes && typeCodes[codec.slice(0, 4)] === true;
  54833. }
  54834. function isCodecSupportedInMp4(codec, type) {
  54835. return MediaSource.isTypeSupported((type || 'video') + "/mp4;codecs=\"" + codec + "\"");
  54836. }
  54837. /***/ }),
  54838. /***/ "./src/utils/cues.ts":
  54839. /*!***************************!*\
  54840. !*** ./src/utils/cues.ts ***!
  54841. \***************************/
  54842. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  54843. "use strict";
  54844. __webpack_require__.r(__webpack_exports__);
  54845. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  54846. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  54847. /* harmony export */ });
  54848. /* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts");
  54849. /* harmony import */ var _webvtt_parser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./webvtt-parser */ "./src/utils/webvtt-parser.ts");
  54850. /* harmony import */ var _texttrack_utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./texttrack-utils */ "./src/utils/texttrack-utils.ts");
  54851. var WHITESPACE_CHAR = /\s/;
  54852. var Cues = {
  54853. newCue: function newCue(track, startTime, endTime, captionScreen) {
  54854. var result = [];
  54855. var row;
  54856. // the type data states this is VTTCue, but it can potentially be a TextTrackCue on old browsers
  54857. var cue;
  54858. var indenting;
  54859. var indent;
  54860. var text;
  54861. var Cue = self.VTTCue || self.TextTrackCue;
  54862. for (var r = 0; r < captionScreen.rows.length; r++) {
  54863. row = captionScreen.rows[r];
  54864. indenting = true;
  54865. indent = 0;
  54866. text = '';
  54867. if (!row.isEmpty()) {
  54868. for (var c = 0; c < row.chars.length; c++) {
  54869. if (WHITESPACE_CHAR.test(row.chars[c].uchar) && indenting) {
  54870. indent++;
  54871. } else {
  54872. text += row.chars[c].uchar;
  54873. indenting = false;
  54874. }
  54875. }
  54876. // To be used for cleaning-up orphaned roll-up captions
  54877. row.cueStartTime = startTime;
  54878. // Give a slight bump to the endTime if it's equal to startTime to avoid a SyntaxError in IE
  54879. if (startTime === endTime) {
  54880. endTime += 0.0001;
  54881. }
  54882. if (indent >= 16) {
  54883. indent--;
  54884. } else {
  54885. indent++;
  54886. }
  54887. var cueText = (0,_vttparser__WEBPACK_IMPORTED_MODULE_0__.fixLineBreaks)(text.trim());
  54888. var id = (0,_webvtt_parser__WEBPACK_IMPORTED_MODULE_1__.generateCueId)(startTime, endTime, cueText);
  54889. // If this cue already exists in the track do not push it
  54890. if (!track || !track.cues || !track.cues.getCueById(id)) {
  54891. cue = new Cue(startTime, endTime, cueText);
  54892. cue.id = id;
  54893. cue.line = r + 1;
  54894. cue.align = 'left';
  54895. // Clamp the position between 10 and 80 percent (CEA-608 PAC indent code)
  54896. // https://dvcs.w3.org/hg/text-tracks/raw-file/default/608toVTT/608toVTT.html#positioning-in-cea-608
  54897. // Firefox throws an exception and captions break with out of bounds 0-100 values
  54898. cue.position = 10 + Math.min(80, Math.floor(indent * 8 / 32) * 10);
  54899. result.push(cue);
  54900. }
  54901. }
  54902. }
  54903. if (track && result.length) {
  54904. // Sort bottom cues in reverse order so that they render in line order when overlapping in Chrome
  54905. result.sort(function (cueA, cueB) {
  54906. if (cueA.line === 'auto' || cueB.line === 'auto') {
  54907. return 0;
  54908. }
  54909. if (cueA.line > 8 && cueB.line > 8) {
  54910. return cueB.line - cueA.line;
  54911. }
  54912. return cueA.line - cueB.line;
  54913. });
  54914. result.forEach(function (cue) {
  54915. return (0,_texttrack_utils__WEBPACK_IMPORTED_MODULE_2__.addCueToTrack)(track, cue);
  54916. });
  54917. }
  54918. return result;
  54919. }
  54920. };
  54921. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Cues);
  54922. /***/ }),
  54923. /***/ "./src/utils/discontinuities.ts":
  54924. /*!**************************************!*\
  54925. !*** ./src/utils/discontinuities.ts ***!
  54926. \**************************************/
  54927. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  54928. "use strict";
  54929. __webpack_require__.r(__webpack_exports__);
  54930. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  54931. /* harmony export */ "adjustSlidingStart": () => (/* binding */ adjustSlidingStart),
  54932. /* harmony export */ "alignMediaPlaylistByPDT": () => (/* binding */ alignMediaPlaylistByPDT),
  54933. /* harmony export */ "alignPDT": () => (/* binding */ alignPDT),
  54934. /* harmony export */ "alignStream": () => (/* binding */ alignStream),
  54935. /* harmony export */ "findDiscontinuousReferenceFrag": () => (/* binding */ findDiscontinuousReferenceFrag),
  54936. /* harmony export */ "findFirstFragWithCC": () => (/* binding */ findFirstFragWithCC),
  54937. /* harmony export */ "shouldAlignOnDiscontinuities": () => (/* binding */ shouldAlignOnDiscontinuities)
  54938. /* harmony export */ });
  54939. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  54940. /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts");
  54941. /* harmony import */ var _controller_level_helper__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../controller/level-helper */ "./src/controller/level-helper.ts");
  54942. function findFirstFragWithCC(fragments, cc) {
  54943. var firstFrag = null;
  54944. for (var i = 0, len = fragments.length; i < len; i++) {
  54945. var currentFrag = fragments[i];
  54946. if (currentFrag && currentFrag.cc === cc) {
  54947. firstFrag = currentFrag;
  54948. break;
  54949. }
  54950. }
  54951. return firstFrag;
  54952. }
  54953. function shouldAlignOnDiscontinuities(lastFrag, lastLevel, details) {
  54954. if (lastLevel.details) {
  54955. if (details.endCC > details.startCC || lastFrag && lastFrag.cc < details.startCC) {
  54956. return true;
  54957. }
  54958. }
  54959. return false;
  54960. }
  54961. // Find the first frag in the previous level which matches the CC of the first frag of the new level
  54962. function findDiscontinuousReferenceFrag(prevDetails, curDetails, referenceIndex) {
  54963. if (referenceIndex === void 0) {
  54964. referenceIndex = 0;
  54965. }
  54966. var prevFrags = prevDetails.fragments;
  54967. var curFrags = curDetails.fragments;
  54968. if (!curFrags.length || !prevFrags.length) {
  54969. _logger__WEBPACK_IMPORTED_MODULE_1__.logger.log('No fragments to align');
  54970. return;
  54971. }
  54972. var prevStartFrag = findFirstFragWithCC(prevFrags, curFrags[0].cc);
  54973. if (!prevStartFrag || prevStartFrag && !prevStartFrag.startPTS) {
  54974. _logger__WEBPACK_IMPORTED_MODULE_1__.logger.log('No frag in previous level to align on');
  54975. return;
  54976. }
  54977. return prevStartFrag;
  54978. }
  54979. function adjustFragmentStart(frag, sliding) {
  54980. if (frag) {
  54981. var start = frag.start + sliding;
  54982. frag.start = frag.startPTS = start;
  54983. frag.endPTS = start + frag.duration;
  54984. }
  54985. }
  54986. function adjustSlidingStart(sliding, details) {
  54987. // Update segments
  54988. var fragments = details.fragments;
  54989. for (var i = 0, len = fragments.length; i < len; i++) {
  54990. adjustFragmentStart(fragments[i], sliding);
  54991. }
  54992. // Update LL-HLS parts at the end of the playlist
  54993. if (details.fragmentHint) {
  54994. adjustFragmentStart(details.fragmentHint, sliding);
  54995. }
  54996. details.alignedSliding = true;
  54997. }
  54998. /**
  54999. * Using the parameters of the last level, this function computes PTS' of the new fragments so that they form a
  55000. * contiguous stream with the last fragments.
  55001. * The PTS of a fragment lets Hls.js know where it fits into a stream - by knowing every PTS, we know which fragment to
  55002. * download at any given time. PTS is normally computed when the fragment is demuxed, so taking this step saves us time
  55003. * and an extra download.
  55004. * @param lastFrag
  55005. * @param lastLevel
  55006. * @param details
  55007. */
  55008. function alignStream(lastFrag, lastLevel, details) {
  55009. if (!lastLevel) {
  55010. return;
  55011. }
  55012. alignDiscontinuities(lastFrag, details, lastLevel);
  55013. if (!details.alignedSliding && lastLevel.details) {
  55014. // If the PTS wasn't figured out via discontinuity sequence that means there was no CC increase within the level.
  55015. // Aligning via Program Date Time should therefore be reliable, since PDT should be the same within the same
  55016. // discontinuity sequence.
  55017. alignPDT(details, lastLevel.details);
  55018. }
  55019. if (!details.alignedSliding && lastLevel.details && !details.skippedSegments) {
  55020. // Try to align on sn so that we pick a better start fragment.
  55021. // Do not perform this on playlists with delta updates as this is only to align levels on switch
  55022. // and adjustSliding only adjusts fragments after skippedSegments.
  55023. (0,_controller_level_helper__WEBPACK_IMPORTED_MODULE_2__.adjustSliding)(lastLevel.details, details);
  55024. }
  55025. }
  55026. /**
  55027. * Computes the PTS if a new level's fragments using the PTS of a fragment in the last level which shares the same
  55028. * discontinuity sequence.
  55029. * @param lastFrag - The last Fragment which shares the same discontinuity sequence
  55030. * @param lastLevel - The details of the last loaded level
  55031. * @param details - The details of the new level
  55032. */
  55033. function alignDiscontinuities(lastFrag, details, lastLevel) {
  55034. if (shouldAlignOnDiscontinuities(lastFrag, lastLevel, details)) {
  55035. var referenceFrag = findDiscontinuousReferenceFrag(lastLevel.details, details);
  55036. if (referenceFrag && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(referenceFrag.start)) {
  55037. _logger__WEBPACK_IMPORTED_MODULE_1__.logger.log("Adjusting PTS using last level due to CC increase within current level " + details.url);
  55038. adjustSlidingStart(referenceFrag.start, details);
  55039. }
  55040. }
  55041. }
  55042. /**
  55043. * Computes the PTS of a new level's fragments using the difference in Program Date Time from the last level.
  55044. * @param details - The details of the new level
  55045. * @param lastDetails - The details of the last loaded level
  55046. */
  55047. function alignPDT(details, lastDetails) {
  55048. // This check protects the unsafe "!" usage below for null program date time access.
  55049. if (!lastDetails.fragments.length || !details.hasProgramDateTime || !lastDetails.hasProgramDateTime) {
  55050. return;
  55051. }
  55052. // if last level sliding is 1000 and its first frag PROGRAM-DATE-TIME is 2017-08-20 1:10:00 AM
  55053. // and if new details first frag PROGRAM DATE-TIME is 2017-08-20 1:10:08 AM
  55054. // then we can deduce that playlist B sliding is 1000+8 = 1008s
  55055. var lastPDT = lastDetails.fragments[0].programDateTime; // hasProgramDateTime check above makes this safe.
  55056. var newPDT = details.fragments[0].programDateTime;
  55057. // date diff is in ms. frag.start is in seconds
  55058. var sliding = (newPDT - lastPDT) / 1000 + lastDetails.fragments[0].start;
  55059. if (sliding && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(sliding)) {
  55060. _logger__WEBPACK_IMPORTED_MODULE_1__.logger.log("Adjusting PTS using programDateTime delta " + (newPDT - lastPDT) + "ms, sliding:" + sliding.toFixed(3) + " " + details.url + " ");
  55061. adjustSlidingStart(sliding, details);
  55062. }
  55063. }
  55064. /**
  55065. * Ensures appropriate time-alignment between renditions based on PDT. Unlike `alignPDT`, which adjusts
  55066. * the timeline based on the delta between PDTs of the 0th fragment of two playlists/`LevelDetails`,
  55067. * this function assumes the timelines represented in `refDetails` are accurate, including the PDTs,
  55068. * and uses the "wallclock"/PDT timeline as a cross-reference to `details`, adjusting the presentation
  55069. * times/timelines of `details` accordingly.
  55070. * Given the asynchronous nature of fetches and initial loads of live `main` and audio/subtitle tracks,
  55071. * the primary purpose of this function is to ensure the "local timelines" of audio/subtitle tracks
  55072. * are aligned to the main/video timeline, using PDT as the cross-reference/"anchor" that should
  55073. * be consistent across playlists, per the HLS spec.
  55074. * @param details - The details of the rendition you'd like to time-align (e.g. an audio rendition).
  55075. * @param refDetails - The details of the reference rendition with start and PDT times for alignment.
  55076. */
  55077. function alignMediaPlaylistByPDT(details, refDetails) {
  55078. if (!details.hasProgramDateTime || !refDetails.hasProgramDateTime) {
  55079. return;
  55080. }
  55081. var fragments = details.fragments;
  55082. var refFragments = refDetails.fragments;
  55083. if (!fragments.length || !refFragments.length) {
  55084. return;
  55085. }
  55086. // Calculate a delta to apply to all fragments according to the delta in PDT times and start times
  55087. // of a fragment in the reference details, and a fragment in the target details of the same discontinuity.
  55088. // If a fragment of the same discontinuity was not found use the middle fragment of both.
  55089. var middleFrag = Math.round(refFragments.length / 2) - 1;
  55090. var refFrag = refFragments[middleFrag];
  55091. var frag = findFirstFragWithCC(fragments, refFrag.cc) || fragments[Math.round(fragments.length / 2) - 1];
  55092. var refPDT = refFrag.programDateTime;
  55093. var targetPDT = frag.programDateTime;
  55094. if (refPDT === null || targetPDT === null) {
  55095. return;
  55096. }
  55097. var delta = (targetPDT - refPDT) / 1000 - (frag.start - refFrag.start);
  55098. adjustSlidingStart(delta, details);
  55099. }
  55100. /***/ }),
  55101. /***/ "./src/utils/ewma-bandwidth-estimator.ts":
  55102. /*!***********************************************!*\
  55103. !*** ./src/utils/ewma-bandwidth-estimator.ts ***!
  55104. \***********************************************/
  55105. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55106. "use strict";
  55107. __webpack_require__.r(__webpack_exports__);
  55108. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55109. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  55110. /* harmony export */ });
  55111. /* harmony import */ var _utils_ewma__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/ewma */ "./src/utils/ewma.ts");
  55112. /*
  55113. * EWMA Bandwidth Estimator
  55114. * - heavily inspired from shaka-player
  55115. * Tracks bandwidth samples and estimates available bandwidth.
  55116. * Based on the minimum of two exponentially-weighted moving averages with
  55117. * different half-lives.
  55118. */
  55119. var EwmaBandWidthEstimator = /*#__PURE__*/function () {
  55120. function EwmaBandWidthEstimator(slow, fast, defaultEstimate) {
  55121. this.defaultEstimate_ = void 0;
  55122. this.minWeight_ = void 0;
  55123. this.minDelayMs_ = void 0;
  55124. this.slow_ = void 0;
  55125. this.fast_ = void 0;
  55126. this.defaultEstimate_ = defaultEstimate;
  55127. this.minWeight_ = 0.001;
  55128. this.minDelayMs_ = 50;
  55129. this.slow_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow);
  55130. this.fast_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast);
  55131. }
  55132. var _proto = EwmaBandWidthEstimator.prototype;
  55133. _proto.update = function update(slow, fast) {
  55134. var slow_ = this.slow_,
  55135. fast_ = this.fast_;
  55136. if (this.slow_.halfLife !== slow) {
  55137. this.slow_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](slow, slow_.getEstimate(), slow_.getTotalWeight());
  55138. }
  55139. if (this.fast_.halfLife !== fast) {
  55140. this.fast_ = new _utils_ewma__WEBPACK_IMPORTED_MODULE_0__["default"](fast, fast_.getEstimate(), fast_.getTotalWeight());
  55141. }
  55142. };
  55143. _proto.sample = function sample(durationMs, numBytes) {
  55144. durationMs = Math.max(durationMs, this.minDelayMs_);
  55145. var numBits = 8 * numBytes;
  55146. // weight is duration in seconds
  55147. var durationS = durationMs / 1000;
  55148. // value is bandwidth in bits/s
  55149. var bandwidthInBps = numBits / durationS;
  55150. this.fast_.sample(durationS, bandwidthInBps);
  55151. this.slow_.sample(durationS, bandwidthInBps);
  55152. };
  55153. _proto.canEstimate = function canEstimate() {
  55154. var fast = this.fast_;
  55155. return fast && fast.getTotalWeight() >= this.minWeight_;
  55156. };
  55157. _proto.getEstimate = function getEstimate() {
  55158. if (this.canEstimate()) {
  55159. // console.log('slow estimate:'+ Math.round(this.slow_.getEstimate()));
  55160. // console.log('fast estimate:'+ Math.round(this.fast_.getEstimate()));
  55161. // Take the minimum of these two estimates. This should have the effect of
  55162. // adapting down quickly, but up more slowly.
  55163. return Math.min(this.fast_.getEstimate(), this.slow_.getEstimate());
  55164. } else {
  55165. return this.defaultEstimate_;
  55166. }
  55167. };
  55168. _proto.destroy = function destroy() {};
  55169. return EwmaBandWidthEstimator;
  55170. }();
  55171. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EwmaBandWidthEstimator);
  55172. /***/ }),
  55173. /***/ "./src/utils/ewma.ts":
  55174. /*!***************************!*\
  55175. !*** ./src/utils/ewma.ts ***!
  55176. \***************************/
  55177. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55178. "use strict";
  55179. __webpack_require__.r(__webpack_exports__);
  55180. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55181. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  55182. /* harmony export */ });
  55183. /*
  55184. * compute an Exponential Weighted moving average
  55185. * - https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
  55186. * - heavily inspired from shaka-player
  55187. */
  55188. var EWMA = /*#__PURE__*/function () {
  55189. // About half of the estimated value will be from the last |halfLife| samples by weight.
  55190. function EWMA(halfLife, estimate, weight) {
  55191. if (estimate === void 0) {
  55192. estimate = 0;
  55193. }
  55194. if (weight === void 0) {
  55195. weight = 0;
  55196. }
  55197. this.halfLife = void 0;
  55198. this.alpha_ = void 0;
  55199. this.estimate_ = void 0;
  55200. this.totalWeight_ = void 0;
  55201. this.halfLife = halfLife;
  55202. // Larger values of alpha expire historical data more slowly.
  55203. this.alpha_ = halfLife ? Math.exp(Math.log(0.5) / halfLife) : 0;
  55204. this.estimate_ = estimate;
  55205. this.totalWeight_ = weight;
  55206. }
  55207. var _proto = EWMA.prototype;
  55208. _proto.sample = function sample(weight, value) {
  55209. var adjAlpha = Math.pow(this.alpha_, weight);
  55210. this.estimate_ = value * (1 - adjAlpha) + adjAlpha * this.estimate_;
  55211. this.totalWeight_ += weight;
  55212. };
  55213. _proto.getTotalWeight = function getTotalWeight() {
  55214. return this.totalWeight_;
  55215. };
  55216. _proto.getEstimate = function getEstimate() {
  55217. if (this.alpha_) {
  55218. var zeroFactor = 1 - Math.pow(this.alpha_, this.totalWeight_);
  55219. if (zeroFactor) {
  55220. return this.estimate_ / zeroFactor;
  55221. }
  55222. }
  55223. return this.estimate_;
  55224. };
  55225. return EWMA;
  55226. }();
  55227. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (EWMA);
  55228. /***/ }),
  55229. /***/ "./src/utils/fetch-loader.ts":
  55230. /*!***********************************!*\
  55231. !*** ./src/utils/fetch-loader.ts ***!
  55232. \***********************************/
  55233. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55234. "use strict";
  55235. __webpack_require__.r(__webpack_exports__);
  55236. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55237. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__),
  55238. /* harmony export */ "fetchSupported": () => (/* binding */ fetchSupported)
  55239. /* harmony export */ });
  55240. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  55241. /* harmony import */ var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/load-stats */ "./src/loader/load-stats.ts");
  55242. /* harmony import */ var _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/chunk-cache */ "./src/demux/chunk-cache.ts");
  55243. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; _setPrototypeOf(subClass, superClass); }
  55244. function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); }
  55245. function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); }
  55246. function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
  55247. function _isNativeFunction(fn) { return Function.toString.call(fn).indexOf("[native code]") !== -1; }
  55248. function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
  55249. function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
  55250. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  55251. function fetchSupported() {
  55252. if (
  55253. // @ts-ignore
  55254. self.fetch && self.AbortController && self.ReadableStream && self.Request) {
  55255. try {
  55256. new self.ReadableStream({}); // eslint-disable-line no-new
  55257. return true;
  55258. } catch (e) {
  55259. /* noop */
  55260. }
  55261. }
  55262. return false;
  55263. }
  55264. var FetchLoader = /*#__PURE__*/function () {
  55265. function FetchLoader(config /* HlsConfig */) {
  55266. this.fetchSetup = void 0;
  55267. this.requestTimeout = void 0;
  55268. this.request = void 0;
  55269. this.response = void 0;
  55270. this.controller = void 0;
  55271. this.context = void 0;
  55272. this.config = null;
  55273. this.callbacks = null;
  55274. this.stats = void 0;
  55275. this.loader = null;
  55276. this.fetchSetup = config.fetchSetup || getRequest;
  55277. this.controller = new self.AbortController();
  55278. this.stats = new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__.LoadStats();
  55279. }
  55280. var _proto = FetchLoader.prototype;
  55281. _proto.destroy = function destroy() {
  55282. this.loader = this.callbacks = null;
  55283. this.abortInternal();
  55284. };
  55285. _proto.abortInternal = function abortInternal() {
  55286. var response = this.response;
  55287. if (!response || !response.ok) {
  55288. this.stats.aborted = true;
  55289. this.controller.abort();
  55290. }
  55291. };
  55292. _proto.abort = function abort() {
  55293. var _this$callbacks;
  55294. this.abortInternal();
  55295. if ((_this$callbacks = this.callbacks) !== null && _this$callbacks !== void 0 && _this$callbacks.onAbort) {
  55296. this.callbacks.onAbort(this.stats, this.context, this.response);
  55297. }
  55298. };
  55299. _proto.load = function load(context, config, callbacks) {
  55300. var _this = this;
  55301. var stats = this.stats;
  55302. if (stats.loading.start) {
  55303. throw new Error('Loader can only be used once.');
  55304. }
  55305. stats.loading.start = self.performance.now();
  55306. var initParams = getRequestParameters(context, this.controller.signal);
  55307. var onProgress = callbacks.onProgress;
  55308. var isArrayBuffer = context.responseType === 'arraybuffer';
  55309. var LENGTH = isArrayBuffer ? 'byteLength' : 'length';
  55310. this.context = context;
  55311. this.config = config;
  55312. this.callbacks = callbacks;
  55313. this.request = this.fetchSetup(context, initParams);
  55314. self.clearTimeout(this.requestTimeout);
  55315. this.requestTimeout = self.setTimeout(function () {
  55316. _this.abortInternal();
  55317. callbacks.onTimeout(stats, context, _this.response);
  55318. }, config.timeout);
  55319. self.fetch(this.request).then(function (response) {
  55320. _this.response = _this.loader = response;
  55321. if (!response.ok) {
  55322. var status = response.status,
  55323. statusText = response.statusText;
  55324. throw new FetchError(statusText || 'fetch, bad network response', status, response);
  55325. }
  55326. stats.loading.first = Math.max(self.performance.now(), stats.loading.start);
  55327. stats.total = parseInt(response.headers.get('Content-Length') || '0');
  55328. if (onProgress && (0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(config.highWaterMark)) {
  55329. return _this.loadProgressively(response, stats, context, config.highWaterMark, onProgress);
  55330. }
  55331. if (isArrayBuffer) {
  55332. return response.arrayBuffer();
  55333. }
  55334. return response.text();
  55335. }).then(function (responseData) {
  55336. var response = _this.response;
  55337. self.clearTimeout(_this.requestTimeout);
  55338. stats.loading.end = Math.max(self.performance.now(), stats.loading.first);
  55339. var total = responseData[LENGTH];
  55340. if (total) {
  55341. stats.loaded = stats.total = total;
  55342. }
  55343. var loaderResponse = {
  55344. url: response.url,
  55345. data: responseData
  55346. };
  55347. if (onProgress && !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(config.highWaterMark)) {
  55348. onProgress(stats, context, responseData, response);
  55349. }
  55350. callbacks.onSuccess(loaderResponse, stats, context, response);
  55351. }).catch(function (error) {
  55352. self.clearTimeout(_this.requestTimeout);
  55353. if (stats.aborted) {
  55354. return;
  55355. }
  55356. // CORS errors result in an undefined code. Set it to 0 here to align with XHR's behavior
  55357. // when destroying, 'error' itself can be undefined
  55358. var code = !error ? 0 : error.code || 0;
  55359. var text = !error ? null : error.message;
  55360. callbacks.onError({
  55361. code: code,
  55362. text: text
  55363. }, context, error ? error.details : null);
  55364. });
  55365. };
  55366. _proto.getCacheAge = function getCacheAge() {
  55367. var result = null;
  55368. if (this.response) {
  55369. var ageHeader = this.response.headers.get('age');
  55370. result = ageHeader ? parseFloat(ageHeader) : null;
  55371. }
  55372. return result;
  55373. };
  55374. _proto.loadProgressively = function loadProgressively(response, stats, context, highWaterMark, onProgress) {
  55375. if (highWaterMark === void 0) {
  55376. highWaterMark = 0;
  55377. }
  55378. var chunkCache = new _demux_chunk_cache__WEBPACK_IMPORTED_MODULE_2__["default"]();
  55379. var reader = response.body.getReader();
  55380. var pump = function pump() {
  55381. return reader.read().then(function (data) {
  55382. if (data.done) {
  55383. if (chunkCache.dataLength) {
  55384. onProgress(stats, context, chunkCache.flush(), response);
  55385. }
  55386. return Promise.resolve(new ArrayBuffer(0));
  55387. }
  55388. var chunk = data.value;
  55389. var len = chunk.length;
  55390. stats.loaded += len;
  55391. if (len < highWaterMark || chunkCache.dataLength) {
  55392. // The current chunk is too small to to be emitted or the cache already has data
  55393. // Push it to the cache
  55394. chunkCache.push(chunk);
  55395. if (chunkCache.dataLength >= highWaterMark) {
  55396. // flush in order to join the typed arrays
  55397. onProgress(stats, context, chunkCache.flush(), response);
  55398. }
  55399. } else {
  55400. // If there's nothing cached already, and the chache is large enough
  55401. // just emit the progress event
  55402. onProgress(stats, context, chunk, response);
  55403. }
  55404. return pump();
  55405. }).catch(function () {
  55406. /* aborted */
  55407. return Promise.reject();
  55408. });
  55409. };
  55410. return pump();
  55411. };
  55412. return FetchLoader;
  55413. }();
  55414. function getRequestParameters(context, signal) {
  55415. var initParams = {
  55416. method: 'GET',
  55417. mode: 'cors',
  55418. credentials: 'same-origin',
  55419. signal: signal,
  55420. headers: new self.Headers(_extends({}, context.headers))
  55421. };
  55422. if (context.rangeEnd) {
  55423. initParams.headers.set('Range', 'bytes=' + context.rangeStart + '-' + String(context.rangeEnd - 1));
  55424. }
  55425. return initParams;
  55426. }
  55427. function getRequest(context, initParams) {
  55428. return new self.Request(context.url, initParams);
  55429. }
  55430. var FetchError = /*#__PURE__*/function (_Error) {
  55431. _inheritsLoose(FetchError, _Error);
  55432. function FetchError(message, code, details) {
  55433. var _this2;
  55434. _this2 = _Error.call(this, message) || this;
  55435. _this2.code = void 0;
  55436. _this2.details = void 0;
  55437. _this2.code = code;
  55438. _this2.details = details;
  55439. return _this2;
  55440. }
  55441. return FetchError;
  55442. }( /*#__PURE__*/_wrapNativeSuper(Error));
  55443. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (FetchLoader);
  55444. /***/ }),
  55445. /***/ "./src/utils/hex.ts":
  55446. /*!**************************!*\
  55447. !*** ./src/utils/hex.ts ***!
  55448. \**************************/
  55449. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55450. "use strict";
  55451. __webpack_require__.r(__webpack_exports__);
  55452. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55453. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  55454. /* harmony export */ });
  55455. /**
  55456. * hex dump helper class
  55457. */
  55458. var Hex = {
  55459. hexDump: function hexDump(array) {
  55460. var str = '';
  55461. for (var i = 0; i < array.length; i++) {
  55462. var h = array[i].toString(16);
  55463. if (h.length < 2) {
  55464. h = '0' + h;
  55465. }
  55466. str += h;
  55467. }
  55468. return str;
  55469. }
  55470. };
  55471. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Hex);
  55472. /***/ }),
  55473. /***/ "./src/utils/imsc1-ttml-parser.ts":
  55474. /*!****************************************!*\
  55475. !*** ./src/utils/imsc1-ttml-parser.ts ***!
  55476. \****************************************/
  55477. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55478. "use strict";
  55479. __webpack_require__.r(__webpack_exports__);
  55480. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55481. /* harmony export */ "IMSC1_CODEC": () => (/* binding */ IMSC1_CODEC),
  55482. /* harmony export */ "parseIMSC1": () => (/* binding */ parseIMSC1)
  55483. /* harmony export */ });
  55484. /* harmony import */ var _mp4_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mp4-tools */ "./src/utils/mp4-tools.ts");
  55485. /* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts");
  55486. /* harmony import */ var _vttcue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./vttcue */ "./src/utils/vttcue.ts");
  55487. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  55488. /* harmony import */ var _timescale_conversion__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./timescale-conversion */ "./src/utils/timescale-conversion.ts");
  55489. /* harmony import */ var _webvtt_parser__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./webvtt-parser */ "./src/utils/webvtt-parser.ts");
  55490. function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
  55491. var IMSC1_CODEC = 'stpp.ttml.im1t';
  55492. // Time format: h:m:s:frames(.subframes)
  55493. var HMSF_REGEX = /^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/;
  55494. // Time format: hours, minutes, seconds, milliseconds, frames, ticks
  55495. var TIME_UNIT_REGEX = /^(\d*(?:\.\d*)?)(h|m|s|ms|f|t)$/;
  55496. var textAlignToLineAlign = {
  55497. left: 'start',
  55498. center: 'center',
  55499. right: 'end',
  55500. start: 'start',
  55501. end: 'end'
  55502. };
  55503. function parseIMSC1(payload, initPTS, timescale, callBack, errorCallBack) {
  55504. var results = (0,_mp4_tools__WEBPACK_IMPORTED_MODULE_0__.findBox)(new Uint8Array(payload), ['mdat']);
  55505. if (results.length === 0) {
  55506. errorCallBack(new Error('Could not parse IMSC1 mdat'));
  55507. return;
  55508. }
  55509. var ttmlList = results.map(function (mdat) {
  55510. return (0,_demux_id3__WEBPACK_IMPORTED_MODULE_3__.utf8ArrayToStr)(mdat);
  55511. });
  55512. var syncTime = (0,_timescale_conversion__WEBPACK_IMPORTED_MODULE_4__.toTimescaleFromScale)(initPTS, 1, timescale);
  55513. try {
  55514. ttmlList.forEach(function (ttml) {
  55515. return callBack(parseTTML(ttml, syncTime));
  55516. });
  55517. } catch (error) {
  55518. errorCallBack(error);
  55519. }
  55520. }
  55521. function parseTTML(ttml, syncTime) {
  55522. var parser = new DOMParser();
  55523. var xmlDoc = parser.parseFromString(ttml, 'text/xml');
  55524. var tt = xmlDoc.getElementsByTagName('tt')[0];
  55525. if (!tt) {
  55526. throw new Error('Invalid ttml');
  55527. }
  55528. var defaultRateInfo = {
  55529. frameRate: 30,
  55530. subFrameRate: 1,
  55531. frameRateMultiplier: 0,
  55532. tickRate: 0
  55533. };
  55534. var rateInfo = Object.keys(defaultRateInfo).reduce(function (result, key) {
  55535. result[key] = tt.getAttribute("ttp:" + key) || defaultRateInfo[key];
  55536. return result;
  55537. }, {});
  55538. var trim = tt.getAttribute('xml:space') !== 'preserve';
  55539. var styleElements = collectionToDictionary(getElementCollection(tt, 'styling', 'style'));
  55540. var regionElements = collectionToDictionary(getElementCollection(tt, 'layout', 'region'));
  55541. var cueElements = getElementCollection(tt, 'body', '[begin]');
  55542. return [].map.call(cueElements, function (cueElement) {
  55543. var cueText = getTextContent(cueElement, trim);
  55544. if (!cueText || !cueElement.hasAttribute('begin')) {
  55545. return null;
  55546. }
  55547. var startTime = parseTtmlTime(cueElement.getAttribute('begin'), rateInfo);
  55548. var duration = parseTtmlTime(cueElement.getAttribute('dur'), rateInfo);
  55549. var endTime = parseTtmlTime(cueElement.getAttribute('end'), rateInfo);
  55550. if (startTime === null) {
  55551. throw timestampParsingError(cueElement);
  55552. }
  55553. if (endTime === null) {
  55554. if (duration === null) {
  55555. throw timestampParsingError(cueElement);
  55556. }
  55557. endTime = startTime + duration;
  55558. }
  55559. var cue = new _vttcue__WEBPACK_IMPORTED_MODULE_2__["default"](startTime - syncTime, endTime - syncTime, cueText);
  55560. cue.id = (0,_webvtt_parser__WEBPACK_IMPORTED_MODULE_5__.generateCueId)(cue.startTime, cue.endTime, cue.text);
  55561. var region = regionElements[cueElement.getAttribute('region')];
  55562. var style = styleElements[cueElement.getAttribute('style')];
  55563. // Apply styles to cue
  55564. var styles = getTtmlStyles(region, style, styleElements);
  55565. var textAlign = styles.textAlign;
  55566. if (textAlign) {
  55567. // cue.positionAlign not settable in FF~2016
  55568. var lineAlign = textAlignToLineAlign[textAlign];
  55569. if (lineAlign) {
  55570. cue.lineAlign = lineAlign;
  55571. }
  55572. cue.align = textAlign;
  55573. }
  55574. _extends(cue, styles);
  55575. return cue;
  55576. }).filter(function (cue) {
  55577. return cue !== null;
  55578. });
  55579. }
  55580. function getElementCollection(fromElement, parentName, childName) {
  55581. var parent = fromElement.getElementsByTagName(parentName)[0];
  55582. if (parent) {
  55583. return [].slice.call(parent.querySelectorAll(childName));
  55584. }
  55585. return [];
  55586. }
  55587. function collectionToDictionary(elementsWithId) {
  55588. return elementsWithId.reduce(function (dict, element) {
  55589. var id = element.getAttribute('xml:id');
  55590. if (id) {
  55591. dict[id] = element;
  55592. }
  55593. return dict;
  55594. }, {});
  55595. }
  55596. function getTextContent(element, trim) {
  55597. return [].slice.call(element.childNodes).reduce(function (str, node, i) {
  55598. var _node$childNodes;
  55599. if (node.nodeName === 'br' && i) {
  55600. return str + '\n';
  55601. }
  55602. if ((_node$childNodes = node.childNodes) !== null && _node$childNodes !== void 0 && _node$childNodes.length) {
  55603. return getTextContent(node, trim);
  55604. } else if (trim) {
  55605. return str + node.textContent.trim().replace(/\s+/g, ' ');
  55606. }
  55607. return str + node.textContent;
  55608. }, '');
  55609. }
  55610. function getTtmlStyles(region, style, styleElements) {
  55611. var ttsNs = 'http://www.w3.org/ns/ttml#styling';
  55612. var regionStyle = null;
  55613. var styleAttributes = ['displayAlign', 'textAlign', 'color', 'backgroundColor', 'fontSize', 'fontFamily'
  55614. // 'fontWeight',
  55615. // 'lineHeight',
  55616. // 'wrapOption',
  55617. // 'fontStyle',
  55618. // 'direction',
  55619. // 'writingMode'
  55620. ];
  55621. var regionStyleName = region !== null && region !== void 0 && region.hasAttribute('style') ? region.getAttribute('style') : null;
  55622. if (regionStyleName && styleElements.hasOwnProperty(regionStyleName)) {
  55623. regionStyle = styleElements[regionStyleName];
  55624. }
  55625. return styleAttributes.reduce(function (styles, name) {
  55626. var value = getAttributeNS(style, ttsNs, name) || getAttributeNS(region, ttsNs, name) || getAttributeNS(regionStyle, ttsNs, name);
  55627. if (value) {
  55628. styles[name] = value;
  55629. }
  55630. return styles;
  55631. }, {});
  55632. }
  55633. function getAttributeNS(element, ns, name) {
  55634. if (!element) {
  55635. return null;
  55636. }
  55637. return element.hasAttributeNS(ns, name) ? element.getAttributeNS(ns, name) : null;
  55638. }
  55639. function timestampParsingError(node) {
  55640. return new Error("Could not parse ttml timestamp " + node);
  55641. }
  55642. function parseTtmlTime(timeAttributeValue, rateInfo) {
  55643. if (!timeAttributeValue) {
  55644. return null;
  55645. }
  55646. var seconds = (0,_vttparser__WEBPACK_IMPORTED_MODULE_1__.parseTimeStamp)(timeAttributeValue);
  55647. if (seconds === null) {
  55648. if (HMSF_REGEX.test(timeAttributeValue)) {
  55649. seconds = parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo);
  55650. } else if (TIME_UNIT_REGEX.test(timeAttributeValue)) {
  55651. seconds = parseTimeUnits(timeAttributeValue, rateInfo);
  55652. }
  55653. }
  55654. return seconds;
  55655. }
  55656. function parseHoursMinutesSecondsFrames(timeAttributeValue, rateInfo) {
  55657. var m = HMSF_REGEX.exec(timeAttributeValue);
  55658. var frames = (m[4] | 0) + (m[5] | 0) / rateInfo.subFrameRate;
  55659. return (m[1] | 0) * 3600 + (m[2] | 0) * 60 + (m[3] | 0) + frames / rateInfo.frameRate;
  55660. }
  55661. function parseTimeUnits(timeAttributeValue, rateInfo) {
  55662. var m = TIME_UNIT_REGEX.exec(timeAttributeValue);
  55663. var value = Number(m[1]);
  55664. var unit = m[2];
  55665. switch (unit) {
  55666. case 'h':
  55667. return value * 3600;
  55668. case 'm':
  55669. return value * 60;
  55670. case 'ms':
  55671. return value * 1000;
  55672. case 'f':
  55673. return value / rateInfo.frameRate;
  55674. case 't':
  55675. return value / rateInfo.tickRate;
  55676. }
  55677. return value;
  55678. }
  55679. /***/ }),
  55680. /***/ "./src/utils/keysystem-util.ts":
  55681. /*!*************************************!*\
  55682. !*** ./src/utils/keysystem-util.ts ***!
  55683. \*************************************/
  55684. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55685. "use strict";
  55686. __webpack_require__.r(__webpack_exports__);
  55687. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55688. /* harmony export */ "changeEndianness": () => (/* binding */ changeEndianness),
  55689. /* harmony export */ "convertDataUriToArrayBytes": () => (/* binding */ convertDataUriToArrayBytes),
  55690. /* harmony export */ "strToUtf8array": () => (/* binding */ strToUtf8array)
  55691. /* harmony export */ });
  55692. /* harmony import */ var _numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./numeric-encoding-utils */ "./src/utils/numeric-encoding-utils.ts");
  55693. function getKeyIdBytes(str) {
  55694. var keyIdbytes = strToUtf8array(str).subarray(0, 16);
  55695. var paddedkeyIdbytes = new Uint8Array(16);
  55696. paddedkeyIdbytes.set(keyIdbytes, 16 - keyIdbytes.length);
  55697. return paddedkeyIdbytes;
  55698. }
  55699. function changeEndianness(keyId) {
  55700. var swap = function swap(array, from, to) {
  55701. var cur = array[from];
  55702. array[from] = array[to];
  55703. array[to] = cur;
  55704. };
  55705. swap(keyId, 0, 3);
  55706. swap(keyId, 1, 2);
  55707. swap(keyId, 4, 5);
  55708. swap(keyId, 6, 7);
  55709. }
  55710. function convertDataUriToArrayBytes(uri) {
  55711. // data:[<media type][;attribute=value][;base64],<data>
  55712. var colonsplit = uri.split(':');
  55713. var keydata = null;
  55714. if (colonsplit[0] === 'data' && colonsplit.length === 2) {
  55715. var semicolonsplit = colonsplit[1].split(';');
  55716. var commasplit = semicolonsplit[semicolonsplit.length - 1].split(',');
  55717. if (commasplit.length === 2) {
  55718. var isbase64 = commasplit[0] === 'base64';
  55719. var data = commasplit[1];
  55720. if (isbase64) {
  55721. semicolonsplit.splice(-1, 1); // remove from processing
  55722. keydata = (0,_numeric_encoding_utils__WEBPACK_IMPORTED_MODULE_0__.base64Decode)(data);
  55723. } else {
  55724. keydata = getKeyIdBytes(data);
  55725. }
  55726. }
  55727. }
  55728. return keydata;
  55729. }
  55730. function strToUtf8array(str) {
  55731. return Uint8Array.from(unescape(encodeURIComponent(str)), function (c) {
  55732. return c.charCodeAt(0);
  55733. });
  55734. }
  55735. /***/ }),
  55736. /***/ "./src/utils/logger.ts":
  55737. /*!*****************************!*\
  55738. !*** ./src/utils/logger.ts ***!
  55739. \*****************************/
  55740. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55741. "use strict";
  55742. __webpack_require__.r(__webpack_exports__);
  55743. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55744. /* harmony export */ "enableLogs": () => (/* binding */ enableLogs),
  55745. /* harmony export */ "logger": () => (/* binding */ logger)
  55746. /* harmony export */ });
  55747. var noop = function noop() {};
  55748. var fakeLogger = {
  55749. trace: noop,
  55750. debug: noop,
  55751. log: noop,
  55752. warn: noop,
  55753. info: noop,
  55754. error: noop
  55755. };
  55756. var exportedLogger = fakeLogger;
  55757. // let lastCallTime;
  55758. // function formatMsgWithTimeInfo(type, msg) {
  55759. // const now = Date.now();
  55760. // const diff = lastCallTime ? '+' + (now - lastCallTime) : '0';
  55761. // lastCallTime = now;
  55762. // msg = (new Date(now)).toISOString() + ' | [' + type + '] > ' + msg + ' ( ' + diff + ' ms )';
  55763. // return msg;
  55764. // }
  55765. function consolePrintFn(type) {
  55766. var func = self.console[type];
  55767. if (func) {
  55768. return func.bind(self.console, "[" + type + "] >");
  55769. }
  55770. return noop;
  55771. }
  55772. function exportLoggerFunctions(debugConfig) {
  55773. for (var _len = arguments.length, functions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  55774. functions[_key - 1] = arguments[_key];
  55775. }
  55776. functions.forEach(function (type) {
  55777. exportedLogger[type] = debugConfig[type] ? debugConfig[type].bind(debugConfig) : consolePrintFn(type);
  55778. });
  55779. }
  55780. function enableLogs(debugConfig, id) {
  55781. // check that console is available
  55782. if (self.console && debugConfig === true || typeof debugConfig === 'object') {
  55783. exportLoggerFunctions(debugConfig,
  55784. // Remove out from list here to hard-disable a log-level
  55785. // 'trace',
  55786. 'debug', 'log', 'info', 'warn', 'error');
  55787. // Some browsers don't allow to use bind on console object anyway
  55788. // fallback to default if needed
  55789. try {
  55790. exportedLogger.log("Debug logs enabled for \"" + id + "\"");
  55791. } catch (e) {
  55792. exportedLogger = fakeLogger;
  55793. }
  55794. } else {
  55795. exportedLogger = fakeLogger;
  55796. }
  55797. }
  55798. var logger = exportedLogger;
  55799. /***/ }),
  55800. /***/ "./src/utils/mediakeys-helper.ts":
  55801. /*!***************************************!*\
  55802. !*** ./src/utils/mediakeys-helper.ts ***!
  55803. \***************************************/
  55804. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55805. "use strict";
  55806. __webpack_require__.r(__webpack_exports__);
  55807. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55808. /* harmony export */ "KeySystemFormats": () => (/* binding */ KeySystemFormats),
  55809. /* harmony export */ "KeySystemIds": () => (/* binding */ KeySystemIds),
  55810. /* harmony export */ "KeySystems": () => (/* binding */ KeySystems),
  55811. /* harmony export */ "getKeySystemsForConfig": () => (/* binding */ getKeySystemsForConfig),
  55812. /* harmony export */ "getSupportedMediaKeySystemConfigurations": () => (/* binding */ getSupportedMediaKeySystemConfigurations),
  55813. /* harmony export */ "keySystemDomainToKeySystemFormat": () => (/* binding */ keySystemDomainToKeySystemFormat),
  55814. /* harmony export */ "keySystemFormatToKeySystemDomain": () => (/* binding */ keySystemFormatToKeySystemDomain),
  55815. /* harmony export */ "keySystemIdToKeySystemDomain": () => (/* binding */ keySystemIdToKeySystemDomain),
  55816. /* harmony export */ "requestMediaKeySystemAccess": () => (/* binding */ requestMediaKeySystemAccess)
  55817. /* harmony export */ });
  55818. /**
  55819. * @see https://developer.mozilla.org/en-US/docs/Web/API/Navigator/requestMediaKeySystemAccess
  55820. */
  55821. var KeySystems;
  55822. // Playlist #EXT-X-KEY KEYFORMAT values
  55823. (function (KeySystems) {
  55824. KeySystems["CLEARKEY"] = "org.w3.clearkey";
  55825. KeySystems["FAIRPLAY"] = "com.apple.fps";
  55826. KeySystems["PLAYREADY"] = "com.microsoft.playready";
  55827. KeySystems["WIDEVINE"] = "com.widevine.alpha";
  55828. })(KeySystems || (KeySystems = {}));
  55829. var KeySystemFormats;
  55830. (function (KeySystemFormats) {
  55831. KeySystemFormats["CLEARKEY"] = "org.w3.clearkey";
  55832. KeySystemFormats["FAIRPLAY"] = "com.apple.streamingkeydelivery";
  55833. KeySystemFormats["PLAYREADY"] = "com.microsoft.playready";
  55834. KeySystemFormats["WIDEVINE"] = "urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed";
  55835. })(KeySystemFormats || (KeySystemFormats = {}));
  55836. function keySystemFormatToKeySystemDomain(format) {
  55837. switch (format) {
  55838. case KeySystemFormats.FAIRPLAY:
  55839. return KeySystems.FAIRPLAY;
  55840. case KeySystemFormats.PLAYREADY:
  55841. return KeySystems.PLAYREADY;
  55842. case KeySystemFormats.WIDEVINE:
  55843. return KeySystems.WIDEVINE;
  55844. case KeySystemFormats.CLEARKEY:
  55845. return KeySystems.CLEARKEY;
  55846. }
  55847. }
  55848. // System IDs for which we can extract a key ID from "encrypted" event PSSH
  55849. var KeySystemIds;
  55850. (function (KeySystemIds) {
  55851. KeySystemIds["WIDEVINE"] = "edef8ba979d64acea3c827dcd51d21ed";
  55852. })(KeySystemIds || (KeySystemIds = {}));
  55853. function keySystemIdToKeySystemDomain(systemId) {
  55854. if (systemId === KeySystemIds.WIDEVINE) {
  55855. return KeySystems.WIDEVINE;
  55856. // } else if (systemId === KeySystemIds.PLAYREADY) {
  55857. // return KeySystems.PLAYREADY;
  55858. // } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
  55859. // return KeySystems.CLEARKEY;
  55860. }
  55861. }
  55862. function keySystemDomainToKeySystemFormat(keySystem) {
  55863. switch (keySystem) {
  55864. case KeySystems.FAIRPLAY:
  55865. return KeySystemFormats.FAIRPLAY;
  55866. case KeySystems.PLAYREADY:
  55867. return KeySystemFormats.PLAYREADY;
  55868. case KeySystems.WIDEVINE:
  55869. return KeySystemFormats.WIDEVINE;
  55870. case KeySystems.CLEARKEY:
  55871. return KeySystemFormats.CLEARKEY;
  55872. }
  55873. }
  55874. function getKeySystemsForConfig(config) {
  55875. var drmSystems = config.drmSystems,
  55876. widevineLicenseUrl = config.widevineLicenseUrl;
  55877. var keySystemsToAttempt = drmSystems ? [KeySystems.FAIRPLAY, KeySystems.WIDEVINE, KeySystems.PLAYREADY, KeySystems.CLEARKEY].filter(function (keySystem) {
  55878. return !!drmSystems[keySystem];
  55879. }) : [];
  55880. if (!keySystemsToAttempt[KeySystems.WIDEVINE] && widevineLicenseUrl) {
  55881. keySystemsToAttempt.push(KeySystems.WIDEVINE);
  55882. }
  55883. return keySystemsToAttempt;
  55884. }
  55885. var requestMediaKeySystemAccess = function () {
  55886. if (typeof self !== 'undefined' && self.navigator && self.navigator.requestMediaKeySystemAccess) {
  55887. return self.navigator.requestMediaKeySystemAccess.bind(self.navigator);
  55888. } else {
  55889. return null;
  55890. }
  55891. }();
  55892. /**
  55893. * @see https://developer.mozilla.org/en-US/docs/Web/API/MediaKeySystemConfiguration
  55894. */
  55895. function getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, drmSystemOptions) {
  55896. var initDataTypes;
  55897. switch (keySystem) {
  55898. case KeySystems.FAIRPLAY:
  55899. initDataTypes = ['cenc', 'sinf'];
  55900. break;
  55901. case KeySystems.WIDEVINE:
  55902. case KeySystems.PLAYREADY:
  55903. initDataTypes = ['cenc'];
  55904. break;
  55905. case KeySystems.CLEARKEY:
  55906. initDataTypes = ['cenc', 'keyids'];
  55907. break;
  55908. default:
  55909. throw new Error("Unknown key-system: " + keySystem);
  55910. }
  55911. return createMediaKeySystemConfigurations(initDataTypes, audioCodecs, videoCodecs, drmSystemOptions);
  55912. }
  55913. function createMediaKeySystemConfigurations(initDataTypes, audioCodecs, videoCodecs, drmSystemOptions) {
  55914. var baseConfig = {
  55915. initDataTypes: initDataTypes,
  55916. persistentState: drmSystemOptions.persistentState || 'not-allowed',
  55917. distinctiveIdentifier: drmSystemOptions.distinctiveIdentifier || 'not-allowed',
  55918. sessionTypes: drmSystemOptions.sessionTypes || [drmSystemOptions.sessionType || 'temporary'],
  55919. audioCapabilities: audioCodecs.map(function (codec) {
  55920. return {
  55921. contentType: "audio/mp4; codecs=\"" + codec + "\"",
  55922. robustness: drmSystemOptions.audioRobustness || '',
  55923. encryptionScheme: drmSystemOptions.audioEncryptionScheme || null
  55924. };
  55925. }),
  55926. videoCapabilities: videoCodecs.map(function (codec) {
  55927. return {
  55928. contentType: "video/mp4; codecs=\"" + codec + "\"",
  55929. robustness: drmSystemOptions.videoRobustness || '',
  55930. encryptionScheme: drmSystemOptions.videoEncryptionScheme || null
  55931. };
  55932. })
  55933. };
  55934. return [baseConfig];
  55935. }
  55936. /***/ }),
  55937. /***/ "./src/utils/mediasource-helper.ts":
  55938. /*!*****************************************!*\
  55939. !*** ./src/utils/mediasource-helper.ts ***!
  55940. \*****************************************/
  55941. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55942. "use strict";
  55943. __webpack_require__.r(__webpack_exports__);
  55944. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55945. /* harmony export */ "getMediaSource": () => (/* binding */ getMediaSource)
  55946. /* harmony export */ });
  55947. /**
  55948. * MediaSource helper
  55949. */
  55950. function getMediaSource() {
  55951. return self.MediaSource || self.WebKitMediaSource;
  55952. }
  55953. /***/ }),
  55954. /***/ "./src/utils/mp4-tools.ts":
  55955. /*!********************************!*\
  55956. !*** ./src/utils/mp4-tools.ts ***!
  55957. \********************************/
  55958. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  55959. "use strict";
  55960. __webpack_require__.r(__webpack_exports__);
  55961. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  55962. /* harmony export */ "RemuxerTrackIdConfig": () => (/* binding */ RemuxerTrackIdConfig),
  55963. /* harmony export */ "appendUint8Array": () => (/* binding */ appendUint8Array),
  55964. /* harmony export */ "bin2str": () => (/* binding */ bin2str),
  55965. /* harmony export */ "computeRawDurationFromSamples": () => (/* binding */ computeRawDurationFromSamples),
  55966. /* harmony export */ "discardEPB": () => (/* binding */ discardEPB),
  55967. /* harmony export */ "findBox": () => (/* binding */ findBox),
  55968. /* harmony export */ "getDuration": () => (/* binding */ getDuration),
  55969. /* harmony export */ "getStartDTS": () => (/* binding */ getStartDTS),
  55970. /* harmony export */ "mp4Box": () => (/* binding */ mp4Box),
  55971. /* harmony export */ "mp4pssh": () => (/* binding */ mp4pssh),
  55972. /* harmony export */ "offsetStartDTS": () => (/* binding */ offsetStartDTS),
  55973. /* harmony export */ "parseEmsg": () => (/* binding */ parseEmsg),
  55974. /* harmony export */ "parseInitSegment": () => (/* binding */ parseInitSegment),
  55975. /* harmony export */ "parsePssh": () => (/* binding */ parsePssh),
  55976. /* harmony export */ "parseSEIMessageFromNALu": () => (/* binding */ parseSEIMessageFromNALu),
  55977. /* harmony export */ "parseSamples": () => (/* binding */ parseSamples),
  55978. /* harmony export */ "parseSegmentIndex": () => (/* binding */ parseSegmentIndex),
  55979. /* harmony export */ "parseSinf": () => (/* binding */ parseSinf),
  55980. /* harmony export */ "patchEncyptionData": () => (/* binding */ patchEncyptionData),
  55981. /* harmony export */ "readSint32": () => (/* binding */ readSint32),
  55982. /* harmony export */ "readUint16": () => (/* binding */ readUint16),
  55983. /* harmony export */ "readUint32": () => (/* binding */ readUint32),
  55984. /* harmony export */ "segmentValidRange": () => (/* binding */ segmentValidRange),
  55985. /* harmony export */ "writeUint32": () => (/* binding */ writeUint32)
  55986. /* harmony export */ });
  55987. /* harmony import */ var _loader_fragment__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../loader/fragment */ "./src/loader/fragment.ts");
  55988. /* harmony import */ var _typed_array__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./typed-array */ "./src/utils/typed-array.ts");
  55989. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  55990. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  55991. /* harmony import */ var _hex__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./hex */ "./src/utils/hex.ts");
  55992. var UINT32_MAX = Math.pow(2, 32) - 1;
  55993. var push = [].push;
  55994. // We are using fixed track IDs for driving the MP4 remuxer
  55995. // instead of following the TS PIDs.
  55996. // There is no reason not to do this and some browsers/SourceBuffer-demuxers
  55997. // may not like if there are TrackID "switches"
  55998. // See https://github.com/video-dev/hls.js/issues/1331
  55999. // Here we are mapping our internal track types to constant MP4 track IDs
  56000. // With MSE currently one can only have one track of each, and we are muxing
  56001. // whatever video/audio rendition in them.
  56002. var RemuxerTrackIdConfig = {
  56003. video: 1,
  56004. audio: 2,
  56005. id3: 3,
  56006. text: 4
  56007. };
  56008. function bin2str(data) {
  56009. return String.fromCharCode.apply(null, data);
  56010. }
  56011. function readUint16(buffer, offset) {
  56012. var val = buffer[offset] << 8 | buffer[offset + 1];
  56013. return val < 0 ? 65536 + val : val;
  56014. }
  56015. function readUint32(buffer, offset) {
  56016. var val = readSint32(buffer, offset);
  56017. return val < 0 ? 4294967296 + val : val;
  56018. }
  56019. function readSint32(buffer, offset) {
  56020. return buffer[offset] << 24 | buffer[offset + 1] << 16 | buffer[offset + 2] << 8 | buffer[offset + 3];
  56021. }
  56022. function writeUint32(buffer, offset, value) {
  56023. buffer[offset] = value >> 24;
  56024. buffer[offset + 1] = value >> 16 & 0xff;
  56025. buffer[offset + 2] = value >> 8 & 0xff;
  56026. buffer[offset + 3] = value & 0xff;
  56027. }
  56028. // Find the data for a box specified by its path
  56029. function findBox(data, path) {
  56030. var results = [];
  56031. if (!path.length) {
  56032. // short-circuit the search for empty paths
  56033. return results;
  56034. }
  56035. var end = data.byteLength;
  56036. for (var i = 0; i < end;) {
  56037. var size = readUint32(data, i);
  56038. var type = bin2str(data.subarray(i + 4, i + 8));
  56039. var endbox = size > 1 ? i + size : end;
  56040. if (type === path[0]) {
  56041. if (path.length === 1) {
  56042. // this is the end of the path and we've found the box we were
  56043. // looking for
  56044. results.push(data.subarray(i + 8, endbox));
  56045. } else {
  56046. // recursively search for the next box along the path
  56047. var subresults = findBox(data.subarray(i + 8, endbox), path.slice(1));
  56048. if (subresults.length) {
  56049. push.apply(results, subresults);
  56050. }
  56051. }
  56052. }
  56053. i = endbox;
  56054. }
  56055. // we've finished searching all of data
  56056. return results;
  56057. }
  56058. function parseSegmentIndex(sidx) {
  56059. var references = [];
  56060. var version = sidx[0];
  56061. // set initial offset, we skip the reference ID (not needed)
  56062. var index = 8;
  56063. var timescale = readUint32(sidx, index);
  56064. index += 4;
  56065. // TODO: parse earliestPresentationTime and firstOffset
  56066. // usually zero in our case
  56067. var earliestPresentationTime = 0;
  56068. var firstOffset = 0;
  56069. if (version === 0) {
  56070. index += 8;
  56071. } else {
  56072. index += 16;
  56073. }
  56074. // skip reserved
  56075. index += 2;
  56076. var startByte = sidx.length + firstOffset;
  56077. var referencesCount = readUint16(sidx, index);
  56078. index += 2;
  56079. for (var i = 0; i < referencesCount; i++) {
  56080. var referenceIndex = index;
  56081. var referenceInfo = readUint32(sidx, referenceIndex);
  56082. referenceIndex += 4;
  56083. var referenceSize = referenceInfo & 0x7fffffff;
  56084. var referenceType = (referenceInfo & 0x80000000) >>> 31;
  56085. if (referenceType === 1) {
  56086. // eslint-disable-next-line no-console
  56087. console.warn('SIDX has hierarchical references (not supported)');
  56088. return null;
  56089. }
  56090. var subsegmentDuration = readUint32(sidx, referenceIndex);
  56091. referenceIndex += 4;
  56092. references.push({
  56093. referenceSize: referenceSize,
  56094. subsegmentDuration: subsegmentDuration,
  56095. // unscaled
  56096. info: {
  56097. duration: subsegmentDuration / timescale,
  56098. start: startByte,
  56099. end: startByte + referenceSize - 1
  56100. }
  56101. });
  56102. startByte += referenceSize;
  56103. // Skipping 1 bit for |startsWithSap|, 3 bits for |sapType|, and 28 bits
  56104. // for |sapDelta|.
  56105. referenceIndex += 4;
  56106. // skip to next ref
  56107. index = referenceIndex;
  56108. }
  56109. return {
  56110. earliestPresentationTime: earliestPresentationTime,
  56111. timescale: timescale,
  56112. version: version,
  56113. referencesCount: referencesCount,
  56114. references: references
  56115. };
  56116. }
  56117. /**
  56118. * Parses an MP4 initialization segment and extracts stream type and
  56119. * timescale values for any declared tracks. Timescale values indicate the
  56120. * number of clock ticks per second to assume for time-based values
  56121. * elsewhere in the MP4.
  56122. *
  56123. * To determine the start time of an MP4, you need two pieces of
  56124. * information: the timescale unit and the earliest base media decode
  56125. * time. Multiple timescales can be specified within an MP4 but the
  56126. * base media decode time is always expressed in the timescale from
  56127. * the media header box for the track:
  56128. * ```
  56129. * moov > trak > mdia > mdhd.timescale
  56130. * moov > trak > mdia > hdlr
  56131. * ```
  56132. * @param initSegment {Uint8Array} the bytes of the init segment
  56133. * @return {InitData} a hash of track type to timescale values or null if
  56134. * the init segment is malformed.
  56135. */
  56136. function parseInitSegment(initSegment) {
  56137. var result = [];
  56138. var traks = findBox(initSegment, ['moov', 'trak']);
  56139. for (var i = 0; i < traks.length; i++) {
  56140. var trak = traks[i];
  56141. var tkhd = findBox(trak, ['tkhd'])[0];
  56142. if (tkhd) {
  56143. var version = tkhd[0];
  56144. var _index = version === 0 ? 12 : 20;
  56145. var trackId = readUint32(tkhd, _index);
  56146. var mdhd = findBox(trak, ['mdia', 'mdhd'])[0];
  56147. if (mdhd) {
  56148. version = mdhd[0];
  56149. _index = version === 0 ? 12 : 20;
  56150. var timescale = readUint32(mdhd, _index);
  56151. var hdlr = findBox(trak, ['mdia', 'hdlr'])[0];
  56152. if (hdlr) {
  56153. var hdlrType = bin2str(hdlr.subarray(8, 12));
  56154. var type = {
  56155. soun: _loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.AUDIO,
  56156. vide: _loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.VIDEO
  56157. }[hdlrType];
  56158. if (type) {
  56159. // Parse codec details
  56160. var stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];
  56161. var codec = void 0;
  56162. if (stsd) {
  56163. codec = bin2str(stsd.subarray(12, 16));
  56164. // TODO: Parse codec details to be able to build MIME type.
  56165. // stsd.start += 8;
  56166. // const codecBox = findBox(stsd, [codec])[0];
  56167. // if (codecBox) {
  56168. // TODO: Codec parsing support for avc1, mp4a, hevc, av01...
  56169. // }
  56170. }
  56171. result[trackId] = {
  56172. timescale: timescale,
  56173. type: type
  56174. };
  56175. result[type] = {
  56176. timescale: timescale,
  56177. id: trackId,
  56178. codec: codec
  56179. };
  56180. }
  56181. }
  56182. }
  56183. }
  56184. }
  56185. var trex = findBox(initSegment, ['moov', 'mvex', 'trex']);
  56186. trex.forEach(function (trex) {
  56187. var trackId = readUint32(trex, 4);
  56188. var track = result[trackId];
  56189. if (track) {
  56190. track.default = {
  56191. duration: readUint32(trex, 12),
  56192. flags: readUint32(trex, 20)
  56193. };
  56194. }
  56195. });
  56196. return result;
  56197. }
  56198. function patchEncyptionData(initSegment, decryptdata) {
  56199. if (!initSegment || !decryptdata) {
  56200. return initSegment;
  56201. }
  56202. var keyId = decryptdata.keyId;
  56203. if (keyId && decryptdata.isCommonEncryption) {
  56204. var traks = findBox(initSegment, ['moov', 'trak']);
  56205. traks.forEach(function (trak) {
  56206. var stsd = findBox(trak, ['mdia', 'minf', 'stbl', 'stsd'])[0];
  56207. // skip the sample entry count
  56208. var sampleEntries = stsd.subarray(8);
  56209. var encBoxes = findBox(sampleEntries, ['enca']);
  56210. var isAudio = encBoxes.length > 0;
  56211. if (!isAudio) {
  56212. encBoxes = findBox(sampleEntries, ['encv']);
  56213. }
  56214. encBoxes.forEach(function (enc) {
  56215. var encBoxChildren = isAudio ? enc.subarray(28) : enc.subarray(78);
  56216. var sinfBoxes = findBox(encBoxChildren, ['sinf']);
  56217. sinfBoxes.forEach(function (sinf) {
  56218. var tenc = parseSinf(sinf);
  56219. if (tenc) {
  56220. // Look for default key id (keyID offset is always 8 within the tenc box):
  56221. var tencKeyId = tenc.subarray(8, 24);
  56222. if (!tencKeyId.some(function (b) {
  56223. return b !== 0;
  56224. })) {
  56225. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.log("[eme] Patching keyId in 'enc" + (isAudio ? 'a' : 'v') + ">sinf>>tenc' box: " + _hex__WEBPACK_IMPORTED_MODULE_4__["default"].hexDump(tencKeyId) + " -> " + _hex__WEBPACK_IMPORTED_MODULE_4__["default"].hexDump(keyId));
  56226. tenc.set(keyId, 8);
  56227. }
  56228. }
  56229. });
  56230. });
  56231. });
  56232. }
  56233. return initSegment;
  56234. }
  56235. function parseSinf(sinf) {
  56236. var schm = findBox(sinf, ['schm'])[0];
  56237. if (schm) {
  56238. var scheme = bin2str(schm.subarray(4, 8));
  56239. if (scheme === 'cbcs' || scheme === 'cenc') {
  56240. return findBox(sinf, ['schi', 'tenc'])[0];
  56241. }
  56242. }
  56243. _utils_logger__WEBPACK_IMPORTED_MODULE_3__.logger.error("[eme] missing 'schm' box");
  56244. return null;
  56245. }
  56246. /**
  56247. * Determine the base media decode start time, in seconds, for an MP4
  56248. * fragment. If multiple fragments are specified, the earliest time is
  56249. * returned.
  56250. *
  56251. * The base media decode time can be parsed from track fragment
  56252. * metadata:
  56253. * ```
  56254. * moof > traf > tfdt.baseMediaDecodeTime
  56255. * ```
  56256. * It requires the timescale value from the mdhd to interpret.
  56257. *
  56258. * @param initData {InitData} a hash of track type to timescale values
  56259. * @param fmp4 {Uint8Array} the bytes of the mp4 fragment
  56260. * @return {number} the earliest base media decode start time for the
  56261. * fragment, in seconds
  56262. */
  56263. function getStartDTS(initData, fmp4) {
  56264. // we need info from two children of each track fragment box
  56265. return findBox(fmp4, ['moof', 'traf']).reduce(function (result, traf) {
  56266. var tfdt = findBox(traf, ['tfdt'])[0];
  56267. var version = tfdt[0];
  56268. var start = findBox(traf, ['tfhd']).reduce(function (result, tfhd) {
  56269. // get the track id from the tfhd
  56270. var id = readUint32(tfhd, 4);
  56271. var track = initData[id];
  56272. if (track) {
  56273. var baseTime = readUint32(tfdt, 4);
  56274. if (version === 1) {
  56275. baseTime *= Math.pow(2, 32);
  56276. baseTime += readUint32(tfdt, 8);
  56277. }
  56278. // assume a 90kHz clock if no timescale was specified
  56279. var scale = track.timescale || 90e3;
  56280. // convert base time to seconds
  56281. var startTime = baseTime / scale;
  56282. if (isFinite(startTime) && (result === null || startTime < result)) {
  56283. return startTime;
  56284. }
  56285. }
  56286. return result;
  56287. }, null);
  56288. if (start !== null && isFinite(start) && (result === null || start < result)) {
  56289. return start;
  56290. }
  56291. return result;
  56292. }, null) || 0;
  56293. }
  56294. /*
  56295. For Reference:
  56296. aligned(8) class TrackFragmentHeaderBox
  56297. extends FullBox(‘tfhd’, 0, tf_flags){
  56298. unsigned int(32) track_ID;
  56299. // all the following are optional fields
  56300. unsigned int(64) base_data_offset;
  56301. unsigned int(32) sample_description_index;
  56302. unsigned int(32) default_sample_duration;
  56303. unsigned int(32) default_sample_size;
  56304. unsigned int(32) default_sample_flags
  56305. }
  56306. */
  56307. function getDuration(data, initData) {
  56308. var rawDuration = 0;
  56309. var videoDuration = 0;
  56310. var audioDuration = 0;
  56311. var trafs = findBox(data, ['moof', 'traf']);
  56312. for (var i = 0; i < trafs.length; i++) {
  56313. var traf = trafs[i];
  56314. // There is only one tfhd & trun per traf
  56315. // This is true for CMAF style content, and we should perhaps check the ftyp
  56316. // and only look for a single trun then, but for ISOBMFF we should check
  56317. // for multiple track runs.
  56318. var tfhd = findBox(traf, ['tfhd'])[0];
  56319. // get the track id from the tfhd
  56320. var id = readUint32(tfhd, 4);
  56321. var track = initData[id];
  56322. if (!track) {
  56323. continue;
  56324. }
  56325. var trackDefault = track.default;
  56326. var tfhdFlags = readUint32(tfhd, 0) | (trackDefault === null || trackDefault === void 0 ? void 0 : trackDefault.flags);
  56327. var sampleDuration = trackDefault === null || trackDefault === void 0 ? void 0 : trackDefault.duration;
  56328. if (tfhdFlags & 0x000008) {
  56329. // 0x000008 indicates the presence of the default_sample_duration field
  56330. if (tfhdFlags & 0x000002) {
  56331. // 0x000002 indicates the presence of the sample_description_index field, which precedes default_sample_duration
  56332. // If present, the default_sample_duration exists at byte offset 12
  56333. sampleDuration = readUint32(tfhd, 12);
  56334. } else {
  56335. // Otherwise, the duration is at byte offset 8
  56336. sampleDuration = readUint32(tfhd, 8);
  56337. }
  56338. }
  56339. // assume a 90kHz clock if no timescale was specified
  56340. var timescale = track.timescale || 90e3;
  56341. var truns = findBox(traf, ['trun']);
  56342. for (var j = 0; j < truns.length; j++) {
  56343. rawDuration = computeRawDurationFromSamples(truns[j]);
  56344. if (!rawDuration && sampleDuration) {
  56345. var sampleCount = readUint32(truns[j], 4);
  56346. rawDuration = sampleDuration * sampleCount;
  56347. }
  56348. if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.VIDEO) {
  56349. videoDuration += rawDuration / timescale;
  56350. } else if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.AUDIO) {
  56351. audioDuration += rawDuration / timescale;
  56352. }
  56353. }
  56354. }
  56355. if (videoDuration === 0 && audioDuration === 0) {
  56356. // If duration samples are not available in the traf use sidx subsegment_duration
  56357. var sidxDuration = 0;
  56358. var sidxs = findBox(data, ['sidx']);
  56359. for (var _i = 0; _i < sidxs.length; _i++) {
  56360. var sidx = parseSegmentIndex(sidxs[_i]);
  56361. if (sidx !== null && sidx !== void 0 && sidx.references) {
  56362. sidxDuration += sidx.references.reduce(function (dur, ref) {
  56363. return dur + ref.info.duration || 0;
  56364. }, 0);
  56365. }
  56366. }
  56367. return sidxDuration;
  56368. }
  56369. if (videoDuration) {
  56370. return videoDuration;
  56371. }
  56372. return audioDuration;
  56373. }
  56374. /*
  56375. For Reference:
  56376. aligned(8) class TrackRunBox
  56377. extends FullBox(‘trun’, version, tr_flags) {
  56378. unsigned int(32) sample_count;
  56379. // the following are optional fields
  56380. signed int(32) data_offset;
  56381. unsigned int(32) first_sample_flags;
  56382. // all fields in the following array are optional
  56383. {
  56384. unsigned int(32) sample_duration;
  56385. unsigned int(32) sample_size;
  56386. unsigned int(32) sample_flags
  56387. if (version == 0)
  56388. { unsigned int(32)
  56389. else
  56390. { signed int(32)
  56391. }[ sample_count ]
  56392. }
  56393. */
  56394. function computeRawDurationFromSamples(trun) {
  56395. var flags = readUint32(trun, 0);
  56396. // Flags are at offset 0, non-optional sample_count is at offset 4. Therefore we start 8 bytes in.
  56397. // Each field is an int32, which is 4 bytes
  56398. var offset = 8;
  56399. // data-offset-present flag
  56400. if (flags & 0x000001) {
  56401. offset += 4;
  56402. }
  56403. // first-sample-flags-present flag
  56404. if (flags & 0x000004) {
  56405. offset += 4;
  56406. }
  56407. var duration = 0;
  56408. var sampleCount = readUint32(trun, 4);
  56409. for (var i = 0; i < sampleCount; i++) {
  56410. // sample-duration-present flag
  56411. if (flags & 0x000100) {
  56412. var sampleDuration = readUint32(trun, offset);
  56413. duration += sampleDuration;
  56414. offset += 4;
  56415. }
  56416. // sample-size-present flag
  56417. if (flags & 0x000200) {
  56418. offset += 4;
  56419. }
  56420. // sample-flags-present flag
  56421. if (flags & 0x000400) {
  56422. offset += 4;
  56423. }
  56424. // sample-composition-time-offsets-present flag
  56425. if (flags & 0x000800) {
  56426. offset += 4;
  56427. }
  56428. }
  56429. return duration;
  56430. }
  56431. function offsetStartDTS(initData, fmp4, timeOffset) {
  56432. findBox(fmp4, ['moof', 'traf']).forEach(function (traf) {
  56433. findBox(traf, ['tfhd']).forEach(function (tfhd) {
  56434. // get the track id from the tfhd
  56435. var id = readUint32(tfhd, 4);
  56436. var track = initData[id];
  56437. if (!track) {
  56438. return;
  56439. }
  56440. // assume a 90kHz clock if no timescale was specified
  56441. var timescale = track.timescale || 90e3;
  56442. // get the base media decode time from the tfdt
  56443. findBox(traf, ['tfdt']).forEach(function (tfdt) {
  56444. var version = tfdt[0];
  56445. var baseMediaDecodeTime = readUint32(tfdt, 4);
  56446. if (version === 0) {
  56447. baseMediaDecodeTime -= timeOffset * timescale;
  56448. baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);
  56449. writeUint32(tfdt, 4, baseMediaDecodeTime);
  56450. } else {
  56451. baseMediaDecodeTime *= Math.pow(2, 32);
  56452. baseMediaDecodeTime += readUint32(tfdt, 8);
  56453. baseMediaDecodeTime -= timeOffset * timescale;
  56454. baseMediaDecodeTime = Math.max(baseMediaDecodeTime, 0);
  56455. var upper = Math.floor(baseMediaDecodeTime / (UINT32_MAX + 1));
  56456. var lower = Math.floor(baseMediaDecodeTime % (UINT32_MAX + 1));
  56457. writeUint32(tfdt, 4, upper);
  56458. writeUint32(tfdt, 8, lower);
  56459. }
  56460. });
  56461. });
  56462. });
  56463. }
  56464. // TODO: Check if the last moof+mdat pair is part of the valid range
  56465. function segmentValidRange(data) {
  56466. var segmentedRange = {
  56467. valid: null,
  56468. remainder: null
  56469. };
  56470. var moofs = findBox(data, ['moof']);
  56471. if (!moofs) {
  56472. return segmentedRange;
  56473. } else if (moofs.length < 2) {
  56474. segmentedRange.remainder = data;
  56475. return segmentedRange;
  56476. }
  56477. var last = moofs[moofs.length - 1];
  56478. // Offset by 8 bytes; findBox offsets the start by as much
  56479. segmentedRange.valid = (0,_typed_array__WEBPACK_IMPORTED_MODULE_1__.sliceUint8)(data, 0, last.byteOffset - 8);
  56480. segmentedRange.remainder = (0,_typed_array__WEBPACK_IMPORTED_MODULE_1__.sliceUint8)(data, last.byteOffset - 8);
  56481. return segmentedRange;
  56482. }
  56483. function appendUint8Array(data1, data2) {
  56484. var temp = new Uint8Array(data1.length + data2.length);
  56485. temp.set(data1);
  56486. temp.set(data2, data1.length);
  56487. return temp;
  56488. }
  56489. function parseSamples(timeOffset, track) {
  56490. var seiSamples = [];
  56491. var videoData = track.samples;
  56492. var timescale = track.timescale;
  56493. var trackId = track.id;
  56494. var isHEVCFlavor = false;
  56495. var moofs = findBox(videoData, ['moof']);
  56496. moofs.map(function (moof) {
  56497. var moofOffset = moof.byteOffset - 8;
  56498. var trafs = findBox(moof, ['traf']);
  56499. trafs.map(function (traf) {
  56500. // get the base media decode time from the tfdt
  56501. var baseTime = findBox(traf, ['tfdt']).map(function (tfdt) {
  56502. var version = tfdt[0];
  56503. var result = readUint32(tfdt, 4);
  56504. if (version === 1) {
  56505. result *= Math.pow(2, 32);
  56506. result += readUint32(tfdt, 8);
  56507. }
  56508. return result / timescale;
  56509. })[0];
  56510. if (baseTime !== undefined) {
  56511. timeOffset = baseTime;
  56512. }
  56513. return findBox(traf, ['tfhd']).map(function (tfhd) {
  56514. var id = readUint32(tfhd, 4);
  56515. var tfhdFlags = readUint32(tfhd, 0) & 0xffffff;
  56516. var baseDataOffsetPresent = (tfhdFlags & 0x000001) !== 0;
  56517. var sampleDescriptionIndexPresent = (tfhdFlags & 0x000002) !== 0;
  56518. var defaultSampleDurationPresent = (tfhdFlags & 0x000008) !== 0;
  56519. var defaultSampleDuration = 0;
  56520. var defaultSampleSizePresent = (tfhdFlags & 0x000010) !== 0;
  56521. var defaultSampleSize = 0;
  56522. var defaultSampleFlagsPresent = (tfhdFlags & 0x000020) !== 0;
  56523. var tfhdOffset = 8;
  56524. if (id === trackId) {
  56525. if (baseDataOffsetPresent) {
  56526. tfhdOffset += 8;
  56527. }
  56528. if (sampleDescriptionIndexPresent) {
  56529. tfhdOffset += 4;
  56530. }
  56531. if (defaultSampleDurationPresent) {
  56532. defaultSampleDuration = readUint32(tfhd, tfhdOffset);
  56533. tfhdOffset += 4;
  56534. }
  56535. if (defaultSampleSizePresent) {
  56536. defaultSampleSize = readUint32(tfhd, tfhdOffset);
  56537. tfhdOffset += 4;
  56538. }
  56539. if (defaultSampleFlagsPresent) {
  56540. tfhdOffset += 4;
  56541. }
  56542. if (track.type === 'video') {
  56543. isHEVCFlavor = isHEVC(track.codec);
  56544. }
  56545. findBox(traf, ['trun']).map(function (trun) {
  56546. var version = trun[0];
  56547. var flags = readUint32(trun, 0) & 0xffffff;
  56548. var dataOffsetPresent = (flags & 0x000001) !== 0;
  56549. var dataOffset = 0;
  56550. var firstSampleFlagsPresent = (flags & 0x000004) !== 0;
  56551. var sampleDurationPresent = (flags & 0x000100) !== 0;
  56552. var sampleDuration = 0;
  56553. var sampleSizePresent = (flags & 0x000200) !== 0;
  56554. var sampleSize = 0;
  56555. var sampleFlagsPresent = (flags & 0x000400) !== 0;
  56556. var sampleCompositionOffsetsPresent = (flags & 0x000800) !== 0;
  56557. var compositionOffset = 0;
  56558. var sampleCount = readUint32(trun, 4);
  56559. var trunOffset = 8; // past version, flags, and sample count
  56560. if (dataOffsetPresent) {
  56561. dataOffset = readUint32(trun, trunOffset);
  56562. trunOffset += 4;
  56563. }
  56564. if (firstSampleFlagsPresent) {
  56565. trunOffset += 4;
  56566. }
  56567. var sampleOffset = dataOffset + moofOffset;
  56568. for (var ix = 0; ix < sampleCount; ix++) {
  56569. if (sampleDurationPresent) {
  56570. sampleDuration = readUint32(trun, trunOffset);
  56571. trunOffset += 4;
  56572. } else {
  56573. sampleDuration = defaultSampleDuration;
  56574. }
  56575. if (sampleSizePresent) {
  56576. sampleSize = readUint32(trun, trunOffset);
  56577. trunOffset += 4;
  56578. } else {
  56579. sampleSize = defaultSampleSize;
  56580. }
  56581. if (sampleFlagsPresent) {
  56582. trunOffset += 4;
  56583. }
  56584. if (sampleCompositionOffsetsPresent) {
  56585. if (version === 0) {
  56586. compositionOffset = readUint32(trun, trunOffset);
  56587. } else {
  56588. compositionOffset = readSint32(trun, trunOffset);
  56589. }
  56590. trunOffset += 4;
  56591. }
  56592. if (track.type === _loader_fragment__WEBPACK_IMPORTED_MODULE_0__.ElementaryStreamTypes.VIDEO) {
  56593. var naluTotalSize = 0;
  56594. while (naluTotalSize < sampleSize) {
  56595. var naluSize = readUint32(videoData, sampleOffset);
  56596. sampleOffset += 4;
  56597. if (isSEIMessage(isHEVCFlavor, videoData[sampleOffset])) {
  56598. var data = videoData.subarray(sampleOffset, sampleOffset + naluSize);
  56599. parseSEIMessageFromNALu(data, isHEVCFlavor ? 2 : 1, timeOffset + compositionOffset / timescale, seiSamples);
  56600. }
  56601. sampleOffset += naluSize;
  56602. naluTotalSize += naluSize + 4;
  56603. }
  56604. }
  56605. timeOffset += sampleDuration / timescale;
  56606. }
  56607. });
  56608. }
  56609. });
  56610. });
  56611. });
  56612. return seiSamples;
  56613. }
  56614. function isHEVC(codec) {
  56615. if (!codec) {
  56616. return false;
  56617. }
  56618. var delimit = codec.indexOf('.');
  56619. var baseCodec = delimit < 0 ? codec : codec.substring(0, delimit);
  56620. return baseCodec === 'hvc1' || baseCodec === 'hev1' ||
  56621. // Dolby Vision
  56622. baseCodec === 'dvh1' || baseCodec === 'dvhe';
  56623. }
  56624. function isSEIMessage(isHEVCFlavor, naluHeader) {
  56625. if (isHEVCFlavor) {
  56626. var naluType = naluHeader >> 1 & 0x3f;
  56627. return naluType === 39 || naluType === 40;
  56628. } else {
  56629. var _naluType = naluHeader & 0x1f;
  56630. return _naluType === 6;
  56631. }
  56632. }
  56633. function parseSEIMessageFromNALu(unescapedData, headerSize, pts, samples) {
  56634. var data = discardEPB(unescapedData);
  56635. var seiPtr = 0;
  56636. // skip nal header
  56637. seiPtr += headerSize;
  56638. var payloadType = 0;
  56639. var payloadSize = 0;
  56640. var endOfCaptions = false;
  56641. var b = 0;
  56642. while (seiPtr < data.length) {
  56643. payloadType = 0;
  56644. do {
  56645. if (seiPtr >= data.length) {
  56646. break;
  56647. }
  56648. b = data[seiPtr++];
  56649. payloadType += b;
  56650. } while (b === 0xff);
  56651. // Parse payload size.
  56652. payloadSize = 0;
  56653. do {
  56654. if (seiPtr >= data.length) {
  56655. break;
  56656. }
  56657. b = data[seiPtr++];
  56658. payloadSize += b;
  56659. } while (b === 0xff);
  56660. var leftOver = data.length - seiPtr;
  56661. if (!endOfCaptions && payloadType === 4 && seiPtr < data.length) {
  56662. endOfCaptions = true;
  56663. var countryCode = data[seiPtr++];
  56664. if (countryCode === 181) {
  56665. var providerCode = readUint16(data, seiPtr);
  56666. seiPtr += 2;
  56667. if (providerCode === 49) {
  56668. var userStructure = readUint32(data, seiPtr);
  56669. seiPtr += 4;
  56670. if (userStructure === 0x47413934) {
  56671. var userDataType = data[seiPtr++];
  56672. // Raw CEA-608 bytes wrapped in CEA-708 packet
  56673. if (userDataType === 3) {
  56674. var firstByte = data[seiPtr++];
  56675. var totalCCs = 0x1f & firstByte;
  56676. var enabled = 0x40 & firstByte;
  56677. var totalBytes = enabled ? 2 + totalCCs * 3 : 0;
  56678. var byteArray = new Uint8Array(totalBytes);
  56679. if (enabled) {
  56680. byteArray[0] = firstByte;
  56681. for (var i = 1; i < totalBytes; i++) {
  56682. byteArray[i] = data[seiPtr++];
  56683. }
  56684. }
  56685. samples.push({
  56686. type: userDataType,
  56687. payloadType: payloadType,
  56688. pts: pts,
  56689. bytes: byteArray
  56690. });
  56691. }
  56692. }
  56693. }
  56694. }
  56695. } else if (payloadType === 5 && payloadSize < leftOver) {
  56696. endOfCaptions = true;
  56697. if (payloadSize > 16) {
  56698. var uuidStrArray = [];
  56699. for (var _i2 = 0; _i2 < 16; _i2++) {
  56700. var _b = data[seiPtr++].toString(16);
  56701. uuidStrArray.push(_b.length == 1 ? '0' + _b : _b);
  56702. if (_i2 === 3 || _i2 === 5 || _i2 === 7 || _i2 === 9) {
  56703. uuidStrArray.push('-');
  56704. }
  56705. }
  56706. var length = payloadSize - 16;
  56707. var userDataBytes = new Uint8Array(length);
  56708. for (var _i3 = 0; _i3 < length; _i3++) {
  56709. userDataBytes[_i3] = data[seiPtr++];
  56710. }
  56711. samples.push({
  56712. payloadType: payloadType,
  56713. pts: pts,
  56714. uuid: uuidStrArray.join(''),
  56715. userData: (0,_demux_id3__WEBPACK_IMPORTED_MODULE_2__.utf8ArrayToStr)(userDataBytes),
  56716. userDataBytes: userDataBytes
  56717. });
  56718. }
  56719. } else if (payloadSize < leftOver) {
  56720. seiPtr += payloadSize;
  56721. } else if (payloadSize > leftOver) {
  56722. break;
  56723. }
  56724. }
  56725. }
  56726. /**
  56727. * remove Emulation Prevention bytes from a RBSP
  56728. */
  56729. function discardEPB(data) {
  56730. var length = data.byteLength;
  56731. var EPBPositions = [];
  56732. var i = 1;
  56733. // Find all `Emulation Prevention Bytes`
  56734. while (i < length - 2) {
  56735. if (data[i] === 0 && data[i + 1] === 0 && data[i + 2] === 0x03) {
  56736. EPBPositions.push(i + 2);
  56737. i += 2;
  56738. } else {
  56739. i++;
  56740. }
  56741. }
  56742. // If no Emulation Prevention Bytes were found just return the original
  56743. // array
  56744. if (EPBPositions.length === 0) {
  56745. return data;
  56746. }
  56747. // Create a new array to hold the NAL unit data
  56748. var newLength = length - EPBPositions.length;
  56749. var newData = new Uint8Array(newLength);
  56750. var sourceIndex = 0;
  56751. for (i = 0; i < newLength; sourceIndex++, i++) {
  56752. if (sourceIndex === EPBPositions[0]) {
  56753. // Skip this byte
  56754. sourceIndex++;
  56755. // Remove this position index
  56756. EPBPositions.shift();
  56757. }
  56758. newData[i] = data[sourceIndex];
  56759. }
  56760. return newData;
  56761. }
  56762. function parseEmsg(data) {
  56763. var version = data[0];
  56764. var schemeIdUri = '';
  56765. var value = '';
  56766. var timeScale = 0;
  56767. var presentationTimeDelta = 0;
  56768. var presentationTime = 0;
  56769. var eventDuration = 0;
  56770. var id = 0;
  56771. var offset = 0;
  56772. if (version === 0) {
  56773. while (bin2str(data.subarray(offset, offset + 1)) !== '\0') {
  56774. schemeIdUri += bin2str(data.subarray(offset, offset + 1));
  56775. offset += 1;
  56776. }
  56777. schemeIdUri += bin2str(data.subarray(offset, offset + 1));
  56778. offset += 1;
  56779. while (bin2str(data.subarray(offset, offset + 1)) !== '\0') {
  56780. value += bin2str(data.subarray(offset, offset + 1));
  56781. offset += 1;
  56782. }
  56783. value += bin2str(data.subarray(offset, offset + 1));
  56784. offset += 1;
  56785. timeScale = readUint32(data, 12);
  56786. presentationTimeDelta = readUint32(data, 16);
  56787. eventDuration = readUint32(data, 20);
  56788. id = readUint32(data, 24);
  56789. offset = 28;
  56790. } else if (version === 1) {
  56791. offset += 4;
  56792. timeScale = readUint32(data, offset);
  56793. offset += 4;
  56794. var leftPresentationTime = readUint32(data, offset);
  56795. offset += 4;
  56796. var rightPresentationTime = readUint32(data, offset);
  56797. offset += 4;
  56798. presentationTime = Math.pow(2, 32) * leftPresentationTime + rightPresentationTime;
  56799. if (!Number.isSafeInteger(presentationTime)) {
  56800. presentationTime = Number.MAX_SAFE_INTEGER;
  56801. // eslint-disable-next-line no-console
  56802. console.warn('Presentation time exceeds safe integer limit and wrapped to max safe integer in parsing emsg box');
  56803. }
  56804. eventDuration = readUint32(data, offset);
  56805. offset += 4;
  56806. id = readUint32(data, offset);
  56807. offset += 4;
  56808. while (bin2str(data.subarray(offset, offset + 1)) !== '\0') {
  56809. schemeIdUri += bin2str(data.subarray(offset, offset + 1));
  56810. offset += 1;
  56811. }
  56812. schemeIdUri += bin2str(data.subarray(offset, offset + 1));
  56813. offset += 1;
  56814. while (bin2str(data.subarray(offset, offset + 1)) !== '\0') {
  56815. value += bin2str(data.subarray(offset, offset + 1));
  56816. offset += 1;
  56817. }
  56818. value += bin2str(data.subarray(offset, offset + 1));
  56819. offset += 1;
  56820. }
  56821. var payload = data.subarray(offset, data.byteLength);
  56822. return {
  56823. schemeIdUri: schemeIdUri,
  56824. value: value,
  56825. timeScale: timeScale,
  56826. presentationTime: presentationTime,
  56827. presentationTimeDelta: presentationTimeDelta,
  56828. eventDuration: eventDuration,
  56829. id: id,
  56830. payload: payload
  56831. };
  56832. }
  56833. function mp4Box(type) {
  56834. for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  56835. payload[_key - 1] = arguments[_key];
  56836. }
  56837. var len = payload.length;
  56838. var size = 8;
  56839. var i = len;
  56840. while (i--) {
  56841. size += payload[i].byteLength;
  56842. }
  56843. var result = new Uint8Array(size);
  56844. result[0] = size >> 24 & 0xff;
  56845. result[1] = size >> 16 & 0xff;
  56846. result[2] = size >> 8 & 0xff;
  56847. result[3] = size & 0xff;
  56848. result.set(type, 4);
  56849. for (i = 0, size = 8; i < len; i++) {
  56850. result.set(payload[i], size);
  56851. size += payload[i].byteLength;
  56852. }
  56853. return result;
  56854. }
  56855. function mp4pssh(systemId, keyids, data) {
  56856. if (systemId.byteLength !== 16) {
  56857. throw new RangeError('Invalid system id');
  56858. }
  56859. var version;
  56860. var kids;
  56861. if (keyids) {
  56862. version = 1;
  56863. kids = new Uint8Array(keyids.length * 16);
  56864. for (var ix = 0; ix < keyids.length; ix++) {
  56865. var k = keyids[ix]; // uint8array
  56866. if (k.byteLength !== 16) {
  56867. throw new RangeError('Invalid key');
  56868. }
  56869. kids.set(k, ix * 16);
  56870. }
  56871. } else {
  56872. version = 0;
  56873. kids = new Uint8Array();
  56874. }
  56875. var kidCount;
  56876. if (version > 0) {
  56877. kidCount = new Uint8Array(4);
  56878. if (keyids.length > 0) {
  56879. new DataView(kidCount.buffer).setUint32(0, keyids.length, false);
  56880. }
  56881. } else {
  56882. kidCount = new Uint8Array();
  56883. }
  56884. var dataSize = new Uint8Array(4);
  56885. if (data && data.byteLength > 0) {
  56886. new DataView(dataSize.buffer).setUint32(0, data.byteLength, false);
  56887. }
  56888. return mp4Box([112, 115, 115, 104], new Uint8Array([version, 0x00, 0x00, 0x00 // Flags
  56889. ]), systemId,
  56890. // 16 bytes
  56891. kidCount, kids, dataSize, data || new Uint8Array());
  56892. }
  56893. function parsePssh(initData) {
  56894. if (!(initData instanceof ArrayBuffer) || initData.byteLength < 32) {
  56895. return null;
  56896. }
  56897. var result = {
  56898. version: 0,
  56899. systemId: '',
  56900. kids: null,
  56901. data: null
  56902. };
  56903. var view = new DataView(initData);
  56904. var boxSize = view.getUint32(0);
  56905. if (initData.byteLength !== boxSize && boxSize > 44) {
  56906. return null;
  56907. }
  56908. var type = view.getUint32(4);
  56909. if (type !== 0x70737368) {
  56910. return null;
  56911. }
  56912. result.version = view.getUint32(8) >>> 24;
  56913. if (result.version > 1) {
  56914. return null;
  56915. }
  56916. result.systemId = _hex__WEBPACK_IMPORTED_MODULE_4__["default"].hexDump(new Uint8Array(initData, 12, 16));
  56917. var dataSizeOrKidCount = view.getUint32(28);
  56918. if (result.version === 0) {
  56919. if (boxSize - 32 < dataSizeOrKidCount) {
  56920. return null;
  56921. }
  56922. result.data = new Uint8Array(initData, 32, dataSizeOrKidCount);
  56923. } else if (result.version === 1) {
  56924. result.kids = [];
  56925. for (var i = 0; i < dataSizeOrKidCount; i++) {
  56926. result.kids.push(new Uint8Array(initData, 32 + i * 16, 16));
  56927. }
  56928. }
  56929. return result;
  56930. }
  56931. /***/ }),
  56932. /***/ "./src/utils/numeric-encoding-utils.ts":
  56933. /*!*********************************************!*\
  56934. !*** ./src/utils/numeric-encoding-utils.ts ***!
  56935. \*********************************************/
  56936. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  56937. "use strict";
  56938. __webpack_require__.r(__webpack_exports__);
  56939. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  56940. /* harmony export */ "base64Decode": () => (/* binding */ base64Decode),
  56941. /* harmony export */ "base64DecodeToStr": () => (/* binding */ base64DecodeToStr),
  56942. /* harmony export */ "base64Encode": () => (/* binding */ base64Encode),
  56943. /* harmony export */ "base64ToBase64Url": () => (/* binding */ base64ToBase64Url),
  56944. /* harmony export */ "base64UrlEncode": () => (/* binding */ base64UrlEncode),
  56945. /* harmony export */ "strToBase64Encode": () => (/* binding */ strToBase64Encode)
  56946. /* harmony export */ });
  56947. function base64ToBase64Url(base64encodedStr) {
  56948. return base64encodedStr.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
  56949. }
  56950. function strToBase64Encode(str) {
  56951. return btoa(str);
  56952. }
  56953. function base64DecodeToStr(str) {
  56954. return atob(str);
  56955. }
  56956. function base64Encode(input) {
  56957. return btoa(String.fromCharCode.apply(String, input));
  56958. }
  56959. function base64UrlEncode(input) {
  56960. return base64ToBase64Url(base64Encode(input));
  56961. }
  56962. function base64Decode(base64encodedStr) {
  56963. return Uint8Array.from(atob(base64encodedStr), function (c) {
  56964. return c.charCodeAt(0);
  56965. });
  56966. }
  56967. /***/ }),
  56968. /***/ "./src/utils/output-filter.ts":
  56969. /*!************************************!*\
  56970. !*** ./src/utils/output-filter.ts ***!
  56971. \************************************/
  56972. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  56973. "use strict";
  56974. __webpack_require__.r(__webpack_exports__);
  56975. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  56976. /* harmony export */ "default": () => (/* binding */ OutputFilter)
  56977. /* harmony export */ });
  56978. var OutputFilter = /*#__PURE__*/function () {
  56979. function OutputFilter(timelineController, trackName) {
  56980. this.timelineController = void 0;
  56981. this.cueRanges = [];
  56982. this.trackName = void 0;
  56983. this.startTime = null;
  56984. this.endTime = null;
  56985. this.screen = null;
  56986. this.timelineController = timelineController;
  56987. this.trackName = trackName;
  56988. }
  56989. var _proto = OutputFilter.prototype;
  56990. _proto.dispatchCue = function dispatchCue() {
  56991. if (this.startTime === null) {
  56992. return;
  56993. }
  56994. this.timelineController.addCues(this.trackName, this.startTime, this.endTime, this.screen, this.cueRanges);
  56995. this.startTime = null;
  56996. };
  56997. _proto.newCue = function newCue(startTime, endTime, screen) {
  56998. if (this.startTime === null || this.startTime > startTime) {
  56999. this.startTime = startTime;
  57000. }
  57001. this.endTime = endTime;
  57002. this.screen = screen;
  57003. this.timelineController.createCaptionsTrack(this.trackName);
  57004. };
  57005. _proto.reset = function reset() {
  57006. this.cueRanges = [];
  57007. this.startTime = null;
  57008. };
  57009. return OutputFilter;
  57010. }();
  57011. /***/ }),
  57012. /***/ "./src/utils/texttrack-utils.ts":
  57013. /*!**************************************!*\
  57014. !*** ./src/utils/texttrack-utils.ts ***!
  57015. \**************************************/
  57016. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57017. "use strict";
  57018. __webpack_require__.r(__webpack_exports__);
  57019. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57020. /* harmony export */ "addCueToTrack": () => (/* binding */ addCueToTrack),
  57021. /* harmony export */ "clearCurrentCues": () => (/* binding */ clearCurrentCues),
  57022. /* harmony export */ "getCuesInRange": () => (/* binding */ getCuesInRange),
  57023. /* harmony export */ "removeCuesInRange": () => (/* binding */ removeCuesInRange),
  57024. /* harmony export */ "sendAddTrackEvent": () => (/* binding */ sendAddTrackEvent)
  57025. /* harmony export */ });
  57026. /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./logger */ "./src/utils/logger.ts");
  57027. function sendAddTrackEvent(track, videoEl) {
  57028. var event;
  57029. try {
  57030. event = new Event('addtrack');
  57031. } catch (err) {
  57032. // for IE11
  57033. event = document.createEvent('Event');
  57034. event.initEvent('addtrack', false, false);
  57035. }
  57036. event.track = track;
  57037. videoEl.dispatchEvent(event);
  57038. }
  57039. function addCueToTrack(track, cue) {
  57040. // Sometimes there are cue overlaps on segmented vtts so the same
  57041. // cue can appear more than once in different vtt files.
  57042. // This avoid showing duplicated cues with same timecode and text.
  57043. var mode = track.mode;
  57044. if (mode === 'disabled') {
  57045. track.mode = 'hidden';
  57046. }
  57047. if (track.cues && !track.cues.getCueById(cue.id)) {
  57048. try {
  57049. track.addCue(cue);
  57050. if (!track.cues.getCueById(cue.id)) {
  57051. throw new Error("addCue is failed for: " + cue);
  57052. }
  57053. } catch (err) {
  57054. _logger__WEBPACK_IMPORTED_MODULE_0__.logger.debug("[texttrack-utils]: " + err);
  57055. var textTrackCue = new self.TextTrackCue(cue.startTime, cue.endTime, cue.text);
  57056. textTrackCue.id = cue.id;
  57057. track.addCue(textTrackCue);
  57058. }
  57059. }
  57060. if (mode === 'disabled') {
  57061. track.mode = mode;
  57062. }
  57063. }
  57064. function clearCurrentCues(track) {
  57065. // When track.mode is disabled, track.cues will be null.
  57066. // To guarantee the removal of cues, we need to temporarily
  57067. // change the mode to hidden
  57068. var mode = track.mode;
  57069. if (mode === 'disabled') {
  57070. track.mode = 'hidden';
  57071. }
  57072. if (track.cues) {
  57073. for (var i = track.cues.length; i--;) {
  57074. track.removeCue(track.cues[i]);
  57075. }
  57076. }
  57077. if (mode === 'disabled') {
  57078. track.mode = mode;
  57079. }
  57080. }
  57081. function removeCuesInRange(track, start, end, predicate) {
  57082. var mode = track.mode;
  57083. if (mode === 'disabled') {
  57084. track.mode = 'hidden';
  57085. }
  57086. if (track.cues && track.cues.length > 0) {
  57087. var cues = getCuesInRange(track.cues, start, end);
  57088. for (var i = 0; i < cues.length; i++) {
  57089. if (!predicate || predicate(cues[i])) {
  57090. track.removeCue(cues[i]);
  57091. }
  57092. }
  57093. }
  57094. if (mode === 'disabled') {
  57095. track.mode = mode;
  57096. }
  57097. }
  57098. // Find first cue starting after given time.
  57099. // Modified version of binary search O(log(n)).
  57100. function getFirstCueIndexAfterTime(cues, time) {
  57101. // If first cue starts after time, start there
  57102. if (time < cues[0].startTime) {
  57103. return 0;
  57104. }
  57105. // If the last cue ends before time there is no overlap
  57106. var len = cues.length - 1;
  57107. if (time > cues[len].endTime) {
  57108. return -1;
  57109. }
  57110. var left = 0;
  57111. var right = len;
  57112. while (left <= right) {
  57113. var mid = Math.floor((right + left) / 2);
  57114. if (time < cues[mid].startTime) {
  57115. right = mid - 1;
  57116. } else if (time > cues[mid].startTime && left < len) {
  57117. left = mid + 1;
  57118. } else {
  57119. // If it's not lower or higher, it must be equal.
  57120. return mid;
  57121. }
  57122. }
  57123. // At this point, left and right have swapped.
  57124. // No direct match was found, left or right element must be the closest. Check which one has the smallest diff.
  57125. return cues[left].startTime - time < time - cues[right].startTime ? left : right;
  57126. }
  57127. function getCuesInRange(cues, start, end) {
  57128. var cuesFound = [];
  57129. var firstCueInRange = getFirstCueIndexAfterTime(cues, start);
  57130. if (firstCueInRange > -1) {
  57131. for (var i = firstCueInRange, len = cues.length; i < len; i++) {
  57132. var _cue = cues[i];
  57133. if (_cue.startTime >= start && _cue.endTime <= end) {
  57134. cuesFound.push(_cue);
  57135. } else if (_cue.startTime > end) {
  57136. return cuesFound;
  57137. }
  57138. }
  57139. }
  57140. return cuesFound;
  57141. }
  57142. /***/ }),
  57143. /***/ "./src/utils/time-ranges.ts":
  57144. /*!**********************************!*\
  57145. !*** ./src/utils/time-ranges.ts ***!
  57146. \**********************************/
  57147. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57148. "use strict";
  57149. __webpack_require__.r(__webpack_exports__);
  57150. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57151. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  57152. /* harmony export */ });
  57153. /**
  57154. * TimeRanges to string helper
  57155. */
  57156. var TimeRanges = {
  57157. toString: function toString(r) {
  57158. var log = '';
  57159. var len = r.length;
  57160. for (var i = 0; i < len; i++) {
  57161. log += "[" + r.start(i).toFixed(3) + "-" + r.end(i).toFixed(3) + "]";
  57162. }
  57163. return log;
  57164. }
  57165. };
  57166. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (TimeRanges);
  57167. /***/ }),
  57168. /***/ "./src/utils/timescale-conversion.ts":
  57169. /*!*******************************************!*\
  57170. !*** ./src/utils/timescale-conversion.ts ***!
  57171. \*******************************************/
  57172. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57173. "use strict";
  57174. __webpack_require__.r(__webpack_exports__);
  57175. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57176. /* harmony export */ "toMpegTsClockFromTimescale": () => (/* binding */ toMpegTsClockFromTimescale),
  57177. /* harmony export */ "toMsFromMpegTsClock": () => (/* binding */ toMsFromMpegTsClock),
  57178. /* harmony export */ "toTimescaleFromBase": () => (/* binding */ toTimescaleFromBase),
  57179. /* harmony export */ "toTimescaleFromScale": () => (/* binding */ toTimescaleFromScale)
  57180. /* harmony export */ });
  57181. var MPEG_TS_CLOCK_FREQ_HZ = 90000;
  57182. function toTimescaleFromBase(value, destScale, srcBase, round) {
  57183. if (srcBase === void 0) {
  57184. srcBase = 1;
  57185. }
  57186. if (round === void 0) {
  57187. round = false;
  57188. }
  57189. var result = value * destScale * srcBase; // equivalent to `(value * scale) / (1 / base)`
  57190. return round ? Math.round(result) : result;
  57191. }
  57192. function toTimescaleFromScale(value, destScale, srcScale, round) {
  57193. if (srcScale === void 0) {
  57194. srcScale = 1;
  57195. }
  57196. if (round === void 0) {
  57197. round = false;
  57198. }
  57199. return toTimescaleFromBase(value, destScale, 1 / srcScale, round);
  57200. }
  57201. function toMsFromMpegTsClock(value, round) {
  57202. if (round === void 0) {
  57203. round = false;
  57204. }
  57205. return toTimescaleFromBase(value, 1000, 1 / MPEG_TS_CLOCK_FREQ_HZ, round);
  57206. }
  57207. function toMpegTsClockFromTimescale(value, srcScale) {
  57208. if (srcScale === void 0) {
  57209. srcScale = 1;
  57210. }
  57211. return toTimescaleFromBase(value, MPEG_TS_CLOCK_FREQ_HZ, 1 / srcScale);
  57212. }
  57213. /***/ }),
  57214. /***/ "./src/utils/typed-array.ts":
  57215. /*!**********************************!*\
  57216. !*** ./src/utils/typed-array.ts ***!
  57217. \**********************************/
  57218. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57219. "use strict";
  57220. __webpack_require__.r(__webpack_exports__);
  57221. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57222. /* harmony export */ "sliceUint8": () => (/* binding */ sliceUint8)
  57223. /* harmony export */ });
  57224. function sliceUint8(array, start, end) {
  57225. // @ts-expect-error This polyfills IE11 usage of Uint8Array slice.
  57226. // It always exists in the TypeScript definition so fails, but it fails at runtime on IE11.
  57227. return Uint8Array.prototype.slice ? array.slice(start, end) : new Uint8Array(Array.prototype.slice.call(array, start, end));
  57228. }
  57229. /***/ }),
  57230. /***/ "./src/utils/vttcue.ts":
  57231. /*!*****************************!*\
  57232. !*** ./src/utils/vttcue.ts ***!
  57233. \*****************************/
  57234. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57235. "use strict";
  57236. __webpack_require__.r(__webpack_exports__);
  57237. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57238. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  57239. /* harmony export */ });
  57240. /**
  57241. * Copyright 2013 vtt.js Contributors
  57242. *
  57243. * Licensed under the Apache License, Version 2.0 (the 'License');
  57244. * you may not use this file except in compliance with the License.
  57245. * You may obtain a copy of the License at
  57246. *
  57247. * http://www.apache.org/licenses/LICENSE-2.0
  57248. *
  57249. * Unless required by applicable law or agreed to in writing, software
  57250. * distributed under the License is distributed on an 'AS IS' BASIS,
  57251. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  57252. * See the License for the specific language governing permissions and
  57253. * limitations under the License.
  57254. */
  57255. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((function () {
  57256. if (typeof self !== 'undefined' && self.VTTCue) {
  57257. return self.VTTCue;
  57258. }
  57259. var AllowedDirections = ['', 'lr', 'rl'];
  57260. var AllowedAlignments = ['start', 'middle', 'end', 'left', 'right'];
  57261. function isAllowedValue(allowed, value) {
  57262. if (typeof value !== 'string') {
  57263. return false;
  57264. }
  57265. // necessary for assuring the generic conforms to the Array interface
  57266. if (!Array.isArray(allowed)) {
  57267. return false;
  57268. }
  57269. // reset the type so that the next narrowing works well
  57270. var lcValue = value.toLowerCase();
  57271. // use the allow list to narrow the type to a specific subset of strings
  57272. if (~allowed.indexOf(lcValue)) {
  57273. return lcValue;
  57274. }
  57275. return false;
  57276. }
  57277. function findDirectionSetting(value) {
  57278. return isAllowedValue(AllowedDirections, value);
  57279. }
  57280. function findAlignSetting(value) {
  57281. return isAllowedValue(AllowedAlignments, value);
  57282. }
  57283. function extend(obj) {
  57284. for (var _len = arguments.length, rest = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
  57285. rest[_key - 1] = arguments[_key];
  57286. }
  57287. var i = 1;
  57288. for (; i < arguments.length; i++) {
  57289. var cobj = arguments[i];
  57290. for (var p in cobj) {
  57291. obj[p] = cobj[p];
  57292. }
  57293. }
  57294. return obj;
  57295. }
  57296. function VTTCue(startTime, endTime, text) {
  57297. var cue = this;
  57298. var baseObj = {
  57299. enumerable: true
  57300. };
  57301. /**
  57302. * Shim implementation specific properties. These properties are not in
  57303. * the spec.
  57304. */
  57305. // Lets us know when the VTTCue's data has changed in such a way that we need
  57306. // to recompute its display state. This lets us compute its display state
  57307. // lazily.
  57308. cue.hasBeenReset = false;
  57309. /**
  57310. * VTTCue and TextTrackCue properties
  57311. * http://dev.w3.org/html5/webvtt/#vttcue-interface
  57312. */
  57313. var _id = '';
  57314. var _pauseOnExit = false;
  57315. var _startTime = startTime;
  57316. var _endTime = endTime;
  57317. var _text = text;
  57318. var _region = null;
  57319. var _vertical = '';
  57320. var _snapToLines = true;
  57321. var _line = 'auto';
  57322. var _lineAlign = 'start';
  57323. var _position = 50;
  57324. var _positionAlign = 'middle';
  57325. var _size = 50;
  57326. var _align = 'middle';
  57327. Object.defineProperty(cue, 'id', extend({}, baseObj, {
  57328. get: function get() {
  57329. return _id;
  57330. },
  57331. set: function set(value) {
  57332. _id = '' + value;
  57333. }
  57334. }));
  57335. Object.defineProperty(cue, 'pauseOnExit', extend({}, baseObj, {
  57336. get: function get() {
  57337. return _pauseOnExit;
  57338. },
  57339. set: function set(value) {
  57340. _pauseOnExit = !!value;
  57341. }
  57342. }));
  57343. Object.defineProperty(cue, 'startTime', extend({}, baseObj, {
  57344. get: function get() {
  57345. return _startTime;
  57346. },
  57347. set: function set(value) {
  57348. if (typeof value !== 'number') {
  57349. throw new TypeError('Start time must be set to a number.');
  57350. }
  57351. _startTime = value;
  57352. this.hasBeenReset = true;
  57353. }
  57354. }));
  57355. Object.defineProperty(cue, 'endTime', extend({}, baseObj, {
  57356. get: function get() {
  57357. return _endTime;
  57358. },
  57359. set: function set(value) {
  57360. if (typeof value !== 'number') {
  57361. throw new TypeError('End time must be set to a number.');
  57362. }
  57363. _endTime = value;
  57364. this.hasBeenReset = true;
  57365. }
  57366. }));
  57367. Object.defineProperty(cue, 'text', extend({}, baseObj, {
  57368. get: function get() {
  57369. return _text;
  57370. },
  57371. set: function set(value) {
  57372. _text = '' + value;
  57373. this.hasBeenReset = true;
  57374. }
  57375. }));
  57376. // todo: implement VTTRegion polyfill?
  57377. Object.defineProperty(cue, 'region', extend({}, baseObj, {
  57378. get: function get() {
  57379. return _region;
  57380. },
  57381. set: function set(value) {
  57382. _region = value;
  57383. this.hasBeenReset = true;
  57384. }
  57385. }));
  57386. Object.defineProperty(cue, 'vertical', extend({}, baseObj, {
  57387. get: function get() {
  57388. return _vertical;
  57389. },
  57390. set: function set(value) {
  57391. var setting = findDirectionSetting(value);
  57392. // Have to check for false because the setting an be an empty string.
  57393. if (setting === false) {
  57394. throw new SyntaxError('An invalid or illegal string was specified.');
  57395. }
  57396. _vertical = setting;
  57397. this.hasBeenReset = true;
  57398. }
  57399. }));
  57400. Object.defineProperty(cue, 'snapToLines', extend({}, baseObj, {
  57401. get: function get() {
  57402. return _snapToLines;
  57403. },
  57404. set: function set(value) {
  57405. _snapToLines = !!value;
  57406. this.hasBeenReset = true;
  57407. }
  57408. }));
  57409. Object.defineProperty(cue, 'line', extend({}, baseObj, {
  57410. get: function get() {
  57411. return _line;
  57412. },
  57413. set: function set(value) {
  57414. if (typeof value !== 'number' && value !== 'auto') {
  57415. throw new SyntaxError('An invalid number or illegal string was specified.');
  57416. }
  57417. _line = value;
  57418. this.hasBeenReset = true;
  57419. }
  57420. }));
  57421. Object.defineProperty(cue, 'lineAlign', extend({}, baseObj, {
  57422. get: function get() {
  57423. return _lineAlign;
  57424. },
  57425. set: function set(value) {
  57426. var setting = findAlignSetting(value);
  57427. if (!setting) {
  57428. throw new SyntaxError('An invalid or illegal string was specified.');
  57429. }
  57430. _lineAlign = setting;
  57431. this.hasBeenReset = true;
  57432. }
  57433. }));
  57434. Object.defineProperty(cue, 'position', extend({}, baseObj, {
  57435. get: function get() {
  57436. return _position;
  57437. },
  57438. set: function set(value) {
  57439. if (value < 0 || value > 100) {
  57440. throw new Error('Position must be between 0 and 100.');
  57441. }
  57442. _position = value;
  57443. this.hasBeenReset = true;
  57444. }
  57445. }));
  57446. Object.defineProperty(cue, 'positionAlign', extend({}, baseObj, {
  57447. get: function get() {
  57448. return _positionAlign;
  57449. },
  57450. set: function set(value) {
  57451. var setting = findAlignSetting(value);
  57452. if (!setting) {
  57453. throw new SyntaxError('An invalid or illegal string was specified.');
  57454. }
  57455. _positionAlign = setting;
  57456. this.hasBeenReset = true;
  57457. }
  57458. }));
  57459. Object.defineProperty(cue, 'size', extend({}, baseObj, {
  57460. get: function get() {
  57461. return _size;
  57462. },
  57463. set: function set(value) {
  57464. if (value < 0 || value > 100) {
  57465. throw new Error('Size must be between 0 and 100.');
  57466. }
  57467. _size = value;
  57468. this.hasBeenReset = true;
  57469. }
  57470. }));
  57471. Object.defineProperty(cue, 'align', extend({}, baseObj, {
  57472. get: function get() {
  57473. return _align;
  57474. },
  57475. set: function set(value) {
  57476. var setting = findAlignSetting(value);
  57477. if (!setting) {
  57478. throw new SyntaxError('An invalid or illegal string was specified.');
  57479. }
  57480. _align = setting;
  57481. this.hasBeenReset = true;
  57482. }
  57483. }));
  57484. /**
  57485. * Other <track> spec defined properties
  57486. */
  57487. // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state
  57488. cue.displayState = undefined;
  57489. }
  57490. /**
  57491. * VTTCue methods
  57492. */
  57493. VTTCue.prototype.getCueAsHTML = function () {
  57494. // Assume WebVTT.convertCueToDOMTree is on the global.
  57495. var WebVTT = self.WebVTT;
  57496. return WebVTT.convertCueToDOMTree(self, this.text);
  57497. };
  57498. // this is a polyfill hack
  57499. return VTTCue;
  57500. })());
  57501. /***/ }),
  57502. /***/ "./src/utils/vttparser.ts":
  57503. /*!********************************!*\
  57504. !*** ./src/utils/vttparser.ts ***!
  57505. \********************************/
  57506. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57507. "use strict";
  57508. __webpack_require__.r(__webpack_exports__);
  57509. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57510. /* harmony export */ "VTTParser": () => (/* binding */ VTTParser),
  57511. /* harmony export */ "fixLineBreaks": () => (/* binding */ fixLineBreaks),
  57512. /* harmony export */ "parseTimeStamp": () => (/* binding */ parseTimeStamp)
  57513. /* harmony export */ });
  57514. /* harmony import */ var _vttcue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./vttcue */ "./src/utils/vttcue.ts");
  57515. /*
  57516. * Source: https://github.com/mozilla/vtt.js/blob/master/dist/vtt.js
  57517. */
  57518. var StringDecoder = /*#__PURE__*/function () {
  57519. function StringDecoder() {}
  57520. var _proto = StringDecoder.prototype;
  57521. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  57522. _proto.decode = function decode(data, options) {
  57523. if (!data) {
  57524. return '';
  57525. }
  57526. if (typeof data !== 'string') {
  57527. throw new Error('Error - expected string data.');
  57528. }
  57529. return decodeURIComponent(encodeURIComponent(data));
  57530. };
  57531. return StringDecoder;
  57532. }(); // Try to parse input as a time stamp.
  57533. function parseTimeStamp(input) {
  57534. function computeSeconds(h, m, s, f) {
  57535. return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + parseFloat(f || 0);
  57536. }
  57537. var m = input.match(/^(?:(\d+):)?(\d{2}):(\d{2})(\.\d+)?/);
  57538. if (!m) {
  57539. return null;
  57540. }
  57541. if (parseFloat(m[2]) > 59) {
  57542. // Timestamp takes the form of [hours]:[minutes].[milliseconds]
  57543. // First position is hours as it's over 59.
  57544. return computeSeconds(m[2], m[3], 0, m[4]);
  57545. }
  57546. // Timestamp takes the form of [hours (optional)]:[minutes]:[seconds].[milliseconds]
  57547. return computeSeconds(m[1], m[2], m[3], m[4]);
  57548. }
  57549. // A settings object holds key/value pairs and will ignore anything but the first
  57550. // assignment to a specific key.
  57551. var Settings = /*#__PURE__*/function () {
  57552. function Settings() {
  57553. this.values = Object.create(null);
  57554. }
  57555. var _proto2 = Settings.prototype;
  57556. // Only accept the first assignment to any key.
  57557. _proto2.set = function set(k, v) {
  57558. if (!this.get(k) && v !== '') {
  57559. this.values[k] = v;
  57560. }
  57561. }
  57562. // Return the value for a key, or a default value.
  57563. // If 'defaultKey' is passed then 'dflt' is assumed to be an object with
  57564. // a number of possible default values as properties where 'defaultKey' is
  57565. // the key of the property that will be chosen; otherwise it's assumed to be
  57566. // a single value.
  57567. ;
  57568. _proto2.get = function get(k, dflt, defaultKey) {
  57569. if (defaultKey) {
  57570. return this.has(k) ? this.values[k] : dflt[defaultKey];
  57571. }
  57572. return this.has(k) ? this.values[k] : dflt;
  57573. }
  57574. // Check whether we have a value for a key.
  57575. ;
  57576. _proto2.has = function has(k) {
  57577. return k in this.values;
  57578. }
  57579. // Accept a setting if its one of the given alternatives.
  57580. ;
  57581. _proto2.alt = function alt(k, v, a) {
  57582. for (var n = 0; n < a.length; ++n) {
  57583. if (v === a[n]) {
  57584. this.set(k, v);
  57585. break;
  57586. }
  57587. }
  57588. }
  57589. // Accept a setting if its a valid (signed) integer.
  57590. ;
  57591. _proto2.integer = function integer(k, v) {
  57592. if (/^-?\d+$/.test(v)) {
  57593. // integer
  57594. this.set(k, parseInt(v, 10));
  57595. }
  57596. }
  57597. // Accept a setting if its a valid percentage.
  57598. ;
  57599. _proto2.percent = function percent(k, v) {
  57600. if (/^([\d]{1,3})(\.[\d]*)?%$/.test(v)) {
  57601. var percent = parseFloat(v);
  57602. if (percent >= 0 && percent <= 100) {
  57603. this.set(k, percent);
  57604. return true;
  57605. }
  57606. }
  57607. return false;
  57608. };
  57609. return Settings;
  57610. }(); // Helper function to parse input into groups separated by 'groupDelim', and
  57611. // interpret each group as a key/value pair separated by 'keyValueDelim'.
  57612. function parseOptions(input, callback, keyValueDelim, groupDelim) {
  57613. var groups = groupDelim ? input.split(groupDelim) : [input];
  57614. for (var i in groups) {
  57615. if (typeof groups[i] !== 'string') {
  57616. continue;
  57617. }
  57618. var kv = groups[i].split(keyValueDelim);
  57619. if (kv.length !== 2) {
  57620. continue;
  57621. }
  57622. var _k = kv[0];
  57623. var _v = kv[1];
  57624. callback(_k, _v);
  57625. }
  57626. }
  57627. var defaults = new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0, 0, '');
  57628. // 'middle' was changed to 'center' in the spec: https://github.com/w3c/webvtt/pull/244
  57629. // Safari doesn't yet support this change, but FF and Chrome do.
  57630. var center = defaults.align === 'middle' ? 'middle' : 'center';
  57631. function parseCue(input, cue, regionList) {
  57632. // Remember the original input if we need to throw an error.
  57633. var oInput = input;
  57634. // 4.1 WebVTT timestamp
  57635. function consumeTimeStamp() {
  57636. var ts = parseTimeStamp(input);
  57637. if (ts === null) {
  57638. throw new Error('Malformed timestamp: ' + oInput);
  57639. }
  57640. // Remove time stamp from input.
  57641. input = input.replace(/^[^\sa-zA-Z-]+/, '');
  57642. return ts;
  57643. }
  57644. // 4.4.2 WebVTT cue settings
  57645. function consumeCueSettings(input, cue) {
  57646. var settings = new Settings();
  57647. parseOptions(input, function (k, v) {
  57648. var vals;
  57649. switch (k) {
  57650. case 'region':
  57651. // Find the last region we parsed with the same region id.
  57652. for (var i = regionList.length - 1; i >= 0; i--) {
  57653. if (regionList[i].id === v) {
  57654. settings.set(k, regionList[i].region);
  57655. break;
  57656. }
  57657. }
  57658. break;
  57659. case 'vertical':
  57660. settings.alt(k, v, ['rl', 'lr']);
  57661. break;
  57662. case 'line':
  57663. vals = v.split(',');
  57664. settings.integer(k, vals[0]);
  57665. if (settings.percent(k, vals[0])) {
  57666. settings.set('snapToLines', false);
  57667. }
  57668. settings.alt(k, vals[0], ['auto']);
  57669. if (vals.length === 2) {
  57670. settings.alt('lineAlign', vals[1], ['start', center, 'end']);
  57671. }
  57672. break;
  57673. case 'position':
  57674. vals = v.split(',');
  57675. settings.percent(k, vals[0]);
  57676. if (vals.length === 2) {
  57677. settings.alt('positionAlign', vals[1], ['start', center, 'end', 'line-left', 'line-right', 'auto']);
  57678. }
  57679. break;
  57680. case 'size':
  57681. settings.percent(k, v);
  57682. break;
  57683. case 'align':
  57684. settings.alt(k, v, ['start', center, 'end', 'left', 'right']);
  57685. break;
  57686. }
  57687. }, /:/, /\s/);
  57688. // Apply default values for any missing fields.
  57689. cue.region = settings.get('region', null);
  57690. cue.vertical = settings.get('vertical', '');
  57691. var line = settings.get('line', 'auto');
  57692. if (line === 'auto' && defaults.line === -1) {
  57693. // set numeric line number for Safari
  57694. line = -1;
  57695. }
  57696. cue.line = line;
  57697. cue.lineAlign = settings.get('lineAlign', 'start');
  57698. cue.snapToLines = settings.get('snapToLines', true);
  57699. cue.size = settings.get('size', 100);
  57700. cue.align = settings.get('align', center);
  57701. var position = settings.get('position', 'auto');
  57702. if (position === 'auto' && defaults.position === 50) {
  57703. // set numeric position for Safari
  57704. position = cue.align === 'start' || cue.align === 'left' ? 0 : cue.align === 'end' || cue.align === 'right' ? 100 : 50;
  57705. }
  57706. cue.position = position;
  57707. }
  57708. function skipWhitespace() {
  57709. input = input.replace(/^\s+/, '');
  57710. }
  57711. // 4.1 WebVTT cue timings.
  57712. skipWhitespace();
  57713. cue.startTime = consumeTimeStamp(); // (1) collect cue start time
  57714. skipWhitespace();
  57715. if (input.slice(0, 3) !== '-->') {
  57716. // (3) next characters must match '-->'
  57717. throw new Error("Malformed time stamp (time stamps must be separated by '-->'): " + oInput);
  57718. }
  57719. input = input.slice(3);
  57720. skipWhitespace();
  57721. cue.endTime = consumeTimeStamp(); // (5) collect cue end time
  57722. // 4.1 WebVTT cue settings list.
  57723. skipWhitespace();
  57724. consumeCueSettings(input, cue);
  57725. }
  57726. function fixLineBreaks(input) {
  57727. return input.replace(/<br(?: \/)?>/gi, '\n');
  57728. }
  57729. var VTTParser = /*#__PURE__*/function () {
  57730. function VTTParser() {
  57731. this.state = 'INITIAL';
  57732. this.buffer = '';
  57733. this.decoder = new StringDecoder();
  57734. this.regionList = [];
  57735. this.cue = null;
  57736. this.oncue = void 0;
  57737. this.onparsingerror = void 0;
  57738. this.onflush = void 0;
  57739. }
  57740. var _proto3 = VTTParser.prototype;
  57741. _proto3.parse = function parse(data) {
  57742. var _this = this;
  57743. // If there is no data then we won't decode it, but will just try to parse
  57744. // whatever is in buffer already. This may occur in circumstances, for
  57745. // example when flush() is called.
  57746. if (data) {
  57747. // Try to decode the data that we received.
  57748. _this.buffer += _this.decoder.decode(data, {
  57749. stream: true
  57750. });
  57751. }
  57752. function collectNextLine() {
  57753. var buffer = _this.buffer;
  57754. var pos = 0;
  57755. buffer = fixLineBreaks(buffer);
  57756. while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') {
  57757. ++pos;
  57758. }
  57759. var line = buffer.slice(0, pos);
  57760. // Advance the buffer early in case we fail below.
  57761. if (buffer[pos] === '\r') {
  57762. ++pos;
  57763. }
  57764. if (buffer[pos] === '\n') {
  57765. ++pos;
  57766. }
  57767. _this.buffer = buffer.slice(pos);
  57768. return line;
  57769. }
  57770. // 3.2 WebVTT metadata header syntax
  57771. function parseHeader(input) {
  57772. parseOptions(input, function (k, v) {
  57773. // switch (k) {
  57774. // case 'region':
  57775. // 3.3 WebVTT region metadata header syntax
  57776. // console.log('parse region', v);
  57777. // parseRegion(v);
  57778. // break;
  57779. // }
  57780. }, /:/);
  57781. }
  57782. // 5.1 WebVTT file parsing.
  57783. try {
  57784. var line = '';
  57785. if (_this.state === 'INITIAL') {
  57786. // We can't start parsing until we have the first line.
  57787. if (!/\r\n|\n/.test(_this.buffer)) {
  57788. return this;
  57789. }
  57790. line = collectNextLine();
  57791. // strip of UTF-8 BOM if any
  57792. // https://en.wikipedia.org/wiki/Byte_order_mark#UTF-8
  57793. var m = line.match(/^()?WEBVTT([ \t].*)?$/);
  57794. if (!m || !m[0]) {
  57795. throw new Error('Malformed WebVTT signature.');
  57796. }
  57797. _this.state = 'HEADER';
  57798. }
  57799. var alreadyCollectedLine = false;
  57800. while (_this.buffer) {
  57801. // We can't parse a line until we have the full line.
  57802. if (!/\r\n|\n/.test(_this.buffer)) {
  57803. return this;
  57804. }
  57805. if (!alreadyCollectedLine) {
  57806. line = collectNextLine();
  57807. } else {
  57808. alreadyCollectedLine = false;
  57809. }
  57810. switch (_this.state) {
  57811. case 'HEADER':
  57812. // 13-18 - Allow a header (metadata) under the WEBVTT line.
  57813. if (/:/.test(line)) {
  57814. parseHeader(line);
  57815. } else if (!line) {
  57816. // An empty line terminates the header and starts the body (cues).
  57817. _this.state = 'ID';
  57818. }
  57819. continue;
  57820. case 'NOTE':
  57821. // Ignore NOTE blocks.
  57822. if (!line) {
  57823. _this.state = 'ID';
  57824. }
  57825. continue;
  57826. case 'ID':
  57827. // Check for the start of NOTE blocks.
  57828. if (/^NOTE($|[ \t])/.test(line)) {
  57829. _this.state = 'NOTE';
  57830. break;
  57831. }
  57832. // 19-29 - Allow any number of line terminators, then initialize new cue values.
  57833. if (!line) {
  57834. continue;
  57835. }
  57836. _this.cue = new _vttcue__WEBPACK_IMPORTED_MODULE_0__["default"](0, 0, '');
  57837. _this.state = 'CUE';
  57838. // 30-39 - Check if self line contains an optional identifier or timing data.
  57839. if (line.indexOf('-->') === -1) {
  57840. _this.cue.id = line;
  57841. continue;
  57842. }
  57843. // Process line as start of a cue.
  57844. /* falls through */
  57845. case 'CUE':
  57846. // 40 - Collect cue timings and settings.
  57847. if (!_this.cue) {
  57848. _this.state = 'BADCUE';
  57849. continue;
  57850. }
  57851. try {
  57852. parseCue(line, _this.cue, _this.regionList);
  57853. } catch (e) {
  57854. // In case of an error ignore rest of the cue.
  57855. _this.cue = null;
  57856. _this.state = 'BADCUE';
  57857. continue;
  57858. }
  57859. _this.state = 'CUETEXT';
  57860. continue;
  57861. case 'CUETEXT':
  57862. {
  57863. var hasSubstring = line.indexOf('-->') !== -1;
  57864. // 34 - If we have an empty line then report the cue.
  57865. // 35 - If we have the special substring '-->' then report the cue,
  57866. // but do not collect the line as we need to process the current
  57867. // one as a new cue.
  57868. if (!line || hasSubstring && (alreadyCollectedLine = true)) {
  57869. // We are done parsing self cue.
  57870. if (_this.oncue && _this.cue) {
  57871. _this.oncue(_this.cue);
  57872. }
  57873. _this.cue = null;
  57874. _this.state = 'ID';
  57875. continue;
  57876. }
  57877. if (_this.cue === null) {
  57878. continue;
  57879. }
  57880. if (_this.cue.text) {
  57881. _this.cue.text += '\n';
  57882. }
  57883. _this.cue.text += line;
  57884. }
  57885. continue;
  57886. case 'BADCUE':
  57887. // 54-62 - Collect and discard the remaining cue.
  57888. if (!line) {
  57889. _this.state = 'ID';
  57890. }
  57891. }
  57892. }
  57893. } catch (e) {
  57894. // If we are currently parsing a cue, report what we have.
  57895. if (_this.state === 'CUETEXT' && _this.cue && _this.oncue) {
  57896. _this.oncue(_this.cue);
  57897. }
  57898. _this.cue = null;
  57899. // Enter BADWEBVTT state if header was not parsed correctly otherwise
  57900. // another exception occurred so enter BADCUE state.
  57901. _this.state = _this.state === 'INITIAL' ? 'BADWEBVTT' : 'BADCUE';
  57902. }
  57903. return this;
  57904. };
  57905. _proto3.flush = function flush() {
  57906. var _this = this;
  57907. try {
  57908. // Finish decoding the stream.
  57909. // _this.buffer += _this.decoder.decode();
  57910. // Synthesize the end of the current cue or region.
  57911. if (_this.cue || _this.state === 'HEADER') {
  57912. _this.buffer += '\n\n';
  57913. _this.parse();
  57914. }
  57915. // If we've flushed, parsed, and we're still on the INITIAL state then
  57916. // that means we don't have enough of the stream to parse the first
  57917. // line.
  57918. if (_this.state === 'INITIAL' || _this.state === 'BADWEBVTT') {
  57919. throw new Error('Malformed WebVTT signature.');
  57920. }
  57921. } catch (e) {
  57922. if (_this.onparsingerror) {
  57923. _this.onparsingerror(e);
  57924. }
  57925. }
  57926. if (_this.onflush) {
  57927. _this.onflush();
  57928. }
  57929. return this;
  57930. };
  57931. return VTTParser;
  57932. }();
  57933. /***/ }),
  57934. /***/ "./src/utils/webvtt-parser.ts":
  57935. /*!************************************!*\
  57936. !*** ./src/utils/webvtt-parser.ts ***!
  57937. \************************************/
  57938. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  57939. "use strict";
  57940. __webpack_require__.r(__webpack_exports__);
  57941. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  57942. /* harmony export */ "generateCueId": () => (/* binding */ generateCueId),
  57943. /* harmony export */ "parseWebVTT": () => (/* binding */ parseWebVTT)
  57944. /* harmony export */ });
  57945. /* harmony import */ var _home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./src/polyfills/number */ "./src/polyfills/number.ts");
  57946. /* harmony import */ var _vttparser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./vttparser */ "./src/utils/vttparser.ts");
  57947. /* harmony import */ var _demux_id3__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../demux/id3 */ "./src/demux/id3.ts");
  57948. /* harmony import */ var _timescale_conversion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./timescale-conversion */ "./src/utils/timescale-conversion.ts");
  57949. /* harmony import */ var _remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../remux/mp4-remuxer */ "./src/remux/mp4-remuxer.ts");
  57950. var LINEBREAKS = /\r\n|\n\r|\n|\r/g;
  57951. // String.prototype.startsWith is not supported in IE11
  57952. var startsWith = function startsWith(inputString, searchString, position) {
  57953. if (position === void 0) {
  57954. position = 0;
  57955. }
  57956. return inputString.slice(position, position + searchString.length) === searchString;
  57957. };
  57958. var cueString2millis = function cueString2millis(timeString) {
  57959. var ts = parseInt(timeString.slice(-3));
  57960. var secs = parseInt(timeString.slice(-6, -4));
  57961. var mins = parseInt(timeString.slice(-9, -7));
  57962. var hours = timeString.length > 9 ? parseInt(timeString.substring(0, timeString.indexOf(':'))) : 0;
  57963. if (!(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(ts) || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(secs) || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(mins) || !(0,_home_runner_work_hls_js_hls_js_src_polyfills_number__WEBPACK_IMPORTED_MODULE_0__.isFiniteNumber)(hours)) {
  57964. throw Error("Malformed X-TIMESTAMP-MAP: Local:" + timeString);
  57965. }
  57966. ts += 1000 * secs;
  57967. ts += 60 * 1000 * mins;
  57968. ts += 60 * 60 * 1000 * hours;
  57969. return ts;
  57970. };
  57971. // From https://github.com/darkskyapp/string-hash
  57972. var hash = function hash(text) {
  57973. var hash = 5381;
  57974. var i = text.length;
  57975. while (i) {
  57976. hash = hash * 33 ^ text.charCodeAt(--i);
  57977. }
  57978. return (hash >>> 0).toString();
  57979. };
  57980. // Create a unique hash id for a cue based on start/end times and text.
  57981. // This helps timeline-controller to avoid showing repeated captions.
  57982. function generateCueId(startTime, endTime, text) {
  57983. return hash(startTime.toString()) + hash(endTime.toString()) + hash(text);
  57984. }
  57985. var calculateOffset = function calculateOffset(vttCCs, cc, presentationTime) {
  57986. var currCC = vttCCs[cc];
  57987. var prevCC = vttCCs[currCC.prevCC];
  57988. // This is the first discontinuity or cues have been processed since the last discontinuity
  57989. // Offset = current discontinuity time
  57990. if (!prevCC || !prevCC.new && currCC.new) {
  57991. vttCCs.ccOffset = vttCCs.presentationOffset = currCC.start;
  57992. currCC.new = false;
  57993. return;
  57994. }
  57995. // There have been discontinuities since cues were last parsed.
  57996. // Offset = time elapsed
  57997. while ((_prevCC = prevCC) !== null && _prevCC !== void 0 && _prevCC.new) {
  57998. var _prevCC;
  57999. vttCCs.ccOffset += currCC.start - prevCC.start;
  58000. currCC.new = false;
  58001. currCC = prevCC;
  58002. prevCC = vttCCs[currCC.prevCC];
  58003. }
  58004. vttCCs.presentationOffset = presentationTime;
  58005. };
  58006. function parseWebVTT(vttByteArray, initPTS, timescale, vttCCs, cc, timeOffset, callBack, errorCallBack) {
  58007. var parser = new _vttparser__WEBPACK_IMPORTED_MODULE_1__.VTTParser();
  58008. // Convert byteArray into string, replacing any somewhat exotic linefeeds with "\n", then split on that character.
  58009. // Uint8Array.prototype.reduce is not implemented in IE11
  58010. var vttLines = (0,_demux_id3__WEBPACK_IMPORTED_MODULE_2__.utf8ArrayToStr)(new Uint8Array(vttByteArray)).trim().replace(LINEBREAKS, '\n').split('\n');
  58011. var cues = [];
  58012. var initPTS90Hz = (0,_timescale_conversion__WEBPACK_IMPORTED_MODULE_3__.toMpegTsClockFromTimescale)(initPTS, timescale);
  58013. var cueTime = '00:00.000';
  58014. var timestampMapMPEGTS = 0;
  58015. var timestampMapLOCAL = 0;
  58016. var parsingError;
  58017. var inHeader = true;
  58018. parser.oncue = function (cue) {
  58019. // Adjust cue timing; clamp cues to start no earlier than - and drop cues that don't end after - 0 on timeline.
  58020. var currCC = vttCCs[cc];
  58021. var cueOffset = vttCCs.ccOffset;
  58022. // Calculate subtitle PTS offset
  58023. var webVttMpegTsMapOffset = (timestampMapMPEGTS - initPTS90Hz) / 90000;
  58024. // Update offsets for new discontinuities
  58025. if (currCC !== null && currCC !== void 0 && currCC.new) {
  58026. if (timestampMapLOCAL !== undefined) {
  58027. // When local time is provided, offset = discontinuity start time - local time
  58028. cueOffset = vttCCs.ccOffset = currCC.start;
  58029. } else {
  58030. calculateOffset(vttCCs, cc, webVttMpegTsMapOffset);
  58031. }
  58032. }
  58033. if (webVttMpegTsMapOffset) {
  58034. // If we have MPEGTS, offset = presentation time + discontinuity offset
  58035. cueOffset = webVttMpegTsMapOffset - vttCCs.presentationOffset;
  58036. }
  58037. var duration = cue.endTime - cue.startTime;
  58038. var startTime = (0,_remux_mp4_remuxer__WEBPACK_IMPORTED_MODULE_4__.normalizePts)((cue.startTime + cueOffset - timestampMapLOCAL) * 90000, timeOffset * 90000) / 90000;
  58039. cue.startTime = Math.max(startTime, 0);
  58040. cue.endTime = Math.max(startTime + duration, 0);
  58041. //trim trailing webvtt block whitespaces
  58042. var text = cue.text.trim();
  58043. // Fix encoding of special characters
  58044. cue.text = decodeURIComponent(encodeURIComponent(text));
  58045. // If the cue was not assigned an id from the VTT file (line above the content), create one.
  58046. if (!cue.id) {
  58047. cue.id = generateCueId(cue.startTime, cue.endTime, text);
  58048. }
  58049. if (cue.endTime > 0) {
  58050. cues.push(cue);
  58051. }
  58052. };
  58053. parser.onparsingerror = function (error) {
  58054. parsingError = error;
  58055. };
  58056. parser.onflush = function () {
  58057. if (parsingError) {
  58058. errorCallBack(parsingError);
  58059. return;
  58060. }
  58061. callBack(cues);
  58062. };
  58063. // Go through contents line by line.
  58064. vttLines.forEach(function (line) {
  58065. if (inHeader) {
  58066. // Look for X-TIMESTAMP-MAP in header.
  58067. if (startsWith(line, 'X-TIMESTAMP-MAP=')) {
  58068. // Once found, no more are allowed anyway, so stop searching.
  58069. inHeader = false;
  58070. // Extract LOCAL and MPEGTS.
  58071. line.slice(16).split(',').forEach(function (timestamp) {
  58072. if (startsWith(timestamp, 'LOCAL:')) {
  58073. cueTime = timestamp.slice(6);
  58074. } else if (startsWith(timestamp, 'MPEGTS:')) {
  58075. timestampMapMPEGTS = parseInt(timestamp.slice(7));
  58076. }
  58077. });
  58078. try {
  58079. // Convert cue time to seconds
  58080. timestampMapLOCAL = cueString2millis(cueTime) / 1000;
  58081. } catch (error) {
  58082. parsingError = error;
  58083. }
  58084. // Return without parsing X-TIMESTAMP-MAP line.
  58085. return;
  58086. } else if (line === '') {
  58087. inHeader = false;
  58088. }
  58089. }
  58090. // Parse line by default.
  58091. parser.parse(line + '\n');
  58092. });
  58093. parser.flush();
  58094. }
  58095. /***/ }),
  58096. /***/ "./src/utils/xhr-loader.ts":
  58097. /*!*********************************!*\
  58098. !*** ./src/utils/xhr-loader.ts ***!
  58099. \*********************************/
  58100. /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  58101. "use strict";
  58102. __webpack_require__.r(__webpack_exports__);
  58103. /* harmony export */ __webpack_require__.d(__webpack_exports__, {
  58104. /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
  58105. /* harmony export */ });
  58106. /* harmony import */ var _utils_logger__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/logger */ "./src/utils/logger.ts");
  58107. /* harmony import */ var _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../loader/load-stats */ "./src/loader/load-stats.ts");
  58108. var AGE_HEADER_LINE_REGEX = /^age:\s*[\d.]+\s*$/m;
  58109. var XhrLoader = /*#__PURE__*/function () {
  58110. function XhrLoader(config /* HlsConfig */) {
  58111. this.xhrSetup = void 0;
  58112. this.requestTimeout = void 0;
  58113. this.retryTimeout = void 0;
  58114. this.retryDelay = void 0;
  58115. this.config = null;
  58116. this.callbacks = null;
  58117. this.context = void 0;
  58118. this.loader = null;
  58119. this.stats = void 0;
  58120. this.xhrSetup = config ? config.xhrSetup : null;
  58121. this.stats = new _loader_load_stats__WEBPACK_IMPORTED_MODULE_1__.LoadStats();
  58122. this.retryDelay = 0;
  58123. }
  58124. var _proto = XhrLoader.prototype;
  58125. _proto.destroy = function destroy() {
  58126. this.callbacks = null;
  58127. this.abortInternal();
  58128. this.loader = null;
  58129. this.config = null;
  58130. };
  58131. _proto.abortInternal = function abortInternal() {
  58132. var loader = this.loader;
  58133. self.clearTimeout(this.requestTimeout);
  58134. self.clearTimeout(this.retryTimeout);
  58135. if (loader) {
  58136. loader.onreadystatechange = null;
  58137. loader.onprogress = null;
  58138. if (loader.readyState !== 4) {
  58139. this.stats.aborted = true;
  58140. loader.abort();
  58141. }
  58142. }
  58143. };
  58144. _proto.abort = function abort() {
  58145. var _this$callbacks;
  58146. this.abortInternal();
  58147. if ((_this$callbacks = this.callbacks) !== null && _this$callbacks !== void 0 && _this$callbacks.onAbort) {
  58148. this.callbacks.onAbort(this.stats, this.context, this.loader);
  58149. }
  58150. };
  58151. _proto.load = function load(context, config, callbacks) {
  58152. if (this.stats.loading.start) {
  58153. throw new Error('Loader can only be used once.');
  58154. }
  58155. this.stats.loading.start = self.performance.now();
  58156. this.context = context;
  58157. this.config = config;
  58158. this.callbacks = callbacks;
  58159. this.retryDelay = config.retryDelay;
  58160. this.loadInternal();
  58161. };
  58162. _proto.loadInternal = function loadInternal() {
  58163. var config = this.config,
  58164. context = this.context;
  58165. if (!config) {
  58166. return;
  58167. }
  58168. var xhr = this.loader = new self.XMLHttpRequest();
  58169. var stats = this.stats;
  58170. stats.loading.first = 0;
  58171. stats.loaded = 0;
  58172. var xhrSetup = this.xhrSetup;
  58173. try {
  58174. if (xhrSetup) {
  58175. try {
  58176. xhrSetup(xhr, context.url);
  58177. } catch (e) {
  58178. // fix xhrSetup: (xhr, url) => {xhr.setRequestHeader("Content-Language", "test");}
  58179. // not working, as xhr.setRequestHeader expects xhr.readyState === OPEN
  58180. xhr.open('GET', context.url, true);
  58181. xhrSetup(xhr, context.url);
  58182. }
  58183. }
  58184. if (!xhr.readyState) {
  58185. xhr.open('GET', context.url, true);
  58186. }
  58187. var headers = this.context.headers;
  58188. if (headers) {
  58189. for (var header in headers) {
  58190. xhr.setRequestHeader(header, headers[header]);
  58191. }
  58192. }
  58193. } catch (e) {
  58194. // IE11 throws an exception on xhr.open if attempting to access an HTTP resource over HTTPS
  58195. this.callbacks.onError({
  58196. code: xhr.status,
  58197. text: e.message
  58198. }, context, xhr);
  58199. return;
  58200. }
  58201. if (context.rangeEnd) {
  58202. xhr.setRequestHeader('Range', 'bytes=' + context.rangeStart + '-' + (context.rangeEnd - 1));
  58203. }
  58204. xhr.onreadystatechange = this.readystatechange.bind(this);
  58205. xhr.onprogress = this.loadprogress.bind(this);
  58206. xhr.responseType = context.responseType;
  58207. // setup timeout before we perform request
  58208. self.clearTimeout(this.requestTimeout);
  58209. this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), config.timeout);
  58210. xhr.send();
  58211. };
  58212. _proto.readystatechange = function readystatechange() {
  58213. var context = this.context,
  58214. xhr = this.loader,
  58215. stats = this.stats;
  58216. if (!context || !xhr) {
  58217. return;
  58218. }
  58219. var readyState = xhr.readyState;
  58220. var config = this.config;
  58221. // don't proceed if xhr has been aborted
  58222. if (stats.aborted) {
  58223. return;
  58224. }
  58225. // >= HEADERS_RECEIVED
  58226. if (readyState >= 2) {
  58227. // clear xhr timeout and rearm it if readyState less than 4
  58228. self.clearTimeout(this.requestTimeout);
  58229. if (stats.loading.first === 0) {
  58230. stats.loading.first = Math.max(self.performance.now(), stats.loading.start);
  58231. }
  58232. if (readyState === 4) {
  58233. xhr.onreadystatechange = null;
  58234. xhr.onprogress = null;
  58235. var status = xhr.status;
  58236. // http status between 200 to 299 are all successful
  58237. var isArrayBuffer = xhr.responseType === 'arraybuffer';
  58238. if (status >= 200 && status < 300 && (isArrayBuffer && xhr.response || xhr.responseText !== null)) {
  58239. stats.loading.end = Math.max(self.performance.now(), stats.loading.first);
  58240. var data;
  58241. var len;
  58242. if (isArrayBuffer) {
  58243. data = xhr.response;
  58244. len = data.byteLength;
  58245. } else {
  58246. data = xhr.responseText;
  58247. len = data.length;
  58248. }
  58249. stats.loaded = stats.total = len;
  58250. if (!this.callbacks) {
  58251. return;
  58252. }
  58253. var onProgress = this.callbacks.onProgress;
  58254. if (onProgress) {
  58255. onProgress(stats, context, data, xhr);
  58256. }
  58257. if (!this.callbacks) {
  58258. return;
  58259. }
  58260. var response = {
  58261. url: xhr.responseURL,
  58262. data: data
  58263. };
  58264. this.callbacks.onSuccess(response, stats, context, xhr);
  58265. } else {
  58266. // if max nb of retries reached or if http status between 400 and 499 (such error cannot be recovered, retrying is useless), return error
  58267. if (stats.retry >= config.maxRetry || status >= 400 && status < 499) {
  58268. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.error(status + " while loading " + context.url);
  58269. this.callbacks.onError({
  58270. code: status,
  58271. text: xhr.statusText
  58272. }, context, xhr);
  58273. } else {
  58274. // retry
  58275. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.warn(status + " while loading " + context.url + ", retrying in " + this.retryDelay + "...");
  58276. // abort and reset internal state
  58277. this.abortInternal();
  58278. this.loader = null;
  58279. // schedule retry
  58280. self.clearTimeout(this.retryTimeout);
  58281. this.retryTimeout = self.setTimeout(this.loadInternal.bind(this), this.retryDelay);
  58282. // set exponential backoff
  58283. this.retryDelay = Math.min(2 * this.retryDelay, config.maxRetryDelay);
  58284. stats.retry++;
  58285. }
  58286. }
  58287. } else {
  58288. // readyState >= 2 AND readyState !==4 (readyState = HEADERS_RECEIVED || LOADING) rearm timeout as xhr not finished yet
  58289. self.clearTimeout(this.requestTimeout);
  58290. this.requestTimeout = self.setTimeout(this.loadtimeout.bind(this), config.timeout);
  58291. }
  58292. }
  58293. };
  58294. _proto.loadtimeout = function loadtimeout() {
  58295. _utils_logger__WEBPACK_IMPORTED_MODULE_0__.logger.warn("timeout while loading " + this.context.url);
  58296. var callbacks = this.callbacks;
  58297. if (callbacks) {
  58298. this.abortInternal();
  58299. callbacks.onTimeout(this.stats, this.context, this.loader);
  58300. }
  58301. };
  58302. _proto.loadprogress = function loadprogress(event) {
  58303. var stats = this.stats;
  58304. stats.loaded = event.loaded;
  58305. if (event.lengthComputable) {
  58306. stats.total = event.total;
  58307. }
  58308. };
  58309. _proto.getCacheAge = function getCacheAge() {
  58310. var result = null;
  58311. if (this.loader && AGE_HEADER_LINE_REGEX.test(this.loader.getAllResponseHeaders())) {
  58312. var ageHeader = this.loader.getResponseHeader('age');
  58313. result = ageHeader ? parseFloat(ageHeader) : null;
  58314. }
  58315. return result;
  58316. };
  58317. return XhrLoader;
  58318. }();
  58319. /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (XhrLoader);
  58320. /***/ }),
  58321. /***/ "./node_modules/eventemitter3/index.js":
  58322. /*!*********************************************!*\
  58323. !*** ./node_modules/eventemitter3/index.js ***!
  58324. \*********************************************/
  58325. /***/ ((module) => {
  58326. "use strict";
  58327. var has = Object.prototype.hasOwnProperty
  58328. , prefix = '~';
  58329. /**
  58330. * Constructor to create a storage for our `EE` objects.
  58331. * An `Events` instance is a plain object whose properties are event names.
  58332. *
  58333. * @constructor
  58334. * @private
  58335. */
  58336. function Events() {}
  58337. //
  58338. // We try to not inherit from `Object.prototype`. In some engines creating an
  58339. // instance in this way is faster than calling `Object.create(null)` directly.
  58340. // If `Object.create(null)` is not supported we prefix the event names with a
  58341. // character to make sure that the built-in object properties are not
  58342. // overridden or used as an attack vector.
  58343. //
  58344. if (Object.create) {
  58345. Events.prototype = Object.create(null);
  58346. //
  58347. // This hack is needed because the `__proto__` property is still inherited in
  58348. // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.
  58349. //
  58350. if (!new Events().__proto__) prefix = false;
  58351. }
  58352. /**
  58353. * Representation of a single event listener.
  58354. *
  58355. * @param {Function} fn The listener function.
  58356. * @param {*} context The context to invoke the listener with.
  58357. * @param {Boolean} [once=false] Specify if the listener is a one-time listener.
  58358. * @constructor
  58359. * @private
  58360. */
  58361. function EE(fn, context, once) {
  58362. this.fn = fn;
  58363. this.context = context;
  58364. this.once = once || false;
  58365. }
  58366. /**
  58367. * Add a listener for a given event.
  58368. *
  58369. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  58370. * @param {(String|Symbol)} event The event name.
  58371. * @param {Function} fn The listener function.
  58372. * @param {*} context The context to invoke the listener with.
  58373. * @param {Boolean} once Specify if the listener is a one-time listener.
  58374. * @returns {EventEmitter}
  58375. * @private
  58376. */
  58377. function addListener(emitter, event, fn, context, once) {
  58378. if (typeof fn !== 'function') {
  58379. throw new TypeError('The listener must be a function');
  58380. }
  58381. var listener = new EE(fn, context || emitter, once)
  58382. , evt = prefix ? prefix + event : event;
  58383. if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
  58384. else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
  58385. else emitter._events[evt] = [emitter._events[evt], listener];
  58386. return emitter;
  58387. }
  58388. /**
  58389. * Clear event by name.
  58390. *
  58391. * @param {EventEmitter} emitter Reference to the `EventEmitter` instance.
  58392. * @param {(String|Symbol)} evt The Event name.
  58393. * @private
  58394. */
  58395. function clearEvent(emitter, evt) {
  58396. if (--emitter._eventsCount === 0) emitter._events = new Events();
  58397. else delete emitter._events[evt];
  58398. }
  58399. /**
  58400. * Minimal `EventEmitter` interface that is molded against the Node.js
  58401. * `EventEmitter` interface.
  58402. *
  58403. * @constructor
  58404. * @public
  58405. */
  58406. function EventEmitter() {
  58407. this._events = new Events();
  58408. this._eventsCount = 0;
  58409. }
  58410. /**
  58411. * Return an array listing the events for which the emitter has registered
  58412. * listeners.
  58413. *
  58414. * @returns {Array}
  58415. * @public
  58416. */
  58417. EventEmitter.prototype.eventNames = function eventNames() {
  58418. var names = []
  58419. , events
  58420. , name;
  58421. if (this._eventsCount === 0) return names;
  58422. for (name in (events = this._events)) {
  58423. if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
  58424. }
  58425. if (Object.getOwnPropertySymbols) {
  58426. return names.concat(Object.getOwnPropertySymbols(events));
  58427. }
  58428. return names;
  58429. };
  58430. /**
  58431. * Return the listeners registered for a given event.
  58432. *
  58433. * @param {(String|Symbol)} event The event name.
  58434. * @returns {Array} The registered listeners.
  58435. * @public
  58436. */
  58437. EventEmitter.prototype.listeners = function listeners(event) {
  58438. var evt = prefix ? prefix + event : event
  58439. , handlers = this._events[evt];
  58440. if (!handlers) return [];
  58441. if (handlers.fn) return [handlers.fn];
  58442. for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
  58443. ee[i] = handlers[i].fn;
  58444. }
  58445. return ee;
  58446. };
  58447. /**
  58448. * Return the number of listeners listening to a given event.
  58449. *
  58450. * @param {(String|Symbol)} event The event name.
  58451. * @returns {Number} The number of listeners.
  58452. * @public
  58453. */
  58454. EventEmitter.prototype.listenerCount = function listenerCount(event) {
  58455. var evt = prefix ? prefix + event : event
  58456. , listeners = this._events[evt];
  58457. if (!listeners) return 0;
  58458. if (listeners.fn) return 1;
  58459. return listeners.length;
  58460. };
  58461. /**
  58462. * Calls each of the listeners registered for a given event.
  58463. *
  58464. * @param {(String|Symbol)} event The event name.
  58465. * @returns {Boolean} `true` if the event had listeners, else `false`.
  58466. * @public
  58467. */
  58468. EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
  58469. var evt = prefix ? prefix + event : event;
  58470. if (!this._events[evt]) return false;
  58471. var listeners = this._events[evt]
  58472. , len = arguments.length
  58473. , args
  58474. , i;
  58475. if (listeners.fn) {
  58476. if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
  58477. switch (len) {
  58478. case 1: return listeners.fn.call(listeners.context), true;
  58479. case 2: return listeners.fn.call(listeners.context, a1), true;
  58480. case 3: return listeners.fn.call(listeners.context, a1, a2), true;
  58481. case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
  58482. case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
  58483. case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
  58484. }
  58485. for (i = 1, args = new Array(len -1); i < len; i++) {
  58486. args[i - 1] = arguments[i];
  58487. }
  58488. listeners.fn.apply(listeners.context, args);
  58489. } else {
  58490. var length = listeners.length
  58491. , j;
  58492. for (i = 0; i < length; i++) {
  58493. if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
  58494. switch (len) {
  58495. case 1: listeners[i].fn.call(listeners[i].context); break;
  58496. case 2: listeners[i].fn.call(listeners[i].context, a1); break;
  58497. case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
  58498. case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;
  58499. default:
  58500. if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
  58501. args[j - 1] = arguments[j];
  58502. }
  58503. listeners[i].fn.apply(listeners[i].context, args);
  58504. }
  58505. }
  58506. }
  58507. return true;
  58508. };
  58509. /**
  58510. * Add a listener for a given event.
  58511. *
  58512. * @param {(String|Symbol)} event The event name.
  58513. * @param {Function} fn The listener function.
  58514. * @param {*} [context=this] The context to invoke the listener with.
  58515. * @returns {EventEmitter} `this`.
  58516. * @public
  58517. */
  58518. EventEmitter.prototype.on = function on(event, fn, context) {
  58519. return addListener(this, event, fn, context, false);
  58520. };
  58521. /**
  58522. * Add a one-time listener for a given event.
  58523. *
  58524. * @param {(String|Symbol)} event The event name.
  58525. * @param {Function} fn The listener function.
  58526. * @param {*} [context=this] The context to invoke the listener with.
  58527. * @returns {EventEmitter} `this`.
  58528. * @public
  58529. */
  58530. EventEmitter.prototype.once = function once(event, fn, context) {
  58531. return addListener(this, event, fn, context, true);
  58532. };
  58533. /**
  58534. * Remove the listeners of a given event.
  58535. *
  58536. * @param {(String|Symbol)} event The event name.
  58537. * @param {Function} fn Only remove the listeners that match this function.
  58538. * @param {*} context Only remove the listeners that have this context.
  58539. * @param {Boolean} once Only remove one-time listeners.
  58540. * @returns {EventEmitter} `this`.
  58541. * @public
  58542. */
  58543. EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
  58544. var evt = prefix ? prefix + event : event;
  58545. if (!this._events[evt]) return this;
  58546. if (!fn) {
  58547. clearEvent(this, evt);
  58548. return this;
  58549. }
  58550. var listeners = this._events[evt];
  58551. if (listeners.fn) {
  58552. if (
  58553. listeners.fn === fn &&
  58554. (!once || listeners.once) &&
  58555. (!context || listeners.context === context)
  58556. ) {
  58557. clearEvent(this, evt);
  58558. }
  58559. } else {
  58560. for (var i = 0, events = [], length = listeners.length; i < length; i++) {
  58561. if (
  58562. listeners[i].fn !== fn ||
  58563. (once && !listeners[i].once) ||
  58564. (context && listeners[i].context !== context)
  58565. ) {
  58566. events.push(listeners[i]);
  58567. }
  58568. }
  58569. //
  58570. // Reset the array, or remove it completely if we have no more listeners.
  58571. //
  58572. if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
  58573. else clearEvent(this, evt);
  58574. }
  58575. return this;
  58576. };
  58577. /**
  58578. * Remove all listeners, or those of the specified event.
  58579. *
  58580. * @param {(String|Symbol)} [event] The event name.
  58581. * @returns {EventEmitter} `this`.
  58582. * @public
  58583. */
  58584. EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
  58585. var evt;
  58586. if (event) {
  58587. evt = prefix ? prefix + event : event;
  58588. if (this._events[evt]) clearEvent(this, evt);
  58589. } else {
  58590. this._events = new Events();
  58591. this._eventsCount = 0;
  58592. }
  58593. return this;
  58594. };
  58595. //
  58596. // Alias methods names because people roll like that.
  58597. //
  58598. EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
  58599. EventEmitter.prototype.addListener = EventEmitter.prototype.on;
  58600. //
  58601. // Expose the prefix.
  58602. //
  58603. EventEmitter.prefixed = prefix;
  58604. //
  58605. // Allow `EventEmitter` to be imported as module namespace.
  58606. //
  58607. EventEmitter.EventEmitter = EventEmitter;
  58608. //
  58609. // Expose the module.
  58610. //
  58611. if (true) {
  58612. module.exports = EventEmitter;
  58613. }
  58614. /***/ }),
  58615. /***/ "./node_modules/url-toolkit/src/url-toolkit.js":
  58616. /*!*****************************************************!*\
  58617. !*** ./node_modules/url-toolkit/src/url-toolkit.js ***!
  58618. \*****************************************************/
  58619. /***/ (function(module) {
  58620. // see https://tools.ietf.org/html/rfc1808
  58621. (function (root) {
  58622. var URL_REGEX =
  58623. /^(?=((?:[a-zA-Z0-9+\-.]+:)?))\1(?=((?:\/\/[^\/?#]*)?))\2(?=((?:(?:[^?#\/]*\/)*[^;?#\/]*)?))\3((?:;[^?#]*)?)(\?[^#]*)?(#[^]*)?$/;
  58624. var FIRST_SEGMENT_REGEX = /^(?=([^\/?#]*))\1([^]*)$/;
  58625. var SLASH_DOT_REGEX = /(?:\/|^)\.(?=\/)/g;
  58626. var SLASH_DOT_DOT_REGEX = /(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g;
  58627. var URLToolkit = {
  58628. // If opts.alwaysNormalize is true then the path will always be normalized even when it starts with / or //
  58629. // E.g
  58630. // With opts.alwaysNormalize = false (default, spec compliant)
  58631. // http://a.com/b/cd + /e/f/../g => http://a.com/e/f/../g
  58632. // With opts.alwaysNormalize = true (not spec compliant)
  58633. // http://a.com/b/cd + /e/f/../g => http://a.com/e/g
  58634. buildAbsoluteURL: function (baseURL, relativeURL, opts) {
  58635. opts = opts || {};
  58636. // remove any remaining space and CRLF
  58637. baseURL = baseURL.trim();
  58638. relativeURL = relativeURL.trim();
  58639. if (!relativeURL) {
  58640. // 2a) If the embedded URL is entirely empty, it inherits the
  58641. // entire base URL (i.e., is set equal to the base URL)
  58642. // and we are done.
  58643. if (!opts.alwaysNormalize) {
  58644. return baseURL;
  58645. }
  58646. var basePartsForNormalise = URLToolkit.parseURL(baseURL);
  58647. if (!basePartsForNormalise) {
  58648. throw new Error('Error trying to parse base URL.');
  58649. }
  58650. basePartsForNormalise.path = URLToolkit.normalizePath(
  58651. basePartsForNormalise.path
  58652. );
  58653. return URLToolkit.buildURLFromParts(basePartsForNormalise);
  58654. }
  58655. var relativeParts = URLToolkit.parseURL(relativeURL);
  58656. if (!relativeParts) {
  58657. throw new Error('Error trying to parse relative URL.');
  58658. }
  58659. if (relativeParts.scheme) {
  58660. // 2b) If the embedded URL starts with a scheme name, it is
  58661. // interpreted as an absolute URL and we are done.
  58662. if (!opts.alwaysNormalize) {
  58663. return relativeURL;
  58664. }
  58665. relativeParts.path = URLToolkit.normalizePath(relativeParts.path);
  58666. return URLToolkit.buildURLFromParts(relativeParts);
  58667. }
  58668. var baseParts = URLToolkit.parseURL(baseURL);
  58669. if (!baseParts) {
  58670. throw new Error('Error trying to parse base URL.');
  58671. }
  58672. if (!baseParts.netLoc && baseParts.path && baseParts.path[0] !== '/') {
  58673. // If netLoc missing and path doesn't start with '/', assume everthing before the first '/' is the netLoc
  58674. // This causes 'example.com/a' to be handled as '//example.com/a' instead of '/example.com/a'
  58675. var pathParts = FIRST_SEGMENT_REGEX.exec(baseParts.path);
  58676. baseParts.netLoc = pathParts[1];
  58677. baseParts.path = pathParts[2];
  58678. }
  58679. if (baseParts.netLoc && !baseParts.path) {
  58680. baseParts.path = '/';
  58681. }
  58682. var builtParts = {
  58683. // 2c) Otherwise, the embedded URL inherits the scheme of
  58684. // the base URL.
  58685. scheme: baseParts.scheme,
  58686. netLoc: relativeParts.netLoc,
  58687. path: null,
  58688. params: relativeParts.params,
  58689. query: relativeParts.query,
  58690. fragment: relativeParts.fragment,
  58691. };
  58692. if (!relativeParts.netLoc) {
  58693. // 3) If the embedded URL's <net_loc> is non-empty, we skip to
  58694. // Step 7. Otherwise, the embedded URL inherits the <net_loc>
  58695. // (if any) of the base URL.
  58696. builtParts.netLoc = baseParts.netLoc;
  58697. // 4) If the embedded URL path is preceded by a slash "/", the
  58698. // path is not relative and we skip to Step 7.
  58699. if (relativeParts.path[0] !== '/') {
  58700. if (!relativeParts.path) {
  58701. // 5) If the embedded URL path is empty (and not preceded by a
  58702. // slash), then the embedded URL inherits the base URL path
  58703. builtParts.path = baseParts.path;
  58704. // 5a) if the embedded URL's <params> is non-empty, we skip to
  58705. // step 7; otherwise, it inherits the <params> of the base
  58706. // URL (if any) and
  58707. if (!relativeParts.params) {
  58708. builtParts.params = baseParts.params;
  58709. // 5b) if the embedded URL's <query> is non-empty, we skip to
  58710. // step 7; otherwise, it inherits the <query> of the base
  58711. // URL (if any) and we skip to step 7.
  58712. if (!relativeParts.query) {
  58713. builtParts.query = baseParts.query;
  58714. }
  58715. }
  58716. } else {
  58717. // 6) The last segment of the base URL's path (anything
  58718. // following the rightmost slash "/", or the entire path if no
  58719. // slash is present) is removed and the embedded URL's path is
  58720. // appended in its place.
  58721. var baseURLPath = baseParts.path;
  58722. var newPath =
  58723. baseURLPath.substring(0, baseURLPath.lastIndexOf('/') + 1) +
  58724. relativeParts.path;
  58725. builtParts.path = URLToolkit.normalizePath(newPath);
  58726. }
  58727. }
  58728. }
  58729. if (builtParts.path === null) {
  58730. builtParts.path = opts.alwaysNormalize
  58731. ? URLToolkit.normalizePath(relativeParts.path)
  58732. : relativeParts.path;
  58733. }
  58734. return URLToolkit.buildURLFromParts(builtParts);
  58735. },
  58736. parseURL: function (url) {
  58737. var parts = URL_REGEX.exec(url);
  58738. if (!parts) {
  58739. return null;
  58740. }
  58741. return {
  58742. scheme: parts[1] || '',
  58743. netLoc: parts[2] || '',
  58744. path: parts[3] || '',
  58745. params: parts[4] || '',
  58746. query: parts[5] || '',
  58747. fragment: parts[6] || '',
  58748. };
  58749. },
  58750. normalizePath: function (path) {
  58751. // The following operations are
  58752. // then applied, in order, to the new path:
  58753. // 6a) All occurrences of "./", where "." is a complete path
  58754. // segment, are removed.
  58755. // 6b) If the path ends with "." as a complete path segment,
  58756. // that "." is removed.
  58757. path = path.split('').reverse().join('').replace(SLASH_DOT_REGEX, '');
  58758. // 6c) All occurrences of "<segment>/../", where <segment> is a
  58759. // complete path segment not equal to "..", are removed.
  58760. // Removal of these path segments is performed iteratively,
  58761. // removing the leftmost matching pattern on each iteration,
  58762. // until no matching pattern remains.
  58763. // 6d) If the path ends with "<segment>/..", where <segment> is a
  58764. // complete path segment not equal to "..", that
  58765. // "<segment>/.." is removed.
  58766. while (
  58767. path.length !== (path = path.replace(SLASH_DOT_DOT_REGEX, '')).length
  58768. ) {}
  58769. return path.split('').reverse().join('');
  58770. },
  58771. buildURLFromParts: function (parts) {
  58772. return (
  58773. parts.scheme +
  58774. parts.netLoc +
  58775. parts.path +
  58776. parts.params +
  58777. parts.query +
  58778. parts.fragment
  58779. );
  58780. },
  58781. };
  58782. if (true)
  58783. module.exports = URLToolkit;
  58784. else {}
  58785. })(this);
  58786. /***/ })
  58787. /******/ });
  58788. /************************************************************************/
  58789. /******/ // The module cache
  58790. /******/ var __webpack_module_cache__ = {};
  58791. /******/
  58792. /******/ // The require function
  58793. /******/ function __webpack_require__(moduleId) {
  58794. /******/ // Check if module is in cache
  58795. /******/ var cachedModule = __webpack_module_cache__[moduleId];
  58796. /******/ if (cachedModule !== undefined) {
  58797. /******/ return cachedModule.exports;
  58798. /******/ }
  58799. /******/ // Create a new module (and put it into the cache)
  58800. /******/ var module = __webpack_module_cache__[moduleId] = {
  58801. /******/ // no module.id needed
  58802. /******/ // no module.loaded needed
  58803. /******/ exports: {}
  58804. /******/ };
  58805. /******/
  58806. /******/ // Execute the module function
  58807. /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);
  58808. /******/
  58809. /******/ // Return the exports of the module
  58810. /******/ return module.exports;
  58811. /******/ }
  58812. /******/
  58813. /******/ // expose the modules object (__webpack_modules__)
  58814. /******/ __webpack_require__.m = __webpack_modules__;
  58815. /******/
  58816. /************************************************************************/
  58817. /******/ /* webpack/runtime/compat get default export */
  58818. /******/ (() => {
  58819. /******/ // getDefaultExport function for compatibility with non-harmony modules
  58820. /******/ __webpack_require__.n = (module) => {
  58821. /******/ var getter = module && module.__esModule ?
  58822. /******/ () => (module['default']) :
  58823. /******/ () => (module);
  58824. /******/ __webpack_require__.d(getter, { a: getter });
  58825. /******/ return getter;
  58826. /******/ };
  58827. /******/ })();
  58828. /******/
  58829. /******/ /* webpack/runtime/define property getters */
  58830. /******/ (() => {
  58831. /******/ // define getter functions for harmony exports
  58832. /******/ __webpack_require__.d = (exports, definition) => {
  58833. /******/ for(var key in definition) {
  58834. /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
  58835. /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
  58836. /******/ }
  58837. /******/ }
  58838. /******/ };
  58839. /******/ })();
  58840. /******/
  58841. /******/ /* webpack/runtime/hasOwnProperty shorthand */
  58842. /******/ (() => {
  58843. /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
  58844. /******/ })();
  58845. /******/
  58846. /******/ /* webpack/runtime/make namespace object */
  58847. /******/ (() => {
  58848. /******/ // define __esModule on exports
  58849. /******/ __webpack_require__.r = (exports) => {
  58850. /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
  58851. /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  58852. /******/ }
  58853. /******/ Object.defineProperty(exports, '__esModule', { value: true });
  58854. /******/ };
  58855. /******/ })();
  58856. /******/
  58857. /************************************************************************/
  58858. /******/
  58859. /******/ // module factories are used so entry inlining is disabled
  58860. /******/ // startup
  58861. /******/ // Load entry module and return exports
  58862. /******/ var __webpack_exports__ = __webpack_require__("./src/hls.ts");
  58863. /******/ __webpack_exports__ = __webpack_exports__["default"];
  58864. /******/
  58865. /******/ return __webpack_exports__;
  58866. /******/ })()
  58867. ;
  58868. });
  58869. //# sourceMappingURL=hls.js.map