1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341 |
- (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
- (function (process){
- /**
- * Tween.js - Licensed under the MIT license
- * https://github.com/tweenjs/tween.js
- * ----------------------------------------------
- *
- * See https://github.com/tweenjs/tween.js/graphs/contributors for the full list of contributors.
- * Thank you all, you're awesome!
- */
- var TWEEN = TWEEN || (function () {
- var _tweens = [];
- return {
- getAll: function () {
- return _tweens;
- },
- removeAll: function () {
- _tweens = [];
- },
- add: function (tween) {
- _tweens.push(tween);
- },
- remove: function (tween) {
- var i = _tweens.indexOf(tween);
- if (i !== -1) {
- _tweens.splice(i, 1);
- }
- },
- update: function (time, preserve) {
- if (_tweens.length === 0) {
- return false;
- }
- var i = 0;
- time = time !== undefined ? time : TWEEN.now();
- while (i < _tweens.length) {
- if (_tweens[i].update(time) || preserve) {
- i++;
- } else {
- _tweens.splice(i, 1);
- }
- }
- return true;
- }
- };
- })();
- // Include a performance.now polyfill.
- // In node.js, use process.hrtime.
- if (typeof (window) === 'undefined' && typeof (process) !== 'undefined') {
- TWEEN.now = function () {
- var time = process.hrtime();
- // Convert [seconds, nanoseconds] to milliseconds.
- return time[0] * 1000 + time[1] / 1000000;
- };
- }
- // In a browser, use window.performance.now if it is available.
- else if (typeof (window) !== 'undefined' &&
- window.performance !== undefined &&
- window.performance.now !== undefined) {
- // This must be bound, because directly assigning this function
- // leads to an invocation exception in Chrome.
- TWEEN.now = window.performance.now.bind(window.performance);
- }
- // Use Date.now if it is available.
- else if (Date.now !== undefined) {
- TWEEN.now = Date.now;
- }
- // Otherwise, use 'new Date().getTime()'.
- else {
- TWEEN.now = function () {
- return new Date().getTime();
- };
- }
- TWEEN.Tween = function (object) {
- var _object = object;
- var _valuesStart = {};
- var _valuesEnd = {};
- var _valuesStartRepeat = {};
- var _duration = 1000;
- var _repeat = 0;
- var _repeatDelayTime;
- var _yoyo = false;
- var _isPlaying = false;
- var _reversed = false;
- var _delayTime = 0;
- var _startTime = null;
- var _easingFunction = TWEEN.Easing.Linear.None;
- var _interpolationFunction = TWEEN.Interpolation.Linear;
- var _chainedTweens = [];
- var _onStartCallback = null;
- var _onStartCallbackFired = false;
- var _onUpdateCallback = null;
- var _onCompleteCallback = null;
- var _onStopCallback = null;
- this.to = function (properties, duration) {
- _valuesEnd = properties;
- if (duration !== undefined) {
- _duration = duration;
- }
- return this;
- };
- this.start = function (time) {
- TWEEN.add(this);
- _isPlaying = true;
- _onStartCallbackFired = false;
- _startTime = time !== undefined ? time : TWEEN.now();
- _startTime += _delayTime;
- for (var property in _valuesEnd) {
- // Check if an Array was provided as property value
- if (_valuesEnd[property] instanceof Array) {
- if (_valuesEnd[property].length === 0) {
- continue;
- }
- // Create a local copy of the Array with the start value at the front
- _valuesEnd[property] = [_object[property]].concat(_valuesEnd[property]);
- }
- // If `to()` specifies a property that doesn't exist in the source object,
- // we should not set that property in the object
- if (_object[property] === undefined) {
- continue;
- }
- // Save the starting value.
- _valuesStart[property] = _object[property];
- if ((_valuesStart[property] instanceof Array) === false) {
- _valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
- }
- _valuesStartRepeat[property] = _valuesStart[property] || 0;
- }
- return this;
- };
- this.stop = function () {
- if (!_isPlaying) {
- return this;
- }
- TWEEN.remove(this);
- _isPlaying = false;
- if (_onStopCallback !== null) {
- _onStopCallback.call(_object, _object);
- }
- this.stopChainedTweens();
- return this;
- };
- this.end = function () {
- this.update(_startTime + _duration);
- return this;
- };
- this.stopChainedTweens = function () {
- for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
- _chainedTweens[i].stop();
- }
- };
- this.delay = function (amount) {
- _delayTime = amount;
- return this;
- };
- this.repeat = function (times) {
- _repeat = times;
- return this;
- };
- this.repeatDelay = function (amount) {
- _repeatDelayTime = amount;
- return this;
- };
- this.yoyo = function (yoyo) {
- _yoyo = yoyo;
- return this;
- };
- this.easing = function (easing) {
- _easingFunction = easing;
- return this;
- };
- this.interpolation = function (interpolation) {
- _interpolationFunction = interpolation;
- return this;
- };
- this.chain = function () {
- _chainedTweens = arguments;
- return this;
- };
- this.onStart = function (callback) {
- _onStartCallback = callback;
- return this;
- };
- this.onUpdate = function (callback) {
- _onUpdateCallback = callback;
- return this;
- };
- this.onComplete = function (callback) {
- _onCompleteCallback = callback;
- return this;
- };
- this.onStop = function (callback) {
- _onStopCallback = callback;
- return this;
- };
- this.update = function (time) {
- var property;
- var elapsed;
- var value;
- if (time < _startTime) {
- return true;
- }
- if (_onStartCallbackFired === false) {
- if (_onStartCallback !== null) {
- _onStartCallback.call(_object, _object);
- }
- _onStartCallbackFired = true;
- }
- elapsed = (time - _startTime) / _duration;
- elapsed = elapsed > 1 ? 1 : elapsed;
- value = _easingFunction(elapsed);
- for (property in _valuesEnd) {
- // Don't update properties that do not exist in the source object
- if (_valuesStart[property] === undefined) {
- continue;
- }
- var start = _valuesStart[property] || 0;
- var end = _valuesEnd[property];
- if (end instanceof Array) {
- _object[property] = _interpolationFunction(end, value);
- } else {
- // Parses relative end values with start as base (e.g.: +10, -3)
- if (typeof (end) === 'string') {
- if (end.charAt(0) === '+' || end.charAt(0) === '-') {
- end = start + parseFloat(end);
- } else {
- end = parseFloat(end);
- }
- }
- // Protect against non numeric properties.
- if (typeof (end) === 'number') {
- _object[property] = start + (end - start) * value;
- }
- }
- }
- if (_onUpdateCallback !== null) {
- _onUpdateCallback.call(_object, value);
- }
- if (elapsed === 1) {
- if (_repeat > 0) {
- if (isFinite(_repeat)) {
- _repeat--;
- }
- // Reassign starting values, restart by making startTime = now
- for (property in _valuesStartRepeat) {
- if (typeof (_valuesEnd[property]) === 'string') {
- _valuesStartRepeat[property] = _valuesStartRepeat[property] + parseFloat(_valuesEnd[property]);
- }
- if (_yoyo) {
- var tmp = _valuesStartRepeat[property];
- _valuesStartRepeat[property] = _valuesEnd[property];
- _valuesEnd[property] = tmp;
- }
- _valuesStart[property] = _valuesStartRepeat[property];
- }
- if (_yoyo) {
- _reversed = !_reversed;
- }
- if (_repeatDelayTime !== undefined) {
- _startTime = time + _repeatDelayTime;
- } else {
- _startTime = time + _delayTime;
- }
- return true;
- } else {
- if (_onCompleteCallback !== null) {
- _onCompleteCallback.call(_object, _object);
- }
- for (var i = 0, numChainedTweens = _chainedTweens.length; i < numChainedTweens; i++) {
- // Make the chained tweens start exactly at the time they should,
- // even if the `update()` method was called way past the duration of the tween
- _chainedTweens[i].start(_startTime + _duration);
- }
- return false;
- }
- }
- return true;
- };
- };
- TWEEN.Easing = {
- Linear: {
- None: function (k) {
- return k;
- }
- },
- Quadratic: {
- In: function (k) {
- return k * k;
- },
- Out: function (k) {
- return k * (2 - k);
- },
- InOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k;
- }
- return - 0.5 * (--k * (k - 2) - 1);
- }
- },
- Cubic: {
- In: function (k) {
- return k * k * k;
- },
- Out: function (k) {
- return --k * k * k + 1;
- },
- InOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k * k;
- }
- return 0.5 * ((k -= 2) * k * k + 2);
- }
- },
- Quartic: {
- In: function (k) {
- return k * k * k * k;
- },
- Out: function (k) {
- return 1 - (--k * k * k * k);
- },
- InOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k * k * k;
- }
- return - 0.5 * ((k -= 2) * k * k * k - 2);
- }
- },
- Quintic: {
- In: function (k) {
- return k * k * k * k * k;
- },
- Out: function (k) {
- return --k * k * k * k * k + 1;
- },
- InOut: function (k) {
- if ((k *= 2) < 1) {
- return 0.5 * k * k * k * k * k;
- }
- return 0.5 * ((k -= 2) * k * k * k * k + 2);
- }
- },
- Sinusoidal: {
- In: function (k) {
- return 1 - Math.cos(k * Math.PI / 2);
- },
- Out: function (k) {
- return Math.sin(k * Math.PI / 2);
- },
- InOut: function (k) {
- return 0.5 * (1 - Math.cos(Math.PI * k));
- }
- },
- Exponential: {
- In: function (k) {
- return k === 0 ? 0 : Math.pow(1024, k - 1);
- },
- Out: function (k) {
- return k === 1 ? 1 : 1 - Math.pow(2, - 10 * k);
- },
- InOut: function (k) {
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- if ((k *= 2) < 1) {
- return 0.5 * Math.pow(1024, k - 1);
- }
- return 0.5 * (- Math.pow(2, - 10 * (k - 1)) + 2);
- }
- },
- Circular: {
- In: function (k) {
- return 1 - Math.sqrt(1 - k * k);
- },
- Out: function (k) {
- return Math.sqrt(1 - (--k * k));
- },
- InOut: function (k) {
- if ((k *= 2) < 1) {
- return - 0.5 * (Math.sqrt(1 - k * k) - 1);
- }
- return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
- }
- },
- Elastic: {
- In: function (k) {
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- return -Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
- },
- Out: function (k) {
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- return Math.pow(2, -10 * k) * Math.sin((k - 0.1) * 5 * Math.PI) + 1;
- },
- InOut: function (k) {
- if (k === 0) {
- return 0;
- }
- if (k === 1) {
- return 1;
- }
- k *= 2;
- if (k < 1) {
- return -0.5 * Math.pow(2, 10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI);
- }
- return 0.5 * Math.pow(2, -10 * (k - 1)) * Math.sin((k - 1.1) * 5 * Math.PI) + 1;
- }
- },
- Back: {
- In: function (k) {
- var s = 1.70158;
- return k * k * ((s + 1) * k - s);
- },
- Out: function (k) {
- var s = 1.70158;
- return --k * k * ((s + 1) * k + s) + 1;
- },
- InOut: function (k) {
- var s = 1.70158 * 1.525;
- if ((k *= 2) < 1) {
- return 0.5 * (k * k * ((s + 1) * k - s));
- }
- return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
- }
- },
- Bounce: {
- In: function (k) {
- return 1 - TWEEN.Easing.Bounce.Out(1 - k);
- },
- Out: function (k) {
- if (k < (1 / 2.75)) {
- return 7.5625 * k * k;
- } else if (k < (2 / 2.75)) {
- return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
- } else if (k < (2.5 / 2.75)) {
- return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
- } else {
- return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
- }
- },
- InOut: function (k) {
- if (k < 0.5) {
- return TWEEN.Easing.Bounce.In(k * 2) * 0.5;
- }
- return TWEEN.Easing.Bounce.Out(k * 2 - 1) * 0.5 + 0.5;
- }
- }
- };
- TWEEN.Interpolation = {
- Linear: function (v, k) {
- var m = v.length - 1;
- var f = m * k;
- var i = Math.floor(f);
- var fn = TWEEN.Interpolation.Utils.Linear;
- if (k < 0) {
- return fn(v[0], v[1], f);
- }
- if (k > 1) {
- return fn(v[m], v[m - 1], m - f);
- }
- return fn(v[i], v[i + 1 > m ? m : i + 1], f - i);
- },
- Bezier: function (v, k) {
- var b = 0;
- var n = v.length - 1;
- var pw = Math.pow;
- var bn = TWEEN.Interpolation.Utils.Bernstein;
- for (var i = 0; i <= n; i++) {
- b += pw(1 - k, n - i) * pw(k, i) * v[i] * bn(n, i);
- }
- return b;
- },
- CatmullRom: function (v, k) {
- var m = v.length - 1;
- var f = m * k;
- var i = Math.floor(f);
- var fn = TWEEN.Interpolation.Utils.CatmullRom;
- if (v[0] === v[m]) {
- if (k < 0) {
- i = Math.floor(f = m * (1 + k));
- }
- return fn(v[(i - 1 + m) % m], v[i], v[(i + 1) % m], v[(i + 2) % m], f - i);
- } else {
- if (k < 0) {
- return v[0] - (fn(v[0], v[0], v[1], v[1], -f) - v[0]);
- }
- if (k > 1) {
- return v[m] - (fn(v[m], v[m], v[m - 1], v[m - 1], f - m) - v[m]);
- }
- 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);
- }
- },
- Utils: {
- Linear: function (p0, p1, t) {
- return (p1 - p0) * t + p0;
- },
- Bernstein: function (n, i) {
- var fc = TWEEN.Interpolation.Utils.Factorial;
- return fc(n) / fc(i) / fc(n - i);
- },
- Factorial: (function () {
- var a = [1];
- return function (n) {
- var s = 1;
- if (a[n]) {
- return a[n];
- }
- for (var i = n; i > 1; i--) {
- s *= i;
- }
- a[n] = s;
- return s;
- };
- })(),
- CatmullRom: function (p0, p1, p2, p3, t) {
- var v0 = (p2 - p0) * 0.5;
- var v1 = (p3 - p1) * 0.5;
- var t2 = t * t;
- var t3 = t * t2;
- return (2 * p1 - 2 * p2 + v0 + v1) * t3 + (- 3 * p1 + 3 * p2 - 2 * v0 - v1) * t2 + v0 * t + p1;
- }
- }
- };
- // UMD (Universal Module Definition)
- (function (root) {
- if (typeof define === 'function' && define.amd) {
- // AMD
- define([], function () {
- return TWEEN;
- });
- } else if (typeof module !== 'undefined' && typeof exports === 'object') {
- // Node.js
- module.exports = TWEEN;
- } else if (root !== undefined) {
- // Global variable
- root.TWEEN = TWEEN;
- }
- })(this);
- }).call(this,_dereq_('_process'))
- },{"_process":4}],2:[function(_dereq_,module,exports){
- (function (process,global){
- /*!
- * @overview es6-promise - a tiny implementation of Promises/A+.
- * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
- * @license Licensed under MIT license
- * See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
- * @version 3.3.1
- */
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
- typeof define === 'function' && define.amd ? define(factory) :
- (global.ES6Promise = factory());
- }(this, (function () { 'use strict';
- function objectOrFunction(x) {
- return typeof x === 'function' || typeof x === 'object' && x !== null;
- }
- function isFunction(x) {
- return typeof x === 'function';
- }
- var _isArray = undefined;
- if (!Array.isArray) {
- _isArray = function (x) {
- return Object.prototype.toString.call(x) === '[object Array]';
- };
- } else {
- _isArray = Array.isArray;
- }
- var isArray = _isArray;
- var len = 0;
- var vertxNext = undefined;
- var customSchedulerFn = undefined;
- var asap = function asap(callback, arg) {
- queue[len] = callback;
- queue[len + 1] = arg;
- len += 2;
- if (len === 2) {
- // If len is 2, that means that we need to schedule an async flush.
- // If additional callbacks are queued before the queue is flushed, they
- // will be processed by this flush that we are scheduling.
- if (customSchedulerFn) {
- customSchedulerFn(flush);
- } else {
- scheduleFlush();
- }
- }
- };
- function setScheduler(scheduleFn) {
- customSchedulerFn = scheduleFn;
- }
- function setAsap(asapFn) {
- asap = asapFn;
- }
- var browserWindow = typeof window !== 'undefined' ? window : undefined;
- var browserGlobal = browserWindow || {};
- var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
- var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && ({}).toString.call(process) === '[object process]';
- // test for web worker but not in IE10
- var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
- // node
- function useNextTick() {
- // node version 0.10.x displays a deprecation warning when nextTick is used recursively
- // see https://github.com/cujojs/when/issues/410 for details
- return function () {
- return process.nextTick(flush);
- };
- }
- // vertx
- function useVertxTimer() {
- return function () {
- vertxNext(flush);
- };
- }
- function useMutationObserver() {
- var iterations = 0;
- var observer = new BrowserMutationObserver(flush);
- var node = document.createTextNode('');
- observer.observe(node, { characterData: true });
- return function () {
- node.data = iterations = ++iterations % 2;
- };
- }
- // web worker
- function useMessageChannel() {
- var channel = new MessageChannel();
- channel.port1.onmessage = flush;
- return function () {
- return channel.port2.postMessage(0);
- };
- }
- function useSetTimeout() {
- // Store setTimeout reference so es6-promise will be unaffected by
- // other code modifying setTimeout (like sinon.useFakeTimers())
- var globalSetTimeout = setTimeout;
- return function () {
- return globalSetTimeout(flush, 1);
- };
- }
- var queue = new Array(1000);
- function flush() {
- for (var i = 0; i < len; i += 2) {
- var callback = queue[i];
- var arg = queue[i + 1];
- callback(arg);
- queue[i] = undefined;
- queue[i + 1] = undefined;
- }
- len = 0;
- }
- function attemptVertx() {
- try {
- var r = _dereq_;
- var vertx = r('vertx');
- vertxNext = vertx.runOnLoop || vertx.runOnContext;
- return useVertxTimer();
- } catch (e) {
- return useSetTimeout();
- }
- }
- var scheduleFlush = undefined;
- // Decide what async method to use to triggering processing of queued callbacks:
- if (isNode) {
- scheduleFlush = useNextTick();
- } else if (BrowserMutationObserver) {
- scheduleFlush = useMutationObserver();
- } else if (isWorker) {
- scheduleFlush = useMessageChannel();
- } else if (browserWindow === undefined && typeof _dereq_ === 'function') {
- scheduleFlush = attemptVertx();
- } else {
- scheduleFlush = useSetTimeout();
- }
- function then(onFulfillment, onRejection) {
- var _arguments = arguments;
- var parent = this;
- var child = new this.constructor(noop);
- if (child[PROMISE_ID] === undefined) {
- makePromise(child);
- }
- var _state = parent._state;
- if (_state) {
- (function () {
- var callback = _arguments[_state - 1];
- asap(function () {
- return invokeCallback(_state, child, callback, parent._result);
- });
- })();
- } else {
- subscribe(parent, child, onFulfillment, onRejection);
- }
- return child;
- }
- /**
- `Promise.resolve` returns a promise that will become resolved with the
- passed `value`. It is shorthand for the following:
- ```javascript
- let promise = new Promise(function(resolve, reject){
- resolve(1);
- });
- promise.then(function(value){
- // value === 1
- });
- ```
- Instead of writing the above, your code now simply becomes the following:
- ```javascript
- let promise = Promise.resolve(1);
- promise.then(function(value){
- // value === 1
- });
- ```
- @method resolve
- @static
- @param {Any} value value that the returned promise will be resolved with
- Useful for tooling.
- @return {Promise} a promise that will become fulfilled with the given
- `value`
- */
- function resolve(object) {
- /*jshint validthis:true */
- var Constructor = this;
- if (object && typeof object === 'object' && object.constructor === Constructor) {
- return object;
- }
- var promise = new Constructor(noop);
- _resolve(promise, object);
- return promise;
- }
- var PROMISE_ID = Math.random().toString(36).substring(16);
- function noop() {}
- var PENDING = void 0;
- var FULFILLED = 1;
- var REJECTED = 2;
- var GET_THEN_ERROR = new ErrorObject();
- function selfFulfillment() {
- return new TypeError("You cannot resolve a promise with itself");
- }
- function cannotReturnOwn() {
- return new TypeError('A promises callback cannot return that same promise.');
- }
- function getThen(promise) {
- try {
- return promise.then;
- } catch (error) {
- GET_THEN_ERROR.error = error;
- return GET_THEN_ERROR;
- }
- }
- function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
- try {
- then.call(value, fulfillmentHandler, rejectionHandler);
- } catch (e) {
- return e;
- }
- }
- function handleForeignThenable(promise, thenable, then) {
- asap(function (promise) {
- var sealed = false;
- var error = tryThen(then, thenable, function (value) {
- if (sealed) {
- return;
- }
- sealed = true;
- if (thenable !== value) {
- _resolve(promise, value);
- } else {
- fulfill(promise, value);
- }
- }, function (reason) {
- if (sealed) {
- return;
- }
- sealed = true;
- _reject(promise, reason);
- }, 'Settle: ' + (promise._label || ' unknown promise'));
- if (!sealed && error) {
- sealed = true;
- _reject(promise, error);
- }
- }, promise);
- }
- function handleOwnThenable(promise, thenable) {
- if (thenable._state === FULFILLED) {
- fulfill(promise, thenable._result);
- } else if (thenable._state === REJECTED) {
- _reject(promise, thenable._result);
- } else {
- subscribe(thenable, undefined, function (value) {
- return _resolve(promise, value);
- }, function (reason) {
- return _reject(promise, reason);
- });
- }
- }
- function handleMaybeThenable(promise, maybeThenable, then$$) {
- if (maybeThenable.constructor === promise.constructor && then$$ === then && maybeThenable.constructor.resolve === resolve) {
- handleOwnThenable(promise, maybeThenable);
- } else {
- if (then$$ === GET_THEN_ERROR) {
- _reject(promise, GET_THEN_ERROR.error);
- } else if (then$$ === undefined) {
- fulfill(promise, maybeThenable);
- } else if (isFunction(then$$)) {
- handleForeignThenable(promise, maybeThenable, then$$);
- } else {
- fulfill(promise, maybeThenable);
- }
- }
- }
- function _resolve(promise, value) {
- if (promise === value) {
- _reject(promise, selfFulfillment());
- } else if (objectOrFunction(value)) {
- handleMaybeThenable(promise, value, getThen(value));
- } else {
- fulfill(promise, value);
- }
- }
- function publishRejection(promise) {
- if (promise._onerror) {
- promise._onerror(promise._result);
- }
- publish(promise);
- }
- function fulfill(promise, value) {
- if (promise._state !== PENDING) {
- return;
- }
- promise._result = value;
- promise._state = FULFILLED;
- if (promise._subscribers.length !== 0) {
- asap(publish, promise);
- }
- }
- function _reject(promise, reason) {
- if (promise._state !== PENDING) {
- return;
- }
- promise._state = REJECTED;
- promise._result = reason;
- asap(publishRejection, promise);
- }
- function subscribe(parent, child, onFulfillment, onRejection) {
- var _subscribers = parent._subscribers;
- var length = _subscribers.length;
- parent._onerror = null;
- _subscribers[length] = child;
- _subscribers[length + FULFILLED] = onFulfillment;
- _subscribers[length + REJECTED] = onRejection;
- if (length === 0 && parent._state) {
- asap(publish, parent);
- }
- }
- function publish(promise) {
- var subscribers = promise._subscribers;
- var settled = promise._state;
- if (subscribers.length === 0) {
- return;
- }
- var child = undefined,
- callback = undefined,
- detail = promise._result;
- for (var i = 0; i < subscribers.length; i += 3) {
- child = subscribers[i];
- callback = subscribers[i + settled];
- if (child) {
- invokeCallback(settled, child, callback, detail);
- } else {
- callback(detail);
- }
- }
- promise._subscribers.length = 0;
- }
- function ErrorObject() {
- this.error = null;
- }
- var TRY_CATCH_ERROR = new ErrorObject();
- function tryCatch(callback, detail) {
- try {
- return callback(detail);
- } catch (e) {
- TRY_CATCH_ERROR.error = e;
- return TRY_CATCH_ERROR;
- }
- }
- function invokeCallback(settled, promise, callback, detail) {
- var hasCallback = isFunction(callback),
- value = undefined,
- error = undefined,
- succeeded = undefined,
- failed = undefined;
- if (hasCallback) {
- value = tryCatch(callback, detail);
- if (value === TRY_CATCH_ERROR) {
- failed = true;
- error = value.error;
- value = null;
- } else {
- succeeded = true;
- }
- if (promise === value) {
- _reject(promise, cannotReturnOwn());
- return;
- }
- } else {
- value = detail;
- succeeded = true;
- }
- if (promise._state !== PENDING) {
- // noop
- } else if (hasCallback && succeeded) {
- _resolve(promise, value);
- } else if (failed) {
- _reject(promise, error);
- } else if (settled === FULFILLED) {
- fulfill(promise, value);
- } else if (settled === REJECTED) {
- _reject(promise, value);
- }
- }
- function initializePromise(promise, resolver) {
- try {
- resolver(function resolvePromise(value) {
- _resolve(promise, value);
- }, function rejectPromise(reason) {
- _reject(promise, reason);
- });
- } catch (e) {
- _reject(promise, e);
- }
- }
- var id = 0;
- function nextId() {
- return id++;
- }
- function makePromise(promise) {
- promise[PROMISE_ID] = id++;
- promise._state = undefined;
- promise._result = undefined;
- promise._subscribers = [];
- }
- function Enumerator(Constructor, input) {
- this._instanceConstructor = Constructor;
- this.promise = new Constructor(noop);
- if (!this.promise[PROMISE_ID]) {
- makePromise(this.promise);
- }
- if (isArray(input)) {
- this._input = input;
- this.length = input.length;
- this._remaining = input.length;
- this._result = new Array(this.length);
- if (this.length === 0) {
- fulfill(this.promise, this._result);
- } else {
- this.length = this.length || 0;
- this._enumerate();
- if (this._remaining === 0) {
- fulfill(this.promise, this._result);
- }
- }
- } else {
- _reject(this.promise, validationError());
- }
- }
- function validationError() {
- return new Error('Array Methods must be provided an Array');
- };
- Enumerator.prototype._enumerate = function () {
- var length = this.length;
- var _input = this._input;
- for (var i = 0; this._state === PENDING && i < length; i++) {
- this._eachEntry(_input[i], i);
- }
- };
- Enumerator.prototype._eachEntry = function (entry, i) {
- var c = this._instanceConstructor;
- var resolve$$ = c.resolve;
- if (resolve$$ === resolve) {
- var _then = getThen(entry);
- if (_then === then && entry._state !== PENDING) {
- this._settledAt(entry._state, i, entry._result);
- } else if (typeof _then !== 'function') {
- this._remaining--;
- this._result[i] = entry;
- } else if (c === Promise) {
- var promise = new c(noop);
- handleMaybeThenable(promise, entry, _then);
- this._willSettleAt(promise, i);
- } else {
- this._willSettleAt(new c(function (resolve$$) {
- return resolve$$(entry);
- }), i);
- }
- } else {
- this._willSettleAt(resolve$$(entry), i);
- }
- };
- Enumerator.prototype._settledAt = function (state, i, value) {
- var promise = this.promise;
- if (promise._state === PENDING) {
- this._remaining--;
- if (state === REJECTED) {
- _reject(promise, value);
- } else {
- this._result[i] = value;
- }
- }
- if (this._remaining === 0) {
- fulfill(promise, this._result);
- }
- };
- Enumerator.prototype._willSettleAt = function (promise, i) {
- var enumerator = this;
- subscribe(promise, undefined, function (value) {
- return enumerator._settledAt(FULFILLED, i, value);
- }, function (reason) {
- return enumerator._settledAt(REJECTED, i, reason);
- });
- };
- /**
- `Promise.all` accepts an array of promises, and returns a new promise which
- is fulfilled with an array of fulfillment values for the passed promises, or
- rejected with the reason of the first passed promise to be rejected. It casts all
- elements of the passed iterable to promises as it runs this algorithm.
- Example:
- ```javascript
- let promise1 = resolve(1);
- let promise2 = resolve(2);
- let promise3 = resolve(3);
- let promises = [ promise1, promise2, promise3 ];
- Promise.all(promises).then(function(array){
- // The array here would be [ 1, 2, 3 ];
- });
- ```
- If any of the `promises` given to `all` are rejected, the first promise
- that is rejected will be given as an argument to the returned promises's
- rejection handler. For example:
- Example:
- ```javascript
- let promise1 = resolve(1);
- let promise2 = reject(new Error("2"));
- let promise3 = reject(new Error("3"));
- let promises = [ promise1, promise2, promise3 ];
- Promise.all(promises).then(function(array){
- // Code here never runs because there are rejected promises!
- }, function(error) {
- // error.message === "2"
- });
- ```
- @method all
- @static
- @param {Array} entries array of promises
- @param {String} label optional string for labeling the promise.
- Useful for tooling.
- @return {Promise} promise that is fulfilled when all `promises` have been
- fulfilled, or rejected if any of them become rejected.
- @static
- */
- function all(entries) {
- return new Enumerator(this, entries).promise;
- }
- /**
- `Promise.race` returns a new promise which is settled in the same way as the
- first passed promise to settle.
- Example:
- ```javascript
- let promise1 = new Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 1');
- }, 200);
- });
- let promise2 = new Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 2');
- }, 100);
- });
- Promise.race([promise1, promise2]).then(function(result){
- // result === 'promise 2' because it was resolved before promise1
- // was resolved.
- });
- ```
- `Promise.race` is deterministic in that only the state of the first
- settled promise matters. For example, even if other promises given to the
- `promises` array argument are resolved, but the first settled promise has
- become rejected before the other promises became fulfilled, the returned
- promise will become rejected:
- ```javascript
- let promise1 = new Promise(function(resolve, reject){
- setTimeout(function(){
- resolve('promise 1');
- }, 200);
- });
- let promise2 = new Promise(function(resolve, reject){
- setTimeout(function(){
- reject(new Error('promise 2'));
- }, 100);
- });
- Promise.race([promise1, promise2]).then(function(result){
- // Code here never runs
- }, function(reason){
- // reason.message === 'promise 2' because promise 2 became rejected before
- // promise 1 became fulfilled
- });
- ```
- An example real-world use case is implementing timeouts:
- ```javascript
- Promise.race([ajax('foo.json'), timeout(5000)])
- ```
- @method race
- @static
- @param {Array} promises array of promises to observe
- Useful for tooling.
- @return {Promise} a promise which settles in the same way as the first passed
- promise to settle.
- */
- function race(entries) {
- /*jshint validthis:true */
- var Constructor = this;
- if (!isArray(entries)) {
- return new Constructor(function (_, reject) {
- return reject(new TypeError('You must pass an array to race.'));
- });
- } else {
- return new Constructor(function (resolve, reject) {
- var length = entries.length;
- for (var i = 0; i < length; i++) {
- Constructor.resolve(entries[i]).then(resolve, reject);
- }
- });
- }
- }
- /**
- `Promise.reject` returns a promise rejected with the passed `reason`.
- It is shorthand for the following:
- ```javascript
- let promise = new Promise(function(resolve, reject){
- reject(new Error('WHOOPS'));
- });
- promise.then(function(value){
- // Code here doesn't run because the promise is rejected!
- }, function(reason){
- // reason.message === 'WHOOPS'
- });
- ```
- Instead of writing the above, your code now simply becomes the following:
- ```javascript
- let promise = Promise.reject(new Error('WHOOPS'));
- promise.then(function(value){
- // Code here doesn't run because the promise is rejected!
- }, function(reason){
- // reason.message === 'WHOOPS'
- });
- ```
- @method reject
- @static
- @param {Any} reason value that the returned promise will be rejected with.
- Useful for tooling.
- @return {Promise} a promise rejected with the given `reason`.
- */
- function reject(reason) {
- /*jshint validthis:true */
- var Constructor = this;
- var promise = new Constructor(noop);
- _reject(promise, reason);
- return promise;
- }
- function needsResolver() {
- throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
- }
- function needsNew() {
- throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
- }
- /**
- Promise objects represent the eventual result of an asynchronous operation. The
- primary way of interacting with a promise is through its `then` method, which
- registers callbacks to receive either a promise's eventual value or the reason
- why the promise cannot be fulfilled.
- Terminology
- -----------
- - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- - `thenable` is an object or function that defines a `then` method.
- - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- - `exception` is a value that is thrown using the throw statement.
- - `reason` is a value that indicates why a promise was rejected.
- - `settled` the final resting state of a promise, fulfilled or rejected.
- A promise can be in one of three states: pending, fulfilled, or rejected.
- Promises that are fulfilled have a fulfillment value and are in the fulfilled
- state. Promises that are rejected have a rejection reason and are in the
- rejected state. A fulfillment value is never a thenable.
- Promises can also be said to *resolve* a value. If this value is also a
- promise, then the original promise's settled state will match the value's
- settled state. So a promise that *resolves* a promise that rejects will
- itself reject, and a promise that *resolves* a promise that fulfills will
- itself fulfill.
- Basic Usage:
- ------------
- ```js
- let promise = new Promise(function(resolve, reject) {
- // on success
- resolve(value);
- // on failure
- reject(reason);
- });
- promise.then(function(value) {
- // on fulfillment
- }, function(reason) {
- // on rejection
- });
- ```
- Advanced Usage:
- ---------------
- Promises shine when abstracting away asynchronous interactions such as
- `XMLHttpRequest`s.
- ```js
- function getJSON(url) {
- return new Promise(function(resolve, reject){
- let xhr = new XMLHttpRequest();
- xhr.open('GET', url);
- xhr.onreadystatechange = handler;
- xhr.responseType = 'json';
- xhr.setRequestHeader('Accept', 'application/json');
- xhr.send();
- function handler() {
- if (this.readyState === this.DONE) {
- if (this.status === 200) {
- resolve(this.response);
- } else {
- reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
- }
- }
- };
- });
- }
- getJSON('/posts.json').then(function(json) {
- // on fulfillment
- }, function(reason) {
- // on rejection
- });
- ```
- Unlike callbacks, promises are great composable primitives.
- ```js
- Promise.all([
- getJSON('/posts'),
- getJSON('/comments')
- ]).then(function(values){
- values[0] // => postsJSON
- values[1] // => commentsJSON
- return values;
- });
- ```
- @class Promise
- @param {function} resolver
- Useful for tooling.
- @constructor
- */
- function Promise(resolver) {
- this[PROMISE_ID] = nextId();
- this._result = this._state = undefined;
- this._subscribers = [];
- if (noop !== resolver) {
- typeof resolver !== 'function' && needsResolver();
- this instanceof Promise ? initializePromise(this, resolver) : needsNew();
- }
- }
- Promise.all = all;
- Promise.race = race;
- Promise.resolve = resolve;
- Promise.reject = reject;
- Promise._setScheduler = setScheduler;
- Promise._setAsap = setAsap;
- Promise._asap = asap;
- Promise.prototype = {
- constructor: Promise,
- /**
- The primary way of interacting with a promise is through its `then` method,
- which registers callbacks to receive either a promise's eventual value or the
- reason why the promise cannot be fulfilled.
-
- ```js
- findUser().then(function(user){
- // user is available
- }, function(reason){
- // user is unavailable, and you are given the reason why
- });
- ```
-
- Chaining
- --------
-
- The return value of `then` is itself a promise. This second, 'downstream'
- promise is resolved with the return value of the first promise's fulfillment
- or rejection handler, or rejected if the handler throws an exception.
-
- ```js
- findUser().then(function (user) {
- return user.name;
- }, function (reason) {
- return 'default name';
- }).then(function (userName) {
- // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
- // will be `'default name'`
- });
-
- findUser().then(function (user) {
- throw new Error('Found user, but still unhappy');
- }, function (reason) {
- throw new Error('`findUser` rejected and we're unhappy');
- }).then(function (value) {
- // never reached
- }, function (reason) {
- // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
- // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
- });
- ```
- If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
-
- ```js
- findUser().then(function (user) {
- throw new PedagogicalException('Upstream error');
- }).then(function (value) {
- // never reached
- }).then(function (value) {
- // never reached
- }, function (reason) {
- // The `PedgagocialException` is propagated all the way down to here
- });
- ```
-
- Assimilation
- ------------
-
- Sometimes the value you want to propagate to a downstream promise can only be
- retrieved asynchronously. This can be achieved by returning a promise in the
- fulfillment or rejection handler. The downstream promise will then be pending
- until the returned promise is settled. This is called *assimilation*.
-
- ```js
- findUser().then(function (user) {
- return findCommentsByAuthor(user);
- }).then(function (comments) {
- // The user's comments are now available
- });
- ```
-
- If the assimliated promise rejects, then the downstream promise will also reject.
-
- ```js
- findUser().then(function (user) {
- return findCommentsByAuthor(user);
- }).then(function (comments) {
- // If `findCommentsByAuthor` fulfills, we'll have the value here
- }, function (reason) {
- // If `findCommentsByAuthor` rejects, we'll have the reason here
- });
- ```
-
- Simple Example
- --------------
-
- Synchronous Example
-
- ```javascript
- let result;
-
- try {
- result = findResult();
- // success
- } catch(reason) {
- // failure
- }
- ```
-
- Errback Example
-
- ```js
- findResult(function(result, err){
- if (err) {
- // failure
- } else {
- // success
- }
- });
- ```
-
- Promise Example;
-
- ```javascript
- findResult().then(function(result){
- // success
- }, function(reason){
- // failure
- });
- ```
-
- Advanced Example
- --------------
-
- Synchronous Example
-
- ```javascript
- let author, books;
-
- try {
- author = findAuthor();
- books = findBooksByAuthor(author);
- // success
- } catch(reason) {
- // failure
- }
- ```
-
- Errback Example
-
- ```js
-
- function foundBooks(books) {
-
- }
-
- function failure(reason) {
-
- }
-
- findAuthor(function(author, err){
- if (err) {
- failure(err);
- // failure
- } else {
- try {
- findBoooksByAuthor(author, function(books, err) {
- if (err) {
- failure(err);
- } else {
- try {
- foundBooks(books);
- } catch(reason) {
- failure(reason);
- }
- }
- });
- } catch(error) {
- failure(err);
- }
- // success
- }
- });
- ```
-
- Promise Example;
-
- ```javascript
- findAuthor().
- then(findBooksByAuthor).
- then(function(books){
- // found books
- }).catch(function(reason){
- // something went wrong
- });
- ```
-
- @method then
- @param {Function} onFulfilled
- @param {Function} onRejected
- Useful for tooling.
- @return {Promise}
- */
- then: then,
- /**
- `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
- as the catch block of a try/catch statement.
-
- ```js
- function findAuthor(){
- throw new Error('couldn't find that author');
- }
-
- // synchronous
- try {
- findAuthor();
- } catch(reason) {
- // something went wrong
- }
-
- // async with promises
- findAuthor().catch(function(reason){
- // something went wrong
- });
- ```
-
- @method catch
- @param {Function} onRejection
- Useful for tooling.
- @return {Promise}
- */
- 'catch': function _catch(onRejection) {
- return this.then(null, onRejection);
- }
- };
- function polyfill() {
- var local = undefined;
- if (typeof global !== 'undefined') {
- local = global;
- } else if (typeof self !== 'undefined') {
- local = self;
- } else {
- try {
- local = Function('return this')();
- } catch (e) {
- throw new Error('polyfill failed because global object is unavailable in this environment');
- }
- }
- var P = local.Promise;
- if (P) {
- var promiseToString = null;
- try {
- promiseToString = Object.prototype.toString.call(P.resolve());
- } catch (e) {
- // silently ignored
- }
- if (promiseToString === '[object Promise]' && !P.cast) {
- return;
- }
- }
- local.Promise = Promise;
- }
- polyfill();
- // Strange compat..
- Promise.polyfill = polyfill;
- Promise.Promise = Promise;
- return Promise;
- })));
- }).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{"_process":4}],3:[function(_dereq_,module,exports){
- 'use strict';
- var has = Object.prototype.hasOwnProperty;
- //
- // We store our EE objects in a plain object whose properties are event names.
- // If `Object.create(null)` is not supported we prefix the event names with a
- // `~` to make sure that the built-in object properties are not overridden or
- // used as an attack vector.
- // We also assume that `Object.create(null)` is available when the event name
- // is an ES6 Symbol.
- //
- var prefix = typeof Object.create !== 'function' ? '~' : false;
- /**
- * Representation of a single EventEmitter function.
- *
- * @param {Function} fn Event handler to be called.
- * @param {Mixed} context Context for function execution.
- * @param {Boolean} [once=false] Only emit once
- * @api private
- */
- function EE(fn, context, once) {
- this.fn = fn;
- this.context = context;
- this.once = once || false;
- }
- /**
- * Minimal EventEmitter interface that is molded against the Node.js
- * EventEmitter interface.
- *
- * @constructor
- * @api public
- */
- function EventEmitter() { /* Nothing to set */ }
- /**
- * Hold the assigned EventEmitters by name.
- *
- * @type {Object}
- * @private
- */
- EventEmitter.prototype._events = undefined;
- /**
- * Return an array listing the events for which the emitter has registered
- * listeners.
- *
- * @returns {Array}
- * @api public
- */
- EventEmitter.prototype.eventNames = function eventNames() {
- var events = this._events
- , names = []
- , name;
- if (!events) return names;
- for (name in events) {
- if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
- }
- if (Object.getOwnPropertySymbols) {
- return names.concat(Object.getOwnPropertySymbols(events));
- }
- return names;
- };
- /**
- * Return a list of assigned event listeners.
- *
- * @param {String} event The events that should be listed.
- * @param {Boolean} exists We only need to know if there are listeners.
- * @returns {Array|Boolean}
- * @api public
- */
- EventEmitter.prototype.listeners = function listeners(event, exists) {
- var evt = prefix ? prefix + event : event
- , available = this._events && this._events[evt];
- if (exists) return !!available;
- if (!available) return [];
- if (available.fn) return [available.fn];
- for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
- ee[i] = available[i].fn;
- }
- return ee;
- };
- /**
- * Emit an event to all registered event listeners.
- *
- * @param {String} event The name of the event.
- * @returns {Boolean} Indication if we've emitted an event.
- * @api public
- */
- EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
- var evt = prefix ? prefix + event : event;
- if (!this._events || !this._events[evt]) return false;
- var listeners = this._events[evt]
- , len = arguments.length
- , args
- , i;
- if ('function' === typeof listeners.fn) {
- if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
- switch (len) {
- case 1: return listeners.fn.call(listeners.context), true;
- case 2: return listeners.fn.call(listeners.context, a1), true;
- case 3: return listeners.fn.call(listeners.context, a1, a2), true;
- case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
- case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
- case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
- }
- for (i = 1, args = new Array(len -1); i < len; i++) {
- args[i - 1] = arguments[i];
- }
- listeners.fn.apply(listeners.context, args);
- } else {
- var length = listeners.length
- , j;
- for (i = 0; i < length; i++) {
- if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
- switch (len) {
- case 1: listeners[i].fn.call(listeners[i].context); break;
- case 2: listeners[i].fn.call(listeners[i].context, a1); break;
- case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
- default:
- if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
- args[j - 1] = arguments[j];
- }
- listeners[i].fn.apply(listeners[i].context, args);
- }
- }
- }
- return true;
- };
- /**
- * Register a new EventListener for the given event.
- *
- * @param {String} event Name of the event.
- * @param {Function} fn Callback function.
- * @param {Mixed} [context=this] The context of the function.
- * @api public
- */
- EventEmitter.prototype.on = function on(event, fn, context) {
- var listener = new EE(fn, context || this)
- , evt = prefix ? prefix + event : event;
- if (!this._events) this._events = prefix ? {} : Object.create(null);
- if (!this._events[evt]) this._events[evt] = listener;
- else {
- if (!this._events[evt].fn) this._events[evt].push(listener);
- else this._events[evt] = [
- this._events[evt], listener
- ];
- }
- return this;
- };
- /**
- * Add an EventListener that's only called once.
- *
- * @param {String} event Name of the event.
- * @param {Function} fn Callback function.
- * @param {Mixed} [context=this] The context of the function.
- * @api public
- */
- EventEmitter.prototype.once = function once(event, fn, context) {
- var listener = new EE(fn, context || this, true)
- , evt = prefix ? prefix + event : event;
- if (!this._events) this._events = prefix ? {} : Object.create(null);
- if (!this._events[evt]) this._events[evt] = listener;
- else {
- if (!this._events[evt].fn) this._events[evt].push(listener);
- else this._events[evt] = [
- this._events[evt], listener
- ];
- }
- return this;
- };
- /**
- * Remove event listeners.
- *
- * @param {String} event The event we want to remove.
- * @param {Function} fn The listener that we need to find.
- * @param {Mixed} context Only remove listeners matching this context.
- * @param {Boolean} once Only remove once listeners.
- * @api public
- */
- EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
- var evt = prefix ? prefix + event : event;
- if (!this._events || !this._events[evt]) return this;
- var listeners = this._events[evt]
- , events = [];
- if (fn) {
- if (listeners.fn) {
- if (
- listeners.fn !== fn
- || (once && !listeners.once)
- || (context && listeners.context !== context)
- ) {
- events.push(listeners);
- }
- } else {
- for (var i = 0, length = listeners.length; i < length; i++) {
- if (
- listeners[i].fn !== fn
- || (once && !listeners[i].once)
- || (context && listeners[i].context !== context)
- ) {
- events.push(listeners[i]);
- }
- }
- }
- }
- //
- // Reset the array, or remove it completely if we have no more listeners.
- //
- if (events.length) {
- this._events[evt] = events.length === 1 ? events[0] : events;
- } else {
- delete this._events[evt];
- }
- return this;
- };
- /**
- * Remove all listeners or only the listeners for the specified event.
- *
- * @param {String} event The event want to remove all listeners for.
- * @api public
- */
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
- if (!this._events) return this;
- if (event) delete this._events[prefix ? prefix + event : event];
- else this._events = prefix ? {} : Object.create(null);
- return this;
- };
- //
- // Alias methods names because people roll like that.
- //
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
- EventEmitter.prototype.addListener = EventEmitter.prototype.on;
- //
- // This function doesn't apply anymore.
- //
- EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
- return this;
- };
- //
- // Expose the prefix.
- //
- EventEmitter.prefixed = prefix;
- //
- // Expose the module.
- //
- if ('undefined' !== typeof module) {
- module.exports = EventEmitter;
- }
- },{}],4:[function(_dereq_,module,exports){
- // shim for using process in browser
- var process = module.exports = {};
- // cached from whatever global is present so that test runners that stub it
- // don't break things. But we need to wrap it in a try catch in case it is
- // wrapped in strict mode code which doesn't define any globals. It's inside a
- // function because try/catches deoptimize in certain engines.
- var cachedSetTimeout;
- var cachedClearTimeout;
- function defaultSetTimout() {
- throw new Error('setTimeout has not been defined');
- }
- function defaultClearTimeout () {
- throw new Error('clearTimeout has not been defined');
- }
- (function () {
- try {
- if (typeof setTimeout === 'function') {
- cachedSetTimeout = setTimeout;
- } else {
- cachedSetTimeout = defaultSetTimout;
- }
- } catch (e) {
- cachedSetTimeout = defaultSetTimout;
- }
- try {
- if (typeof clearTimeout === 'function') {
- cachedClearTimeout = clearTimeout;
- } else {
- cachedClearTimeout = defaultClearTimeout;
- }
- } catch (e) {
- cachedClearTimeout = defaultClearTimeout;
- }
- } ())
- function runTimeout(fun) {
- if (cachedSetTimeout === setTimeout) {
- //normal enviroments in sane situations
- return setTimeout(fun, 0);
- }
- // if setTimeout wasn't available but was latter defined
- if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
- cachedSetTimeout = setTimeout;
- return setTimeout(fun, 0);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedSetTimeout(fun, 0);
- } catch(e){
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedSetTimeout.call(null, fun, 0);
- } catch(e){
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
- return cachedSetTimeout.call(this, fun, 0);
- }
- }
- }
- function runClearTimeout(marker) {
- if (cachedClearTimeout === clearTimeout) {
- //normal enviroments in sane situations
- return clearTimeout(marker);
- }
- // if clearTimeout wasn't available but was latter defined
- if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
- cachedClearTimeout = clearTimeout;
- return clearTimeout(marker);
- }
- try {
- // when when somebody has screwed with setTimeout but no I.E. maddness
- return cachedClearTimeout(marker);
- } catch (e){
- try {
- // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
- return cachedClearTimeout.call(null, marker);
- } catch (e){
- // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
- // Some versions of I.E. have different rules for clearTimeout vs setTimeout
- return cachedClearTimeout.call(this, marker);
- }
- }
- }
- var queue = [];
- var draining = false;
- var currentQueue;
- var queueIndex = -1;
- function cleanUpNextTick() {
- if (!draining || !currentQueue) {
- return;
- }
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
- }
- function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = runTimeout(cleanUpNextTick);
- draining = true;
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- if (currentQueue) {
- currentQueue[queueIndex].run();
- }
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- runClearTimeout(timeout);
- }
- process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- runTimeout(drainQueue);
- }
- };
- // v8 likes predictible objects
- function Item(fun, array) {
- this.fun = fun;
- this.array = array;
- }
- Item.prototype.run = function () {
- this.fun.apply(null, this.array);
- };
- process.title = 'browser';
- process.browser = true;
- process.env = {};
- process.argv = [];
- process.version = ''; // empty string to avoid regexp issues
- process.versions = {};
- function noop() {}
- process.on = noop;
- process.addListener = noop;
- process.once = noop;
- process.off = noop;
- process.removeListener = noop;
- process.removeAllListeners = noop;
- process.emit = noop;
- process.prependListener = noop;
- process.prependOnceListener = noop;
- process.listeners = function (name) { return [] }
- process.binding = function (name) {
- throw new Error('process.binding is not supported');
- };
- process.cwd = function () { return '/' };
- process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
- };
- process.umask = function() { return 0; };
- },{}],5:[function(_dereq_,module,exports){
- (function(){var g={};
- (function(window){var k,aa=this;aa.we=!0;function n(a,b){var c=a.split("."),d=aa;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d[e]?d=d[e]:d=d[e]={}:d[e]=b}function ba(a){var b=p;function c(){}c.prototype=b.prototype;a.Be=b.prototype;a.prototype=new c;a.prototype.constructor=a;a.ye=function(a,c,f){return b.prototype[c].apply(a,Array.prototype.slice.call(arguments,2))}};/*
- Copyright 2016 Google Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- function ca(a){this.c=Math.exp(Math.log(.5)/a);this.b=this.a=0}function da(a,b,c){var d=Math.pow(a.c,b);c=c*(1-d)+d*a.a;isNaN(c)||(a.a=c,a.b+=b)}function ea(a){return a.a/(1-Math.pow(a.c,a.b))};function fa(){this.c=new ca(2);this.f=new ca(5);this.a=0;this.b=5E5}fa.prototype.setDefaultEstimate=function(a){this.b=a};fa.prototype.getBandwidthEstimate=function(){return 128E3>this.a?this.b:Math.min(ea(this.c),ea(this.f))};function ga(){};function t(a,b,c,d){this.severity=a;this.category=b;this.code=c;this.data=Array.prototype.slice.call(arguments,3)}n("shaka.util.Error",t);t.prototype.toString=function(){return"shaka.util.Error "+JSON.stringify(this,null," ")};t.Severity={RECOVERABLE:1,CRITICAL:2};t.Category={NETWORK:1,TEXT:2,MEDIA:3,MANIFEST:4,STREAMING:5,DRM:6,PLAYER:7,CAST:8,STORAGE:9};
- t.Code={UNSUPPORTED_SCHEME:1E3,BAD_HTTP_STATUS:1001,HTTP_ERROR:1002,TIMEOUT:1003,MALFORMED_DATA_URI:1004,UNKNOWN_DATA_URI_ENCODING:1005,REQUEST_FILTER_ERROR:1006,RESPONSE_FILTER_ERROR:1007,INVALID_TEXT_HEADER:2E3,INVALID_TEXT_CUE:2001,UNABLE_TO_DETECT_ENCODING:2003,BAD_ENCODING:2004,INVALID_XML:2005,INVALID_MP4_TTML:2007,INVALID_MP4_VTT:2008,BUFFER_READ_OUT_OF_BOUNDS:3E3,JS_INTEGER_OVERFLOW:3001,EBML_OVERFLOW:3002,EBML_BAD_FLOATING_POINT_SIZE:3003,MP4_SIDX_WRONG_BOX_TYPE:3004,MP4_SIDX_INVALID_TIMESCALE:3005,
- MP4_SIDX_TYPE_NOT_SUPPORTED:3006,WEBM_CUES_ELEMENT_MISSING:3007,WEBM_EBML_HEADER_ELEMENT_MISSING:3008,WEBM_SEGMENT_ELEMENT_MISSING:3009,WEBM_INFO_ELEMENT_MISSING:3010,WEBM_DURATION_ELEMENT_MISSING:3011,WEBM_CUE_TRACK_POSITIONS_ELEMENT_MISSING:3012,WEBM_CUE_TIME_ELEMENT_MISSING:3013,MEDIA_SOURCE_OPERATION_FAILED:3014,MEDIA_SOURCE_OPERATION_THREW:3015,VIDEO_ERROR:3016,QUOTA_EXCEEDED_ERROR:3017,UNABLE_TO_GUESS_MANIFEST_TYPE:4E3,DASH_INVALID_XML:4001,DASH_NO_SEGMENT_INFO:4002,DASH_EMPTY_ADAPTATION_SET:4003,
- DASH_EMPTY_PERIOD:4004,DASH_WEBM_MISSING_INIT:4005,DASH_UNSUPPORTED_CONTAINER:4006,DASH_PSSH_BAD_ENCODING:4007,DASH_NO_COMMON_KEY_SYSTEM:4008,DASH_MULTIPLE_KEY_IDS_NOT_SUPPORTED:4009,DASH_CONFLICTING_KEY_IDS:4010,UNPLAYABLE_PERIOD:4011,RESTRICTIONS_CANNOT_BE_MET:4012,NO_PERIODS:4014,HLS_PLAYLIST_HEADER_MISSING:4015,INVALID_HLS_TAG:4016,HLS_INVALID_PLAYLIST_HIERARCHY:4017,DASH_DUPLICATE_REPRESENTATION_ID:4018,HLS_MULTIPLE_MEDIA_INIT_SECTIONS_FOUND:4020,HLS_COULD_NOT_GUESS_MIME_TYPE:4021,HLS_MASTER_PLAYLIST_NOT_PROVIDED:4022,
- HLS_REQUIRED_ATTRIBUTE_MISSING:4023,HLS_REQUIRED_TAG_MISSING:4024,HLS_COULD_NOT_GUESS_CODECS:4025,HLS_KEYFORMATS_NOT_SUPPORTED:4026,INVALID_STREAMS_CHOSEN:5005,NO_RECOGNIZED_KEY_SYSTEMS:6E3,REQUESTED_KEY_SYSTEM_CONFIG_UNAVAILABLE:6001,FAILED_TO_CREATE_CDM:6002,FAILED_TO_ATTACH_TO_VIDEO:6003,INVALID_SERVER_CERTIFICATE:6004,FAILED_TO_CREATE_SESSION:6005,FAILED_TO_GENERATE_LICENSE_REQUEST:6006,LICENSE_REQUEST_FAILED:6007,LICENSE_RESPONSE_REJECTED:6008,ENCRYPTED_CONTENT_WITHOUT_DRM_INFO:6010,NO_LICENSE_SERVER_GIVEN:6012,
- OFFLINE_SESSION_REMOVED:6013,EXPIRED:6014,LOAD_INTERRUPTED:7E3,CAST_API_UNAVAILABLE:8E3,NO_CAST_RECEIVERS:8001,ALREADY_CASTING:8002,UNEXPECTED_CAST_ERROR:8003,CAST_CANCELED_BY_USER:8004,CAST_CONNECTION_TIMED_OUT:8005,CAST_RECEIVER_APP_UNAVAILABLE:8006,STORAGE_NOT_SUPPORTED:9E3,INDEXED_DB_ERROR:9001,OPERATION_ABORTED:9002,REQUESTED_ITEM_NOT_FOUND:9003,MALFORMED_OFFLINE_URI:9004,CANNOT_STORE_LIVE_OFFLINE:9005,STORE_ALREADY_IN_PROGRESS:9006,NO_INIT_DATA_FOR_OFFLINE:9007,LOCAL_PLAYER_INSTANCE_REQUIRED:9008};var ha=/^(?:([^:/?#.]+):)?(?:\/\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\?([^#]*))?(?:#(.*))?$/;function ia(a){var b;a instanceof ia?(ja(this,a.aa),this.Ba=a.Ba,this.ca=a.ca,ka(this,a.Ja),this.W=a.W,la(this,ma(a.a)),this.ta=a.ta):a&&(b=String(a).match(ha))?(ja(this,b[1]||"",!0),this.Ba=na(b[2]||""),this.ca=na(b[3]||"",!0),ka(this,b[4]),this.W=na(b[5]||"",!0),la(this,b[6]||"",!0),this.ta=na(b[7]||"")):this.a=new oa(null)}k=ia.prototype;k.aa="";k.Ba="";k.ca="";k.Ja=null;k.W="";k.ta="";
- k.toString=function(){var a=[],b=this.aa;b&&a.push(qa(b,ra,!0),":");if(b=this.ca){a.push("//");var c=this.Ba;c&&a.push(qa(c,ra,!0),"@");a.push(encodeURIComponent(b).replace(/%25([0-9a-fA-F]{2})/g,"%$1"));b=this.Ja;null!=b&&a.push(":",String(b))}if(b=this.W)this.ca&&"/"!=b.charAt(0)&&a.push("/"),a.push(qa(b,"/"==b.charAt(0)?sa:ta,!0));(b=this.a.toString())&&a.push("?",b);(b=this.ta)&&a.push("#",qa(b,ua));return a.join("")};
- k.resolve=function(a){var b=new ia(this);"data"===b.aa&&(b=new ia);var c=!!a.aa;c?ja(b,a.aa):c=!!a.Ba;c?b.Ba=a.Ba:c=!!a.ca;c?b.ca=a.ca:c=null!=a.Ja;var d=a.W;if(c)ka(b,a.Ja);else if(c=!!a.W){if("/"!=d.charAt(0))if(this.ca&&!this.W)d="/"+d;else{var e=b.W.lastIndexOf("/");-1!=e&&(d=b.W.substr(0,e+1)+d)}if(".."==d||"."==d)d="";else if(-1!=d.indexOf("./")||-1!=d.indexOf("/.")){for(var e=!d.lastIndexOf("/",0),d=d.split("/"),f=[],g=0;g<d.length;){var h=d[g++];"."==h?e&&g==d.length&&f.push(""):".."==h?((1<
- f.length||1==f.length&&""!=f[0])&&f.pop(),e&&g==d.length&&f.push("")):(f.push(h),e=!0)}d=f.join("/")}}c?b.W=d:c=""!==a.a.toString();c?la(b,ma(a.a)):c=!!a.ta;c&&(b.ta=a.ta);return b};function ja(a,b,c){a.aa=c?na(b,!0):b;a.aa&&(a.aa=a.aa.replace(/:$/,""))}function ka(a,b){if(b){b=Number(b);if(isNaN(b)||0>b)throw Error("Bad port number "+b);a.Ja=b}else a.Ja=null}function la(a,b,c){b instanceof oa?a.a=b:(c||(b=qa(b,va)),a.a=new oa(b))}
- function na(a,b){return a?b?decodeURI(a):decodeURIComponent(a):""}function qa(a,b,c){return"string"==typeof a?(a=encodeURI(a).replace(b,wa),c&&(a=a.replace(/%25([0-9a-fA-F]{2})/g,"%$1")),a):null}function wa(a){a=a.charCodeAt(0);return"%"+(a>>4&15).toString(16)+(a&15).toString(16)}var ra=/[#\/\?@]/g,ta=/[\#\?:]/g,sa=/[\#\?]/g,va=/[\#\?@]/g,ua=/#/g;function oa(a){this.b=a||null}oa.prototype.a=null;oa.prototype.c=null;
- oa.prototype.toString=function(){if(this.b)return this.b;if(!this.a)return"";var a=[],b;for(b in this.a)for(var c=encodeURIComponent(b),d=this.a[b],e=0;e<d.length;e++){var f=c;""!==d[e]&&(f+="="+encodeURIComponent(d[e]));a.push(f)}return this.b=a.join("&")};function ma(a){var b=new oa;b.b=a.b;if(a.a){var c={},d;for(d in a.a)c[d]=a.a[d].concat();b.a=c;b.c=a.c}return b};function xa(a,b){return a.reduce(function(a,b,e){return b["catch"](a.bind(null,e))}.bind(null,b),Promise.reject())}function x(a,b){return a.concat(b)}function y(){}function ya(a){return null!=a}function za(a){return function(b){return b!=a}}function Aa(a,b,c){return c.indexOf(a)==b};function z(a,b){if(!b.length)return a;var c=b.map(function(a){return new ia(a)});return a.map(function(a){return new ia(a)}).map(function(a){return c.map(a.resolve.bind(a))}).reduce(x,[]).map(function(a){return a.toString()})}function Ba(a,b){return{keySystem:a,licenseServerUri:"",distinctiveIdentifierRequired:!1,persistentStateRequired:!1,audioRobustness:"",videoRobustness:"",serverCertificate:null,initData:b||[],keyIds:[]}};function Ca(a,b,c,d,e){var f=e in d,g;for(g in b){var h=e+"."+g,l=f?d[e]:c[g],m=!!{".abr.manager":!0}[h]||!!{serverCertificate:!0}[g];if(f||g in a)void 0===b[g]?void 0===l||f?delete a[g]:a[g]=l:m?a[g]=b[g]:"object"==typeof a[g]&&"object"==typeof b[g]?Ca(a[g],b[g],l,d,h):typeof b[g]==typeof l&&(a[g]=b[g])}}function Da(a){return JSON.parse(JSON.stringify(a))};function A(){var a,b,c=new Promise(function(c,e){a=c;b=e});c.resolve=a;c.reject=b;return c};function B(a){this.f=!1;this.a=[];this.b=[];this.c=[];this.h=a||null}n("shaka.net.NetworkingEngine",B);B.RequestType={MANIFEST:0,SEGMENT:1,LICENSE:2,APP:3};var Ea={};B.registerScheme=function(a,b){Ea[a]=b};B.unregisterScheme=function(a){delete Ea[a]};B.prototype.Ld=function(a){this.b.push(a)};B.prototype.registerRequestFilter=B.prototype.Ld;B.prototype.oe=function(a){var b=this.b;a=b.indexOf(a);0<=a&&b.splice(a,1)};B.prototype.unregisterRequestFilter=B.prototype.oe;
- B.prototype.Ic=function(){this.b=[]};B.prototype.clearAllRequestFilters=B.prototype.Ic;B.prototype.Md=function(a){this.c.push(a)};B.prototype.registerResponseFilter=B.prototype.Md;B.prototype.pe=function(a){var b=this.c;a=b.indexOf(a);0<=a&&b.splice(a,1)};B.prototype.unregisterResponseFilter=B.prototype.pe;B.prototype.Jc=function(){this.c=[]};B.prototype.clearAllResponseFilters=B.prototype.Jc;function Fa(){return{maxAttempts:2,baseDelay:1E3,backoffFactor:2,fuzzFactor:.5,timeout:0}}
- function C(a,b){return{uris:a,method:"GET",body:null,headers:{},allowCrossSiteCredentials:!1,retryParameters:b}}B.prototype.m=function(){this.f=!0;this.b=[];this.c=[];for(var a=[],b=0;b<this.a.length;++b)a.push(this.a[b]["catch"](y));return Promise.all(a)};B.prototype.destroy=B.prototype.m;
- B.prototype.request=function(a,b){if(this.f)return Promise.reject();b.method=b.method||"GET";b.headers=b.headers||{};b.retryParameters=b.retryParameters?Da(b.retryParameters):Fa();b.uris=Da(b.uris);var c=Date.now(),d=Promise.resolve();this.b.forEach(function(c){d=d.then(c.bind(null,a,b))});d=d["catch"](function(a){throw new t(2,1,1006,a);});d=d.then(function(){for(var d=Date.now()-c,f=b.retryParameters||{},g=f.maxAttempts||1,h=f.backoffFactor||2,f=null==f.baseDelay?1E3:f.baseDelay,l=this.g(a,b,0,
- d),m=1;m<g;m++)l=l["catch"](function(c,e,f){if(f&&1==f.severity){f=new A;var g=b.retryParameters||{};window.setTimeout(f.resolve,c*(1+(2*Math.random()-1)*(null==g.fuzzFactor?.5:g.fuzzFactor)));return f.then(this.g.bind(this,a,b,e,d))}throw f;}.bind(this,f,m%b.uris.length)),f*=h;return l}.bind(this));this.a.push(d);return d.then(function(b){0<=this.a.indexOf(d)&&this.a.splice(this.a.indexOf(d),1);this.h&&!b.fromCache&&1==a&&this.h(b.timeMs,b.data.byteLength);return b}.bind(this))["catch"](function(a){a&&
- (a.severity=2);0<=this.a.indexOf(d)&&this.a.splice(this.a.indexOf(d),1);return Promise.reject(a)}.bind(this))};B.prototype.request=B.prototype.request;
- B.prototype.g=function(a,b,c,d){if(this.f)return Promise.reject();var e=new ia(b.uris[c]),f=e.aa;f||(f=location.protocol,f=f.slice(0,-1),ja(e,f),b.uris[c]=e.toString());f=Ea[f];if(!f)return Promise.reject(new t(2,1,1E3,e));var g=Date.now();return f(b.uris[c],b,a).then(function(b){void 0==b.timeMs&&(b.timeMs=Date.now()-g);var c=Date.now(),e=Promise.resolve();this.c.forEach(function(c){e=e.then(function(){return Promise.resolve(c(a,b))}.bind(this))});e=e["catch"](function(a){var b=2;a instanceof t&&
- (b=a.severity);throw new t(b,1,1007,a);});return e.then(function(){b.timeMs+=Date.now()-c;b.timeMs+=d;return b})}.bind(this))};function Ga(a,b){for(var c=[],d=0;d<a.length;++d){for(var e=!1,f=0;f<c.length&&!(e=b?b(a[d],c[f]):a[d]===c[f]);++f);e||c.push(a[d])}return c}function Ha(a,b,c){for(var d=0;d<a.length;++d)if(c(a[d],b))return d;return-1};function Ia(){this.a={}}Ia.prototype.push=function(a,b){this.a.hasOwnProperty(a)?this.a[a].push(b):this.a[a]=[b]};Ia.prototype.get=function(a){return(a=this.a[a])?a.slice():null};Ia.prototype.remove=function(a,b){var c=this.a[a];if(c)for(var d=0;d<c.length;++d)c[d]==b&&(c.splice(d,1),--d)};function D(){this.a=new Ia}D.prototype.m=function(){Ja(this);this.a=null;return Promise.resolve()};function E(a,b,c,d){a.a&&(b=new Ka(b,c,d),a.a.push(c,b))}function La(a,b,c,d){E(a,b,c,function(a){this.ha(b,c);d(a)}.bind(a))}D.prototype.ha=function(a,b){if(this.a)for(var c=this.a.get(b)||[],d=0;d<c.length;++d){var e=c[d];e.target==a&&(e.ha(),this.a.remove(b,e))}};function Ja(a){if(a.a){var b=a.a,c=[],d;for(d in b.a)c.push.apply(c,b.a[d]);for(b=0;b<c.length;++b)c[b].ha();a.a.a={}}}
- function Ka(a,b,c){this.target=a;this.type=b;this.a=c;this.target.addEventListener(b,c,!1)}Ka.prototype.ha=function(){this.target.removeEventListener(this.type,this.a,!1);this.a=this.target=null};function Ma(a){return!a||!Object.keys(a).length}function Na(a){return Object.keys(a).map(function(b){return a[b]})}function Oa(a,b){return Object.keys(a).reduce(function(c,d){c[d]=b(a[d],d);return c},{})}function Pa(a,b){return Object.keys(a).every(function(c){return b(c,a[c])})}function Qa(a,b){Object.keys(a).forEach(function(c){b(c,a[c])})};function F(a){if(!a)return"";a=new Uint8Array(a);239==a[0]&&187==a[1]&&191==a[2]&&(a=a.subarray(3));a=escape(Ra(a));try{return decodeURIComponent(a)}catch(b){throw new t(2,2,2004);}}n("shaka.util.StringUtils.fromUTF8",F);
- function Sa(a,b,c){if(!a)return"";if(!c&&a.byteLength%2)throw new t(2,2,2004);if(a instanceof ArrayBuffer)var d=a;else c=new Uint8Array(a.byteLength),c.set(new Uint8Array(a)),d=c.buffer;a=Math.floor(a.byteLength/2);c=new Uint16Array(a);d=new DataView(d);for(var e=0;e<a;e++)c[e]=d.getUint16(2*e,b);return Ra(c)}n("shaka.util.StringUtils.fromUTF16",Sa);
- function Ta(a){var b=new Uint8Array(a);if(239==b[0]&&187==b[1]&&191==b[2])return F(b);if(254==b[0]&&255==b[1])return Sa(b.subarray(2),!1);if(255==b[0]&&254==b[1])return Sa(b.subarray(2),!0);var c=function(a,b){return a.byteLength<=b||32<=a[b]&&126>=a[b]}.bind(null,b);if(b[0]||b[2]){if(!b[1]&&!b[3])return Sa(a,!0);if(c(0)&&c(1)&&c(2)&&c(3))return F(a)}else return Sa(a,!1);throw new t(2,2,2003);}n("shaka.util.StringUtils.fromBytesAutoDetect",Ta);
- function Ua(a){a=unescape(encodeURIComponent(a));for(var b=new Uint8Array(a.length),c=0;c<a.length;++c)b[c]=a.charCodeAt(c);return b.buffer}n("shaka.util.StringUtils.toUTF8",Ua);function Ra(a){for(var b="",c=0;c<a.length;c+=16E3)b+=String.fromCharCode.apply(null,a.subarray(c,c+16E3));return b};function Va(a){this.a=null;this.b=function(){this.a=null;a()}.bind(this)}Va.prototype.cancel=function(){null!=this.a&&(clearTimeout(this.a),this.a=null)};function Wa(a){a.cancel();a.a=setTimeout(a.b,500)};function Xa(a,b){var c=void 0==b?!0:b,d=window.btoa(String.fromCharCode.apply(null,a)).replace(/\+/g,"-").replace(/\//g,"_");return c?d:d.replace(/=*$/,"")}n("shaka.util.Uint8ArrayUtils.toBase64",Xa);function Ya(a){a=window.atob(a.replace(/-/g,"+").replace(/_/g,"/"));for(var b=new Uint8Array(a.length),c=0;c<a.length;++c)b[c]=a.charCodeAt(c);return b}n("shaka.util.Uint8ArrayUtils.fromBase64",Ya);
- function Za(a){for(var b=new Uint8Array(a.length/2),c=0;c<a.length;c+=2)b[c/2]=window.parseInt(a.substr(c,2),16);return b}n("shaka.util.Uint8ArrayUtils.fromHex",Za);function $a(a){for(var b="",c=0;c<a.length;++c){var d=a[c].toString(16);1==d.length&&(d="0"+d);b+=d}return b}n("shaka.util.Uint8ArrayUtils.toHex",$a);function ab(a,b){if(!a&&!b)return!0;if(!a||!b||a.length!=b.length)return!1;for(var c=0;c<a.length;++c)if(a[c]!=b[c])return!1;return!0}n("shaka.util.Uint8ArrayUtils.equal",ab);
- n("shaka.util.Uint8ArrayUtils.concat",function(a){for(var b=0,c=0;c<arguments.length;++c)b+=arguments[c].length;for(var b=new Uint8Array(b),d=0,c=0;c<arguments.length;++c)b.set(arguments[c],d),d+=arguments[c].length;return b});function bb(a,b,c,d){this.j=this.i=this.v=null;this.J=!1;this.b=null;this.f=new D;this.a=[];this.o=[];this.l=new A;this.ka=a;this.h=null;this.g=function(a){this.l.reject(a);b(a)}.bind(this);this.A={};this.Ca=c;this.la=d;this.B=new Va(this.Kd.bind(this));this.ja=this.c=!1;this.G=[];this.ia=!1;this.O=setInterval(this.Jd.bind(this),1E3);this.l["catch"](function(){})}k=bb.prototype;
- k.m=function(){this.c=!0;var a=this.a.map(function(a){return(a.ba.close()||Promise.resolve())["catch"](y)});this.l.reject();this.f&&a.push(this.f.m());this.j&&a.push(this.j.setMediaKeys(null)["catch"](y));this.O&&(clearInterval(this.O),this.O=null);this.B&&this.B.cancel();this.f=this.j=this.i=this.v=this.b=this.B=null;this.a=[];this.o=[];this.la=this.g=this.h=this.ka=null;return Promise.all(a)};k.configure=function(a){this.h=a};
- k.init=function(a,b){var c={},d=[];this.ja=b;this.o=a.offlineSessionIds;cb(this,a,b||0<a.offlineSessionIds.length,c,d);return d.length?db(this,c,d):(this.J=!0,Promise.resolve())};
- function eb(a,b){if(!a.i)return La(a.f,b,"encrypted",function(){this.g(new t(2,6,6010))}.bind(a)),Promise.resolve();a.j=b;La(a.f,a.j,"play",a.qd.bind(a));var c=a.j.setMediaKeys(a.i),c=c["catch"](function(a){return Promise.reject(new t(2,6,6003,a.message))}),d=null;a.b.serverCertificate&&(d=a.i.setServerCertificate(a.b.serverCertificate).then(function(){})["catch"](function(a){return Promise.reject(new t(2,6,6004,a.message))}));return Promise.all([c,d]).then(function(){if(this.c)return Promise.reject();
- fb(this);this.b.initData.length||this.o.length||E(this.f,this.j,"encrypted",this.fd.bind(this))}.bind(a))["catch"](function(a){return this.c?Promise.resolve():Promise.reject(a)}.bind(a))}function gb(a,b){return Promise.all(b.map(function(a){return hb(this,a).then(function(a){if(a){for(var b=new A,c=0;c<this.a.length;c++)if(this.a[c].ba==a){this.a[c].ib=b;break}return Promise.all([a.remove(),b])}}.bind(this))}.bind(a)))}
- function fb(a){var b=a.b?a.b.initData:[];b.forEach(function(a){ib(this,a.initDataType,a.initData)}.bind(a));a.o.forEach(function(a){hb(this,a)}.bind(a));b.length||a.o.length||a.l.resolve();return a.l}k.keySystem=function(){return this.b?this.b.keySystem:""};function jb(a){return a.a.map(function(a){return a.ba.sessionId})}k.ab=function(){var a=this.a.map(function(a){a=a.ba.expiration;return isNaN(a)?Infinity:a});return Math.min.apply(Math,a)};
- function cb(a,b,c,d,e){var f=kb(a);b.periods.forEach(function(a){a.variants.forEach(function(a){f&&(a.drmInfos=[f]);a.drmInfos.forEach(function(b){lb(this,b);window.cast&&window.cast.__platform__&&"com.microsoft.playready"==b.keySystem&&(b.keySystem="com.chromecast.playready");var f=d[b.keySystem];f||(f={audioCapabilities:[],videoCapabilities:[],distinctiveIdentifier:"optional",persistentState:c?"required":"optional",sessionTypes:[c?"persistent-license":"temporary"],label:b.keySystem,drmInfos:[]},
- d[b.keySystem]=f,e.push(b.keySystem));f.drmInfos.push(b);b.distinctiveIdentifierRequired&&(f.distinctiveIdentifier="required");b.persistentStateRequired&&(f.persistentState="required");var g=[];a.video&&g.push(a.video);a.audio&&g.push(a.audio);g.forEach(function(a){var c="video"==a.type?f.videoCapabilities:f.audioCapabilities,d=("video"==a.type?b.videoRobustness:b.audioRobustness)||"",e=a.mimeType;a.codecs&&(e+='; codecs="'+a.codecs+'"');c.push({robustness:d,contentType:e})}.bind(this))}.bind(this))}.bind(this))}.bind(a))}
- function db(a,b,c){if(1==c.length&&""==c[0])return Promise.reject(new t(2,6,6E3));var d=new A,e=d;[!0,!1].forEach(function(a){c.forEach(function(c){var d=b[c];d.drmInfos.some(function(a){return!!a.licenseServerUri})==a&&(d.audioCapabilities.length||delete d.audioCapabilities,d.videoCapabilities.length||delete d.videoCapabilities,e=e["catch"](function(){return this.c?Promise.reject():navigator.requestMediaKeySystemAccess(c,[d])}.bind(this)))}.bind(this))}.bind(a));e=e["catch"](function(){return Promise.reject(new t(2,
- 6,6001))});e=e.then(function(a){if(this.c)return Promise.reject();var c=0<=navigator.userAgent.indexOf("Edge/"),d=a.getConfiguration();this.v=(d.audioCapabilities||[]).concat(d.videoCapabilities||[]).map(function(a){return a.contentType});c&&(this.v=null);c=b[a.keySystem];mb(this,a.keySystem,c,c.drmInfos);return this.b.licenseServerUri?a.createMediaKeys():Promise.reject(new t(2,6,6012))}.bind(a)).then(function(a){if(this.c)return Promise.reject();this.i=a;this.J=!0}.bind(a))["catch"](function(a){if(this.c)return Promise.resolve();
- this.v=this.b=null;return a instanceof t?Promise.reject(a):Promise.reject(new t(2,6,6002,a.message))}.bind(a));d.reject();return e}
- function lb(a,b){var c=b.keySystem;if(c){if(!b.licenseServerUri){var d=a.h.servers[c];d&&(b.licenseServerUri=d)}b.keyIds||(b.keyIds=[]);if(c=a.h.advanced[c])b.distinctiveIdentifierRequired||(b.distinctiveIdentifierRequired=c.distinctiveIdentifierRequired),b.persistentStateRequired||(b.persistentStateRequired=c.persistentStateRequired),b.videoRobustness||(b.videoRobustness=c.videoRobustness),b.audioRobustness||(b.audioRobustness=c.audioRobustness),b.serverCertificate||(b.serverCertificate=c.serverCertificate)}}
- function kb(a){if(Ma(a.h.clearKeys))return null;var b=[],c=[],d;for(d in a.h.clearKeys){var e=a.h.clearKeys[d],f=Za(d),e=Za(e),f={kty:"oct",kid:Xa(f,!1),k:Xa(e,!1)};b.push(f);c.push(f.kid)}a=JSON.stringify({keys:b});c=JSON.stringify({kids:c});c=[{initData:new Uint8Array(Ua(c)),initDataType:"keyids"}];return{keySystem:"org.w3.clearkey",licenseServerUri:"data:application/json;base64,"+window.btoa(a),distinctiveIdentifierRequired:!1,persistentStateRequired:!1,audioRobustness:"",videoRobustness:"",serverCertificate:null,
- initData:c,keyIds:[]}}function mb(a,b,c,d){var e=[],f=[],g=[],h=[];nb(d,e,f,g,h);a.b={keySystem:b,licenseServerUri:e[0],distinctiveIdentifierRequired:"required"==c.distinctiveIdentifier,persistentStateRequired:"required"==c.persistentState,audioRobustness:c.audioCapabilities?c.audioCapabilities[0].robustness:"",videoRobustness:c.videoCapabilities?c.videoCapabilities[0].robustness:"",serverCertificate:f[0],initData:g,keyIds:h}}
- function nb(a,b,c,d,e){function f(a,b){return a.keyId&&a.keyId==b.keyId?!0:a.initDataType==b.initDataType&&ab(a.initData,b.initData)}a.forEach(function(a){-1==b.indexOf(a.licenseServerUri)&&b.push(a.licenseServerUri);a.serverCertificate&&-1==Ha(c,a.serverCertificate,ab)&&c.push(a.serverCertificate);a.initData&&a.initData.forEach(function(a){-1==Ha(d,a,f)&&d.push(a)});if(a.keyIds)for(var g=0;g<a.keyIds.length;++g)-1==e.indexOf(a.keyIds[g])&&e.push(a.keyIds[g])})}
- k.fd=function(a){for(var b=new Uint8Array(a.initData),c=0;c<this.a.length;++c)if(ab(b,this.a[c].initData))return;ib(this,a.initDataType,b)};
- function hb(a,b){try{var c=a.i.createSession("persistent-license")}catch(f){var d=new t(2,6,6005,f.message);a.g(d);return Promise.reject(d)}E(a.f,c,"message",a.kc.bind(a));E(a.f,c,"keystatuseschange",a.ec.bind(a));var e={initData:null,ba:c,loaded:!1,zb:Infinity,ib:null};a.a.push(e);return c.load(b).then(function(a){if(!this.c){if(a)return e.loaded=!0,this.a.every(function(a){return a.loaded})&&this.l.resolve(),c;this.a.splice(this.a.indexOf(e),1);this.g(new t(2,6,6013))}}.bind(a),function(a){this.c||
- (this.a.splice(this.a.indexOf(e),1),this.g(new t(2,6,6005,a.message)))}.bind(a))}
- function ib(a,b,c){try{var d=a.ja?a.i.createSession("persistent-license"):a.i.createSession()}catch(e){a.g(new t(2,6,6005,e.message));return}E(a.f,d,"message",a.kc.bind(a));E(a.f,d,"keystatuseschange",a.ec.bind(a));a.a.push({initData:c,ba:d,loaded:!1,zb:Infinity,ib:null});d.generateRequest(b,c.buffer)["catch"](function(a){if(!this.c){for(var b=0;b<this.a.length;++b)if(this.a[b].ba==d){this.a.splice(b,1);break}this.g(new t(2,6,6006,a.message))}}.bind(a))}
- k.kc=function(a){this.h.delayLicenseRequestUntilPlayed&&this.j.paused&&!this.ia?this.G.push(a):ob(this,a)};
- function ob(a,b){for(var c=b.target,d,e=0;e<a.a.length;e++)if(a.a[e].ba==c){d=a.a[e].ib;break}e=C([a.b.licenseServerUri],a.h.retryParameters);e.body=b.message;e.method="POST";"com.microsoft.playready"!=a.b.keySystem&&"com.chromecast.playready"!=a.b.keySystem||pb(e);a.ka.request(2,e).then(function(a){return this.c?Promise.reject():c.update(a.data).then(function(){d&&d.resolve()})}.bind(a),function(a){if(this.c)return Promise.resolve();a=new t(2,6,6007,a);this.g(a);d&&d.reject(a)}.bind(a))["catch"](function(a){if(this.c)return Promise.resolve();
- a=new t(2,6,6008,a.message);this.g(a);d&&d.reject(a)}.bind(a))}function pb(a){var b=Sa(a.body,!0,!0);if(-1==b.indexOf("PlayReadyKeyMessage"))a.headers["Content-Type"]="text/xml; charset=utf-8";else{for(var b=(new DOMParser).parseFromString(b,"application/xml"),c=b.getElementsByTagName("HttpHeader"),d=0;d<c.length;++d)a.headers[c[d].querySelector("name").textContent]=c[d].querySelector("value").textContent;a.body=Ya(b.querySelector("Challenge").textContent).buffer}}
- k.ec=function(a){a=a.target;var b;for(b=0;b<this.a.length&&this.a[b].ba!=a;++b);if(b!=this.a.length){var c=!1;a.keyStatuses.forEach(function(a,d){if("string"==typeof d){var e=d;d=a;a=e}if("com.microsoft.playready"==this.b.keySystem&&16==d.byteLength){var e=new DataView(d),f=e.getUint32(0,!0),l=e.getUint16(4,!0),m=e.getUint16(6,!0);e.setUint32(0,f,!1);e.setUint16(4,l,!1);e.setUint16(6,m,!1)}"com.microsoft.playready"==this.b.keySystem&&"status-pending"==a&&(a="usable");"status-pending"!=a&&(this.a[b].loaded=
- !0,this.a.every(function(a){return a.loaded})&&this.l.resolve());"expired"==a&&(c=!0);e=$a(new Uint8Array(d));this.A[e]=a}.bind(this));var d=a.expiration-Date.now();(0>d||c&&1E3>d)&&!this.a[b].ib&&(this.a.splice(b,1),a.close());Wa(this.B)}};k.Kd=function(){function a(a,c){return"expired"==c}!Ma(this.A)&&Pa(this.A,a)&&this.g(new t(2,6,6014));this.Ca(this.A)};
- function qb(){var a=[],b=[{contentType:'video/mp4; codecs="avc1.42E01E"'},{contentType:'video/webm; codecs="vp8"'}],c=[{videoCapabilities:b,persistentState:"required",sessionTypes:["persistent-license"]},{videoCapabilities:b}],d={};"org.w3.clearkey com.widevine.alpha com.microsoft.playready com.apple.fps.2_0 com.apple.fps.1_0 com.apple.fps com.adobe.primetime".split(" ").forEach(function(b){var e=navigator.requestMediaKeySystemAccess(b,c).then(function(a){var c=a.getConfiguration().sessionTypes;d[b]=
- {persistentState:c?0<=c.indexOf("persistent-license"):!1};return a.createMediaKeys()})["catch"](function(){d[b]=null});a.push(e)});return Promise.all(a).then(function(){return d})}k.qd=function(){for(var a=0;a<this.G.length;a++)ob(this,this.G[a]);this.ia=!0;this.G=[]};function rb(a,b){var c=a.keySystem();return!b.drmInfos.length||b.drmInfos.some(function(a){return a.keySystem==c})}
- function sb(a,b){if(!a.length)return b;if(!b.length)return a;for(var c=[],d=0;d<a.length;d++)for(var e=0;e<b.length;e++)if(a[d].keySystem==b[e].keySystem){var f=a[d],e=b[e],g=[],g=g.concat(f.initData||[]),g=g.concat(e.initData||[]),h=[],h=h.concat(f.keyIds),h=h.concat(e.keyIds);c.push({keySystem:f.keySystem,licenseServerUri:f.licenseServerUri||e.licenseServerUri,distinctiveIdentifierRequired:f.distinctiveIdentifierRequired||e.distinctiveIdentifierRequired,persistentStateRequired:f.persistentStateRequired||
- e.persistentStateRequired,videoRobustness:f.videoRobustness||e.videoRobustness,audioRobustness:f.audioRobustness||e.audioRobustness,serverCertificate:f.serverCertificate||e.serverCertificate,initData:g,keyIds:h});break}return c}k.Jd=function(){this.a.forEach(function(a){var b=a.zb,c=a.ba.expiration;isNaN(c)&&(c=Infinity);c!=b&&(this.la(a.ba.sessionId,c),a.zb=c)}.bind(this))};function tb(a){this.f=null;this.c=a;this.h=0;this.g=Infinity;this.a=this.b=null}var ub={};function vb(a,b){ub[a]=b.length?wb.bind(null,b):b}n("shaka.media.TextEngine.registerParser",vb);n("shaka.media.TextEngine.unregisterParser",function(a){delete ub[a]});function xb(a,b,c){return a>=b?null:new VTTCue(a,b,c)}n("shaka.media.TextEngine.makeCue",xb);tb.prototype.m=function(){this.c&&yb(this,function(){return!0});this.c=this.f=null;return Promise.resolve()};
- function zb(a,b,c,d){return Promise.resolve().then(function(){if(this.c)if(null==c||null==d)this.f.parseInit(b);else{for(var a=this.f.parseMedia(b,{periodStart:this.h,segmentStart:c,segmentEnd:d}),f=0;f<a.length&&!(a[f].startTime>=this.g);++f)this.c.addCue(a[f]);null==this.b&&(this.b=c);this.a=Math.min(d,this.g)}}.bind(a))}
- tb.prototype.remove=function(a,b){return Promise.resolve().then(function(){this.c&&(yb(this,function(c){return c.startTime>=b||c.endTime<=a?!1:!0}),null==this.b||b<=this.b||a>=this.a||(a<=this.b&&b>=this.a?this.b=this.a=null:a<=this.b&&b<this.a?this.b=b:a>this.b&&b>=this.a&&(this.a=a)))}.bind(this))};function yb(a,b){for(var c=a.c.cues,d=[],e=0;e<c.length;++e)b(c[e])&&d.push(c[e]);for(e=0;e<d.length;++e)a.c.removeCue(d[e])}function wb(a){this.Na=a}
- wb.prototype.parseInit=function(a){this.Na(a,0,null,null)};wb.prototype.parseMedia=function(a,b){return this.Na(a,b.periodStart,b.segmentStart,b.segmentEnd)};function Ab(a){return!a||1==a.length&&1E-6>a.end(0)-a.start(0)?null:a.length?a.end(a.length-1):null}function Bb(a,b){return!a||!a.length||1==a.length&&1E-6>a.end(0)-a.start(0)?!1:b>=a.start(0)&&b<=a.end(a.length-1)}function Cb(a,b){if(!a||!a.length||1==a.length&&1E-6>a.end(0)-a.start(0))return 0;for(var c=0,d=a.length-1;0<=d&&a.end(d)>b;--d)c+=a.end(d)-Math.max(a.start(d),b);return c};function Db(a,b,c){this.f=a;this.N=b;this.i=c;this.c={};this.a=null;this.b={};this.g=new D;this.h=!1}
- function Eb(){var a={};'video/mp4; codecs="avc1.42E01E",video/mp4; codecs="avc3.42E01E",video/mp4; codecs="hvc1.1.6.L93.90",audio/mp4; codecs="mp4a.40.2",audio/mp4; codecs="ac-3",audio/mp4; codecs="ec-3",video/webm; codecs="vp8",video/webm; codecs="vp9",video/webm; codecs="av1",audio/webm; codecs="vorbis",audio/webm; codecs="opus",video/mp2t; codecs="avc1.42E01E",video/mp2t; codecs="avc3.42E01E",video/mp2t; codecs="hvc1.1.6.L93.90",video/mp2t; codecs="mp4a.40.2",video/mp2t; codecs="ac-3",video/mp2t; codecs="ec-3",video/mp2t; codecs="mp4a.40.2",text/vtt,application/mp4; codecs="wvtt",application/ttml+xml,application/mp4; codecs="stpp"'.split(",").forEach(function(b){a[b]=!!ub[b]||
- MediaSource.isTypeSupported(b);var c=b.split(";")[0];a[c]=a[c]||a[b]});return a}k=Db.prototype;k.m=function(){this.h=!0;var a=[],b;for(b in this.b){var c=this.b[b],d=c[0];this.b[b]=c.slice(0,1);d&&a.push(d.p["catch"](y));for(d=1;d<c.length;++d)c[d].p["catch"](y),c[d].p.reject()}this.a&&a.push(this.a.m());return Promise.all(a).then(function(){this.g.m();this.a=this.i=this.N=this.f=this.g=null;this.c={};this.b={}}.bind(this))};
- k.init=function(a){for(var b in a){var c=a[b];"text"==b?Fb(this,c):(c=this.N.addSourceBuffer(c),E(this.g,c,"error",this.je.bind(this,b)),E(this.g,c,"updateend",this.Ia.bind(this,b)),this.c[b]=c,this.b[b]=[])}};function Fb(a,b){a.a||(a.a=new tb(a.i));a.a.f=new ub[b]}function Gb(a,b){if("text"==b)var c=a.a.b;else c=Ib(a,b),c=!c||1==c.length&&1E-6>c.end(0)-c.start(0)?null:1==c.length&&0>c.start(0)?0:c.length?c.start(0):null;return c}function Ib(a,b){try{return a.c[b].buffered}catch(c){return null}}
- function Jb(a,b,c,d,e){return"text"==b?zb(a.a,c,d,e):Kb(a,b,a.ie.bind(a,b,c))}k.remove=function(a,b,c){return"text"==a?this.a.remove(b,c):Kb(this,a,this.qc.bind(this,a,b,c))};function Lb(a,b){return"text"==b?a.a.remove(0,Infinity):Kb(a,b,a.qc.bind(a,b,0,a.N.duration))}function Mb(a,b,c,d){if("text"==b)return a.a.h=c,null!=d&&(a.a.g=d),Promise.resolve();null==d&&(d=Infinity);return Promise.all([Kb(a,b,a.Ec.bind(a,b)),Kb(a,b,a.Zd.bind(a,b,c)),Kb(a,b,a.Xd.bind(a,b,d))])}
- k.endOfStream=function(a){return Nb(this,function(){a?this.N.endOfStream(a):this.N.endOfStream()}.bind(this))};k.pa=function(a){return Nb(this,function(){this.N.duration=a}.bind(this))};k.Y=function(){return this.N.duration};k.ie=function(a,b){this.c[a].appendBuffer(b)};k.qc=function(a,b,c){c<=b?this.Ia(a):this.c[a].remove(b,c)};k.Ec=function(a){var b=this.c[a].appendWindowEnd;this.c[a].abort();this.c[a].appendWindowEnd=b;this.Ia(a)};k.Oc=function(a){this.f.currentTime-=.001;this.Ia(a)};
- k.Zd=function(a,b){this.c[a].timestampOffset=b;this.Ia(a)};k.Xd=function(a,b){this.c[a].appendWindowEnd=b+.04;this.Ia(a)};k.je=function(a){this.b[a][0].p.reject(new t(2,3,3014,this.f.error?this.f.error.code:0))};k.Ia=function(a){var b=this.b[a][0];b&&(b.p.resolve(),Ob(this,a))};
- function Kb(a,b,c){if(a.h)return Promise.reject();c={start:c,p:new A};a.b[b].push(c);if(1==a.b[b].length)try{c.start()}catch(d){"QuotaExceededError"==d.name?c.p.reject(new t(2,3,3017,b)):c.p.reject(new t(2,3,3015,d)),Ob(a,b)}return c.p}
- function Nb(a,b){if(a.h)return Promise.reject();var c=[],d;for(d in a.c){var e=new A,f={start:function(a){a.resolve()}.bind(null,e),p:e};a.b[d].push(f);c.push(e);1==a.b[d].length&&f.start()}return Promise.all(c).then(function(){var a;try{b()}catch(l){var c=Promise.reject(new t(2,3,3015,l))}for(a in this.c)Ob(this,a);return c}.bind(a),function(){return Promise.reject()}.bind(a))}function Ob(a,b){a.b[b].shift();var c=a.b[b][0];if(c)try{c.start()}catch(d){c.p.reject(new t(2,3,3015,d)),Ob(a,b)}};function Pb(a,b,c){return c==b||a>=Qb&&c==b.split("-")[0]||a>=Rb&&c.split("-")[0]==b.split("-")[0]?!0:!1}var Qb=1,Rb=2;function Sb(a){a=a.toLowerCase().split("-");var b=Tb[a[0]];b&&(a[0]=b);return a.join("-")}
- var Tb={aar:"aa",abk:"ab",afr:"af",aka:"ak",alb:"sq",amh:"am",ara:"ar",arg:"an",arm:"hy",asm:"as",ava:"av",ave:"ae",aym:"ay",aze:"az",bak:"ba",bam:"bm",baq:"eu",bel:"be",ben:"bn",bih:"bh",bis:"bi",bod:"bo",bos:"bs",bre:"br",bul:"bg",bur:"my",cat:"ca",ces:"cs",cha:"ch",che:"ce",chi:"zh",chu:"cu",chv:"cv",cor:"kw",cos:"co",cre:"cr",cym:"cy",cze:"cs",dan:"da",deu:"de",div:"dv",dut:"nl",dzo:"dz",ell:"el",eng:"en",epo:"eo",est:"et",eus:"eu",ewe:"ee",fao:"fo",fas:"fa",fij:"fj",fin:"fi",fra:"fr",fre:"fr",
- fry:"fy",ful:"ff",geo:"ka",ger:"de",gla:"gd",gle:"ga",glg:"gl",glv:"gv",gre:"el",grn:"gn",guj:"gu",hat:"ht",hau:"ha",heb:"he",her:"hz",hin:"hi",hmo:"ho",hrv:"hr",hun:"hu",hye:"hy",ibo:"ig",ice:"is",ido:"io",iii:"ii",iku:"iu",ile:"ie",ina:"ia",ind:"id",ipk:"ik",isl:"is",ita:"it",jav:"jv",jpn:"ja",kal:"kl",kan:"kn",kas:"ks",kat:"ka",kau:"kr",kaz:"kk",khm:"km",kik:"ki",kin:"rw",kir:"ky",kom:"kv",kon:"kg",kor:"ko",kua:"kj",kur:"ku",lao:"lo",lat:"la",lav:"lv",lim:"li",lin:"ln",lit:"lt",ltz:"lb",lub:"lu",
- lug:"lg",mac:"mk",mah:"mh",mal:"ml",mao:"mi",mar:"mr",may:"ms",mkd:"mk",mlg:"mg",mlt:"mt",mon:"mn",mri:"mi",msa:"ms",mya:"my",nau:"na",nav:"nv",nbl:"nr",nde:"nd",ndo:"ng",nep:"ne",nld:"nl",nno:"nn",nob:"nb",nor:"no",nya:"ny",oci:"oc",oji:"oj",ori:"or",orm:"om",oss:"os",pan:"pa",per:"fa",pli:"pi",pol:"pl",por:"pt",pus:"ps",que:"qu",roh:"rm",ron:"ro",rum:"ro",run:"rn",rus:"ru",sag:"sg",san:"sa",sin:"si",slk:"sk",slo:"sk",slv:"sl",sme:"se",smo:"sm",sna:"sn",snd:"sd",som:"so",sot:"st",spa:"es",sqi:"sq",
- srd:"sc",srp:"sr",ssw:"ss",sun:"su",swa:"sw",swe:"sv",tah:"ty",tam:"ta",tat:"tt",tel:"te",tgk:"tg",tgl:"tl",tha:"th",tib:"bo",tir:"ti",ton:"to",tsn:"tn",tso:"ts",tuk:"tk",tur:"tr",twi:"tw",uig:"ug",ukr:"uk",urd:"ur",uzb:"uz",ven:"ve",vie:"vi",vol:"vo",wel:"cy",wln:"wa",wol:"wo",xho:"xh",yid:"yi",yor:"yo",zha:"za",zho:"zh",zul:"zu"};function Ub(a,b,c){var d=a.video;return d&&(d.width<b.minWidth||d.width>b.maxWidth||d.width>c.width||d.height<b.minHeight||d.height>b.maxHeight||d.height>c.height||d.width*d.height<b.minPixels||d.width*d.height>b.maxPixels)||a.bandwidth<b.minBandwidth||a.bandwidth>b.maxBandwidth?!1:!0}function Vb(a,b,c){var d=!1;a.variants.forEach(function(a){var e=a.allowedByApplication;a.allowedByApplication=Ub(a,b,c);e!=a.allowedByApplication&&(d=!0)});return d}
- function Wb(a,b,c){var d=b.video,e=b.audio;for(b=0;b<c.variants.length;++b){var f=c.variants[b],g=a,h=e,l=d;(g&&g.J&&!rb(g,f)?0:Xb(f.audio,g,h)&&Xb(f.video,g,l))||(c.variants.splice(b,1),--b)}for(b=0;b<c.textStreams.length;++b)a=c.textStreams[b],ub[Yb(a.mimeType,a.codecs)]||(c.textStreams.splice(b,1),--b)}
- function Xb(a,b,c){if(!a)return!0;var d=null;b&&b.J&&(d=b.v);b=Yb(a.mimeType,a.codecs);return!ub[b]&&!MediaSource.isTypeSupported(b)||d&&a.encrypted&&0>d.indexOf(b)||c&&(a.mimeType!=c.mimeType||a.codecs.split(".")[0]!=c.codecs.split(".")[0])?!1:!0}
- function Zb(a,b,c){var d=null;return $b(a.variants).map(function(a){var e;a.video&&a.audio?e=c==a.video.id&&b==a.audio.id:e=a.video&&c==a.video.id||a.audio&&b==a.audio.id;var g="";a.video&&(g+=a.video.codecs);a.audio&&(""!=g&&(g+=", "),g+=a.audio.codecs,d=a.audio.label);var h=a.audio?a.audio.codecs:null,l=a.video?a.video.codecs:null,m=null;a.video?m=a.video.mimeType:a.audio&&(m=a.audio.mimeType);var q=null;a.audio?q=a.audio.kind:a.video&&(q=a.video.kind);var r=Ga((a.audio?a.audio.roles:[]).concat(a.video?
- a.video.roles:[]));return{id:a.id,active:e,type:"variant",bandwidth:a.bandwidth,language:a.language,label:d,kind:q||null,width:a.video?a.video.width:null,height:a.video?a.video.height:null,frameRate:a.video?a.video.frameRate:void 0,mimeType:m,codecs:g,audioCodec:h,videoCodec:l,primary:a.primary,roles:r,videoId:a.video?a.video.id:null,audioId:a.audio?a.audio.id:null}})}
- function ac(a,b){return a.textStreams.map(function(a){return{id:a.id,active:b==a.id,type:"text",language:a.language,label:a.label,kind:a.kind,mimeType:a.mimeType,codecs:a.codecs||null,audioCodec:null,videoCodec:null,primary:a.primary,roles:a.roles}})}function bc(a,b){for(var c=0;c<a.variants.length;c++)if(a.variants[c].id==b.id)return a.variants[c];return null}function cc(a,b){for(var c=0;c<a.textStreams.length;c++)if(a.textStreams[c].id==b.id)return a.textStreams[c];return null}
- function $b(a){return a.filter(function(a){return a.allowedByApplication&&a.allowedByKeySystem})}
- function dc(a,b,c,d){var e=$b(a.variants),f=e.filter(function(a){return a.language==e[0].language});a=e.filter(function(a){return a.primary});a.length&&(f=a);if(b){var g=Sb(b);[Rb,Qb,0].forEach(function(a){var b=!1;e.forEach(function(d){g=Sb(g);var e=Sb(d.language);Pb(a,g,e)&&(b?f.push(d):(f=[d],b=!0),c&&(c.audio=!0))})})}var h=d||"";return h&&(b=f.filter(function(a){return a.audio&&-1<a.audio.roles.indexOf(h)||a.video&&-1<a.video.roles.indexOf(h)}),b.length)?b:f}
- function ec(a,b,c,d){var e=a.textStreams,f=e;a=e.filter(function(a){return a.primary});a.length&&(f=a);if(b){var g=Sb(b);[Rb,Qb,0].forEach(function(a){var b=!1;e.forEach(function(d){var e=Sb(d.language);Pb(a,g,e)&&(b?f.push(d):(f=[d],b=!0),c&&(c.text=!0))})})}var h=d||"";return h&&(b=f.filter(function(a){return a&&-1<a.roles.indexOf(h)}),b.length)?b:f}function fc(a,b,c){for(var d=0;d<c.length;d++)if(c[d].audio==a&&c[d].video==b)return c[d];return null}
- function gc(a,b,c){function d(a,b){return null==a?null==b:b.id==a}for(var e=0;e<c.length;e++)if(d(a,c[e].audio)&&d(b,c[e].video))return c[e];return null}function Yb(a,b){var c=a;b&&(c+='; codecs="'+b+'"');return c}function hc(a,b){for(var c=a.periods.length-1;0<c;--c)if(b>=a.periods[c].startTime)return c;return 0}
- function ic(a,b){for(var c=0;c<a.periods.length;++c){var d=a.periods[c];if("text"==b.type)for(var e=0;e<d.textStreams.length;++e){if(d.textStreams[e]==b)return c}else for(e=0;e<d.variants.length;++e){var f=d.variants[e];if(f.audio==b||f.video==b||f.video&&f.video.trickModeVideo==b)return c}}return-1};function H(){this.f=null;this.b=!1;this.a=new fa;this.h=[];this.g=[];this.j=!1;this.c=null;this.i={minWidth:0,maxWidth:Infinity,minHeight:0,maxHeight:Infinity,minPixels:0,maxPixels:Infinity,minBandwidth:0,maxBandwidth:Infinity}}n("shaka.abr.SimpleAbrManager",H);H.prototype.stop=function(){this.f=null;this.b=!1;this.h=[];this.g=[];this.c=null};H.prototype.stop=H.prototype.stop;H.prototype.init=function(a){this.f=a};H.prototype.init=H.prototype.init;
- H.prototype.chooseStreams=function(a){var b={};if(-1<a.indexOf("audio")||-1<a.indexOf("video")){var c=this.h;var d=jc(this.i,c);var e=this.a.getBandwidthEstimate();if(c.length&&!d.length)throw new t(2,4,4012);for(var c=d[0],f=0;f<d.length;++f){var g=d[f],h=(d[f+1]||{bandwidth:Infinity}).bandwidth/.85;e>=g.bandwidth/.95&&e<=h&&(c=g)}(d=c)&&d.video&&(b.video=d.video);d&&d.audio&&(b.audio=d.audio)}-1<a.indexOf("text")&&(b.text=this.g[0]);this.c=Date.now();return b};H.prototype.chooseStreams=H.prototype.chooseStreams;
- H.prototype.enable=function(){this.b=!0};H.prototype.enable=H.prototype.enable;H.prototype.disable=function(){this.b=!1};H.prototype.disable=H.prototype.disable;H.prototype.segmentDownloaded=function(a,b){var c=this.a;if(!(16E3>b)){var d=8E3*b/a,e=a/1E3;c.a+=b;da(c.c,e,d);da(c.f,e,d)}if(null!=this.c&&this.b)a:{if(!this.j){if(!(128E3<=this.a.a))break a;this.j=!0}else if(8E3>Date.now()-this.c)break a;c=this.chooseStreams(["audio","video"]);this.a.getBandwidthEstimate();this.f(c)}};
- H.prototype.segmentDownloaded=H.prototype.segmentDownloaded;H.prototype.getBandwidthEstimate=function(){return this.a.getBandwidthEstimate()};H.prototype.getBandwidthEstimate=H.prototype.getBandwidthEstimate;H.prototype.setDefaultEstimate=function(a){this.a.setDefaultEstimate(a)};H.prototype.setDefaultEstimate=H.prototype.setDefaultEstimate;H.prototype.setRestrictions=function(a){this.i=a};H.prototype.setRestrictions=H.prototype.setRestrictions;H.prototype.setVariants=function(a){this.h=a};
- H.prototype.setVariants=H.prototype.setVariants;H.prototype.setTextStreams=function(a){this.g=a};H.prototype.setTextStreams=H.prototype.setTextStreams;function jc(a,b){return b.filter(function(b){return Ub(b,a,{width:Infinity,height:Infinity})}).sort(function(a,b){return a.bandwidth-b.bandwidth})};function I(a,b){var c=b||{},d;for(d in c)this[d]=c[d];this.defaultPrevented=this.cancelable=this.bubbles=!1;this.timeStamp=window.performance&&window.performance.now?window.performance.now():Date.now();this.type=a;this.isTrusted=!1;this.target=this.currentTarget=null;this.a=!1}I.prototype.preventDefault=function(){this.cancelable&&(this.defaultPrevented=!0)};I.prototype.stopImmediatePropagation=function(){this.a=!0};I.prototype.stopPropagation=function(){};var kc="ended play playing pause pausing ratechange seeked seeking timeupdate volumechange".split(" "),lc="buffered currentTime duration ended loop muted paused playbackRate seeking videoHeight videoWidth volume".split(" "),mc=["loop","playbackRate"],nc=["pause","play"],oc="adaptation buffering emsg error loading unloading texttrackvisibility timelineregionadded timelineregionenter timelineregionexit trackschanged".split(" "),pc="drmInfo getAudioLanguages getConfiguration getExpiration getManifestUri getPlaybackRate getPlayheadTimeAsDate getTextLanguages getTextTracks getTracks getStats getVariantTracks isBuffering isInProgress isLive isTextTrackVisible keySystem seekRange".split(" "),
- qc=[["getConfiguration","configure"]],rc=[["isTextTrackVisible","setTextTrackVisibility"]],sc="addTextTrack cancelTrickPlay configure resetConfiguration selectAudioLanguage selectTextLanguage selectTextTrack selectTrack selectVariantTrack setTextTrackVisibility trickPlay".split(" "),uc=["load","unload"];
- function vc(a){return JSON.stringify(a,function(a,c){if("manager"!=a&&"function"!=typeof c){if(c instanceof Event||c instanceof I){var b={},e;for(e in c){var f=c[e];f&&"object"==typeof f||e in Event||(b[e]=f)}return b}if(c instanceof TimeRanges)for(b={__type__:"TimeRanges",length:c.length,start:[],end:[]},e=0;e<c.length;++e)b.start.push(c.start(e)),b.end.push(c.end(e));else b="number"==typeof c?isNaN(c)?"NaN":isFinite(c)?c:0>c?"-Infinity":"Infinity":c;return b}})}
- function wc(a){return JSON.parse(a,function(a,c){return"NaN"==c?NaN:"-Infinity"==c?-Infinity:"Infinity"==c?Infinity:c&&"object"==typeof c&&"TimeRanges"==c.__type__?xc(c):c})}function xc(a){return{length:a.length,start:function(b){return a.start[b]},end:function(b){return a.end[b]}}};function yc(a,b,c,d,e){this.J=a;this.l=b;this.B=c;this.G=d;this.v=e;this.c=this.j=this.h=!1;this.A="";this.a=this.i=null;this.b={video:{},player:{}};this.o=0;this.f={};this.g=null}k=yc.prototype;k.m=function(){zc(this);this.a&&(this.a.leave(function(){},function(){}),this.a=null);this.G=this.B=this.l=null;this.c=this.j=this.h=!1;this.g=this.f=this.b=this.i=null;return Promise.resolve()};k.V=function(){return this.c};k.Fb=function(){return this.A};
- k.init=function(){if(window.chrome&&chrome.cast&&chrome.cast.isAvailable){delete window.__onGCastApiAvailable;this.h=!0;this.l();var a=new chrome.cast.SessionRequest(this.J),a=new chrome.cast.ApiConfig(a,this.gd.bind(this),this.sd.bind(this),"origin_scoped");chrome.cast.initialize(a,function(){},function(){})}else window.__onGCastApiAvailable=function(a){a&&this.init()}.bind(this)};k.Ib=function(a){this.i=a;this.c&&Ac(this,{type:"appData",appData:this.i})};
- k.cast=function(a){if(!this.h)return Promise.reject(new t(1,8,8E3));if(!this.j)return Promise.reject(new t(1,8,8001));if(this.c)return Promise.reject(new t(1,8,8002));this.g=new A;chrome.cast.requestSession(this.Bb.bind(this,a),this.cc.bind(this));return this.g};k.$a=function(){this.c&&(zc(this),this.a&&(this.a.stop(function(){},function(){}),this.a=null))};
- k.get=function(a,b){if("video"==a){if(0<=nc.indexOf(b))return this.pc.bind(this,a,b)}else if("player"==a){if(0<=sc.indexOf(b))return this.pc.bind(this,a,b);if(0<=uc.indexOf(b))return this.Od.bind(this,a,b);if(0<=pc.indexOf(b))return this.lc.bind(this,a,b)}return this.lc(a,b)};k.set=function(a,b,c){this.b[a][b]=c;Ac(this,{type:"set",targetName:a,property:b,value:c})};
- k.Bb=function(a,b){this.a=b;this.a.addUpdateListener(this.dc.bind(this));this.a.addMessageListener("urn:x-cast:com.google.shaka.v2",this.md.bind(this));this.dc();Ac(this,{type:"init",initState:a,appData:this.i});this.g.resolve()};k.cc=function(a){var b=8003;switch(a.code){case "cancel":b=8004;break;case "timeout":b=8005;break;case "receiver_unavailable":b=8006}this.g.reject(new t(2,8,b,a))};k.lc=function(a,b){return this.b[a][b]};
- k.pc=function(a,b){Ac(this,{type:"call",targetName:a,methodName:b,args:Array.prototype.slice.call(arguments,2)})};k.Od=function(a,b){var c=Array.prototype.slice.call(arguments,2),d=new A,e=this.o.toString();this.o++;this.f[e]=d;Ac(this,{type:"asyncCall",targetName:a,methodName:b,args:c,id:e});return d};k.gd=function(a){var b=this.v();this.g=new A;this.Bb(b,a)};k.sd=function(a){this.j="available"==a;this.l()};
- k.dc=function(){var a=this.a?"connected"==this.a.status:!1;if(this.c&&!a){this.G();for(var b in this.b)this.b[b]={};zc(this)}this.A=(this.c=a)?this.a.receiver.friendlyName:"";this.l()};function zc(a){for(var b in a.f){var c=a.f[b];delete a.f[b];c.reject(new t(1,7,7E3))}}
- k.md=function(a,b){var c=wc(b);switch(c.type){case "event":var d=c.targetName,e=c.event;this.B(d,new I(e.type,e));break;case "update":e=c.update;for(d in e){var c=this.b[d]||{};for(f in e[d])c[f]=e[d][f]}break;case "asyncComplete":d=c.id;var f=c.error;c=this.f[d];delete this.f[d];if(c)if(f){d=new t(f.severity,f.category,f.code);for(e in f)d[e]=f[e];c.reject(d)}else c.resolve()}};function Ac(a,b){var c=vc(b);a.a.sendMessage("urn:x-cast:com.google.shaka.v2",c,function(){},ga)};function p(){this.nb=new Ia;this.Ta=this}p.prototype.addEventListener=function(a,b){this.nb.push(a,b)};p.prototype.removeEventListener=function(a,b){this.nb.remove(a,b)};p.prototype.dispatchEvent=function(a){for(var b=this.nb.get(a.type)||[],c=0;c<b.length;++c){a.target=this.Ta;a.currentTarget=this.Ta;var d=b[c];try{d.handleEvent?d.handleEvent(a):d.call(this,a)}catch(e){}if(a.a)break}return a.defaultPrevented};function J(a,b,c){p.call(this);this.c=a;this.b=b;this.h=this.f=this.g=this.i=this.j=null;this.a=new yc(c,this.ee.bind(this),this.fe.bind(this),this.ge.bind(this),this.Vb.bind(this));Bc(this)}ba(J);n("shaka.cast.CastProxy",J);J.prototype.m=function(a){a&&this.a&&this.a.$a();a=[this.h?this.h.m():null,this.b?this.b.m():null,this.a?this.a.m():null];this.a=this.h=this.i=this.j=this.b=this.c=null;return Promise.all(a)};J.prototype.destroy=J.prototype.m;J.prototype.Zc=function(){return this.j};
- J.prototype.getVideo=J.prototype.Zc;J.prototype.Tc=function(){return this.i};J.prototype.getPlayer=J.prototype.Tc;J.prototype.Fc=function(){return this.a?this.a.h&&this.a.j:!1};J.prototype.canCast=J.prototype.Fc;J.prototype.V=function(){return this.a?this.a.V():!1};J.prototype.isCasting=J.prototype.V;J.prototype.Fb=function(){return this.a?this.a.Fb():""};J.prototype.receiverName=J.prototype.Fb;J.prototype.cast=function(){var a=this.Vb();return this.a.cast(a).then(function(){return this.b.hb()}.bind(this))};
- J.prototype.cast=J.prototype.cast;J.prototype.Ib=function(a){this.a.Ib(a)};J.prototype.setAppData=J.prototype.Ib;J.prototype.me=function(){var a=this.a;if(a.c){var b=a.v();chrome.cast.requestSession(a.Bb.bind(a,b),a.cc.bind(a))}};J.prototype.suggestDisconnect=J.prototype.me;J.prototype.$a=function(){this.a.$a()};J.prototype.forceDisconnect=J.prototype.$a;
- function Bc(a){a.a.init();a.h=new D;kc.forEach(function(a){E(this.h,this.c,a,this.te.bind(this))}.bind(a));oc.forEach(function(a){E(this.h,this.b,a,this.Id.bind(this))}.bind(a));a.j={};for(var b in a.c)Object.defineProperty(a.j,b,{configurable:!1,enumerable:!0,get:a.se.bind(a,b),set:a.ue.bind(a,b)});a.i={};for(b in a.b)Object.defineProperty(a.i,b,{configurable:!1,enumerable:!0,get:a.Hd.bind(a,b)});a.g=new p;a.g.Ta=a.j;a.f=new p;a.f.Ta=a.i}k=J.prototype;
- k.Vb=function(){var a={video:{},player:{},playerAfterLoad:{},manifest:this.b.Ya,startTime:null};this.c.pause();mc.forEach(function(b){a.video[b]=this.c[b]}.bind(this));this.c.ended||(a.startTime=this.c.currentTime);qc.forEach(function(b){var c=b[1];b=this.b[b[0]]();a.player[c]=b}.bind(this));rc.forEach(function(b){var c=b[1];b=this.b[b[0]]();a.playerAfterLoad[c]=b}.bind(this));return a};k.ee=function(){this.dispatchEvent(new I("caststatuschanged"))};
- k.ge=function(){qc.forEach(function(a){var b=a[1];a=this.a.get("player",a[0])();this.b[b](a)}.bind(this));var a=this.a.get("player","getManifestUri")(),b=this.a.get("video","ended"),c=Promise.resolve(),d=this.c.autoplay,e=null;b||(e=this.a.get("video","currentTime"));a&&(this.c.autoplay=!1,c=this.b.load(a,e),c["catch"](function(a){this.b.dispatchEvent(new I("error",{detail:a}))}.bind(this)));var f={};mc.forEach(function(a){f[a]=this.a.get("video",a)}.bind(this));c.then(function(){mc.forEach(function(a){this.c[a]=
- f[a]}.bind(this));rc.forEach(function(a){var b=a[1];a=this.a.get("player",a[0])();this.b[b](a)}.bind(this));this.c.autoplay=d;a&&this.c.play()}.bind(this))};
- k.se=function(a){if("addEventListener"==a)return this.g.addEventListener.bind(this.g);if("removeEventListener"==a)return this.g.removeEventListener.bind(this.g);if(this.a.V()&&!Object.keys(this.a.b.video).length){var b=this.c[a];if("function"!=typeof b)return b}return this.a.V()?this.a.get("video",a):(b=this.c[a],"function"==typeof b&&(b=b.bind(this.c)),b)};k.ue=function(a,b){this.a.V()?this.a.set("video",a,b):this.c[a]=b};k.te=function(a){this.a.V()||this.g.dispatchEvent(new I(a.type,a))};
- k.Hd=function(a){return"addEventListener"==a?this.f.addEventListener.bind(this.f):"removeEventListener"==a?this.f.removeEventListener.bind(this.f):"getNetworkingEngine"==a?this.b.Wb.bind(this.b):this.a.V()&&!Object.keys(this.a.b.video).length&&0<=pc.indexOf(a)||!this.a.V()?(a=this.b[a],a.bind(this.b)):this.a.get("player",a)};k.Id=function(a){this.a.V()||this.f.dispatchEvent(a)};k.fe=function(a,b){this.a.V()&&("video"==a?this.g.dispatchEvent(b):"player"==a&&this.f.dispatchEvent(b))};function K(a,b,c,d){p.call(this);this.a=a;this.b=b;this.j={video:a,player:b};this.l=c||function(){};this.o=d||function(a){return a};this.i=!1;this.f=!0;this.h=this.g=this.c=null;Cc(this)}ba(K);n("shaka.cast.CastReceiver",K);K.prototype.isConnected=function(){return this.i};K.prototype.isConnected=K.prototype.isConnected;K.prototype.ad=function(){return this.f};K.prototype.isIdle=K.prototype.ad;
- K.prototype.m=function(){var a=this.b?this.b.m():Promise.resolve();null!=this.h&&window.clearTimeout(this.h);this.l=this.j=this.b=this.a=null;this.i=!1;this.f=!0;this.h=this.g=this.c=null;return a.then(function(){cast.receiver.CastReceiverManager.getInstance().stop()})};K.prototype.destroy=K.prototype.m;
- function Cc(a){var b=cast.receiver.CastReceiverManager.getInstance();b.onSenderConnected=a.jc.bind(a);b.onSenderDisconnected=a.jc.bind(a);b.onSystemVolumeChanged=a.Mc.bind(a);a.g=b.getCastMessageBus("urn:x-cast:com.google.cast.media");a.g.onMessage=a.hd.bind(a);a.c=b.getCastMessageBus("urn:x-cast:com.google.shaka.v2");a.c.onMessage=a.vd.bind(a);b.start();kc.forEach(function(a){this.a.addEventListener(a,this.mc.bind(this,"video"))}.bind(a));oc.forEach(function(a){this.b.addEventListener(a,this.mc.bind(this,
- "player"))}.bind(a));cast.__platform__&&cast.__platform__.canDisplayType('video/mp4; codecs="avc1.640028"; width=3840; height=2160')?a.b.Jb(3840,2160):a.b.Jb(1920,1080);a.b.addEventListener("loading",function(){this.f=!1;Dc(this)}.bind(a));a.a.addEventListener("playing",function(){this.f=!1;Dc(this)}.bind(a));a.a.addEventListener("pause",function(){Dc(this)}.bind(a));a.b.addEventListener("unloading",function(){this.f=!0;Dc(this)}.bind(a));a.a.addEventListener("ended",function(){window.setTimeout(function(){this.a&&
- this.a.ended&&(this.f=!0,Dc(this))}.bind(this),5E3)}.bind(a))}k=K.prototype;k.jc=function(){this.i=!!cast.receiver.CastReceiverManager.getInstance().getSenders().length;Dc(this)};function Dc(a){Promise.resolve().then(function(){this.dispatchEvent(new I("caststatuschanged"));L(this,0)}.bind(a))}
- function Ec(a,b,c){for(var d in b.player)a.b[d](b.player[d]);a.l(c);c=Promise.resolve();var e=a.a.autoplay;b.manifest&&(a.a.autoplay=!1,c=a.b.load(b.manifest,b.startTime),c["catch"](function(a){this.b.dispatchEvent(new I("error",{detail:a}))}.bind(a)));c.then(function(){var a;for(a in b.video){var c=b.video[a];this.a[a]=c}for(a in b.playerAfterLoad)c=b.playerAfterLoad[a],this.b[a](c);this.a.autoplay=e;b.manifest&&(this.a.play(),L(this,0))}.bind(a))}
- k.mc=function(a,b){this.Cb();Fc(this,{type:"event",targetName:a,event:b},this.c)};k.Cb=function(){null!=this.h&&window.clearTimeout(this.h);this.h=window.setTimeout(this.Cb.bind(this),500);var a={video:{},player:{}};lc.forEach(function(b){a.video[b]=this.a[b]}.bind(this));pc.forEach(function(b){a.player[b]=this.b[b]()}.bind(this));var b=cast.receiver.CastReceiverManager.getInstance().getSystemVolume();b&&(a.video.volume=b.level,a.video.muted=b.muted);Fc(this,{type:"update",update:a},this.c)};
- k.Mc=function(){var a=cast.receiver.CastReceiverManager.getInstance().getSystemVolume();a&&Fc(this,{type:"update",update:{video:{volume:a.level,muted:a.muted}}},this.c);Fc(this,{type:"event",targetName:"video",event:{type:"volumechange"}},this.c)};
- k.vd=function(a){var b=wc(a.data);switch(b.type){case "init":Ec(this,b.initState,b.appData);this.Cb();break;case "appData":this.l(b.appData);break;case "set":var c=b.targetName,d=b.property,e=b.value;if("video"==c)if(b=cast.receiver.CastReceiverManager.getInstance(),"volume"==d){b.setSystemVolumeLevel(e);break}else if("muted"==d){b.setSystemVolumeMuted(e);break}this.j[c][d]=e;break;case "call":c=b.targetName;d=b.methodName;e=b.args;c=this.j[c];c[d].apply(c,e);break;case "asyncCall":c=b.targetName,
- d=b.methodName,e=b.args,b=b.id,a=a.senderId,c=this.j[c],c[d].apply(c,e).then(this.vc.bind(this,a,b,null),this.vc.bind(this,a,b))}};
- k.hd=function(a){var b=wc(a.data);switch(b.type){case "PLAY":this.a.play();L(this,0);break;case "PAUSE":this.a.pause();L(this,0);break;case "SEEK":a=b.currentTime;var c=b.resumeState;null!=a&&(this.a.currentTime=Number(a));c&&"PLAYBACK_START"==c?(this.a.play(),L(this,0)):c&&"PLAYBACK_PAUSE"==c&&(this.a.pause(),L(this,0));break;case "STOP":this.b.hb().then(function(){L(this,0)}.bind(this));break;case "GET_STATUS":L(this,Number(b.requestId));break;case "VOLUME":c=b.volume;a=c.level;var c=c.muted,d=
- this.a.volume,e=this.a.muted;null!=a&&(this.a.volume=Number(a));null!=c&&(this.a.muted=c);d==this.a.volume&&e==this.a.muted||L(this,0);break;case "LOAD":c=b.media.contentId;a=b.currentTime;var f=this.o(c);this.a.autoplay=!0;this.b.load(f,a).then(function(){L(this,0,{contentId:f,streamType:this.b.$()?"LIVE":"BUFFERED",contentType:""})}.bind(this))["catch"](function(a){var c="LOAD_FAILED";7==a.category&&7E3==a.code&&(c="LOAD_CANCELLED");Fc(this,{requestId:Number(b.requestId),type:c},this.g)}.bind(this));
- break;default:Fc(this,{requestId:Number(b.requestId),type:"INVALID_REQUEST",reason:"INVALID_COMMAND"},this.g)}};k.vc=function(a,b,c){Fc(this,{type:"asyncComplete",id:b,error:c},this.c,a)};function Fc(a,b,c,d){a.i&&(a=vc(b),d?c.getCastChannel(d).send(a):c.broadcast(a))}
- function L(a,b,c){var d=Gc,d={mediaSessionId:0,playbackRate:a.a.playbackRate,playerState:a.f?d.IDLE:a.b.ka?d.Ac:a.a.paused?d.Bc:d.Cc,currentTime:a.a.currentTime,supportedMediaCommands:15,volume:{level:a.a.volume,muted:a.a.muted}};c&&(d.media=c);Fc(a,{requestId:b,type:"MEDIA_STATUS",status:[d]},a.g)}var Gc={IDLE:"IDLE",Cc:"PLAYING",Ac:"BUFFERING",Bc:"PAUSED"};function Hc(a,b){var c=M(a,b);return 1!=c.length?null:c[0]}function M(a,b){return Array.prototype.filter.call(a.childNodes,function(a){return a.tagName==b})}function Ic(a){var b=a.firstChild;return b&&b.nodeType==Node.TEXT_NODE?a.textContent.trim():null}function N(a,b,c,d){var e=null;a=a.getAttribute(b);null!=a&&(e=c(a));return null==e?void 0!=d?d:null:e}function Jc(a){if(!a)return null;a=Date.parse(a);return isNaN(a)?null:Math.floor(a/1E3)}
- function Kc(a){if(!a)return null;a=/^P(?:([0-9]*)Y)?(?:([0-9]*)M)?(?:([0-9]*)D)?(?:T(?:([0-9]*)H)?(?:([0-9]*)M)?(?:([0-9.]*)S)?)?$/.exec(a);if(!a)return null;a=31536E3*Number(a[1]||null)+2592E3*Number(a[2]||null)+86400*Number(a[3]||null)+3600*Number(a[4]||null)+60*Number(a[5]||null)+Number(a[6]||null);return isFinite(a)?a:null}function Lc(a){var b=/([0-9]+)-([0-9]+)/.exec(a);if(!b)return null;a=Number(b[1]);if(!isFinite(a))return null;b=Number(b[2]);return isFinite(b)?{start:a,end:b}:null}
- function Mc(a){a=Number(a);return a%1?null:a}function Nc(a){a=Number(a);return!(a%1)&&0<a?a:null}function Oc(a){a=Number(a);return!(a%1)&&0<=a?a:null}function Pc(a){var b;a=(b=a.match(/^(\d+)\/(\d+)$/))?Number(b[1]/b[2]):Number(a);return isNaN(a)?null:a};var Qc={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"};
- function Rc(a,b,c){a=Sc(a);var d=null,e=null,f=[],g=[],h=a.map(function(a){return a.keyId}).filter(ya);if(0<h.length&&(e=h[0],h.some(za(e))))throw new t(2,4,4010);c||(g=a.filter(function(a){return"urn:mpeg:dash:mp4protection:2011"==a.sc?(d=a.init||d,!1):!0}),0<g.length&&(f=Tc(d,b,g),f.length||(f=[Ba("",d)])));0<a.length&&(c||!g.length)&&(f=Na(Qc).map(function(a){return Ba(a,d)}));e&&f.forEach(function(a){a.initData.forEach(function(a){a.keyId=e})});return{Sb:e,ze:d,drmInfos:f,Ub:!0}}
- function Uc(a,b,c,d){var e=Rc(a,b,d);if(c.Ub){a=1==c.drmInfos.length&&!c.drmInfos[0].keySystem;b=!e.drmInfos.length;if(!c.drmInfos.length||a&&!b)c.drmInfos=e.drmInfos;c.Ub=!1}else if(0<e.drmInfos.length&&(c.drmInfos=c.drmInfos.filter(function(a){return e.drmInfos.some(function(b){return b.keySystem==a.keySystem})}),!c.drmInfos.length))throw new t(2,4,4008);return e.Sb||c.Sb}function Tc(a,b,c){return c.map(function(c){var d=Qc[c.sc];return d?[Ba(d,c.init||a)]:b(c.node)||[]}).reduce(x,[])}
- function Sc(a){return a.map(function(a){var b=a.getAttribute("schemeIdUri"),d=a.getAttribute("cenc:default_KID"),e=M(a,"cenc:pssh").map(Ic);if(!b)return null;b=b.toLowerCase();if(d&&(d=d.replace(/-/g,"").toLowerCase(),0<=d.indexOf(" ")))throw new t(2,4,4009);var f=[];try{f=e.map(function(a){return{initDataType:"cenc",initData:Ya(a),keyId:null}})}catch(g){throw new t(2,4,4007);}return{node:a,sc:b,keyId:d,init:0<f.length?f:null}}).filter(ya)};function Vc(a,b,c,d,e){null!=e&&(e=Math.round(e));var f={RepresentationID:b,Number:c,Bandwidth:d,Time:e};return a.replace(/\$(RepresentationID|Number|Bandwidth|Time)?(?:%0([0-9]+)d)?\$/g,function(a,b,c){if("$$"==a)return"$";var d=f[b];if(null==d)return a;"RepresentationID"==b&&c&&(c=void 0);a=d.toString();c=window.parseInt(c,10)||1;return Array(Math.max(0,c-a.length)+1).join("0")+a})}
- function Wc(a,b){var c=Xc(a,b,"timescale"),d=1;c&&(d=Nc(c)||1);c=Xc(a,b,"duration");(c=Nc(c||""))&&(c/=d);var e=Xc(a,b,"startNumber"),f=Xc(a,b,"presentationTimeOffset"),g=Oc(e||"");if(null==e||null==g)g=1;var h=Yc(a,b,"SegmentTimeline"),e=null;if(h){for(var e=d,l=Number(f),m=a.R.duration||Infinity,h=M(h,"S"),q=[],r=0,v=0;v<h.length;++v){var u=h[v],w=N(u,"t",Oc),G=N(u,"d",Oc),u=N(u,"r",Mc);null!=w&&(w-=l);if(!G)break;w=null!=w?w:r;u=u||0;if(0>u)if(v+1<h.length){u=N(h[v+1],"t",Oc);if(null==u)break;
- else if(w>=u)break;u=Math.ceil((u-w)/G)-1}else{if(Infinity==m)break;else if(w/e>=m)break;u=Math.ceil((m*e-w)/G)-1}0<q.length&&w!=r&&(q[q.length-1].end=w/e);for(var pa=0;pa<=u;++pa)r=w+G,q.push({start:w/e,end:r/e,qe:w}),w=r}e=q}return{timescale:d,P:c,za:g,presentationTimeOffset:Number(f)/d||0,Pb:Number(f),F:e}}function Xc(a,b,c){return[b(a.w),b(a.S),b(a.T)].filter(ya).map(function(a){return a.getAttribute(c)}).reduce(function(a,b){return a||b})}
- function Yc(a,b,c){return[b(a.w),b(a.S),b(a.T)].filter(ya).map(function(a){return Hc(a,c)}).reduce(function(a,b){return a||b})};function Zc(a,b,c){this.a=a;this.X=b;this.M=c}n("shaka.media.InitSegmentReference",Zc);function O(a,b,c,d,e,f){this.position=a;this.startTime=b;this.endTime=c;this.a=d;this.X=e;this.M=f}n("shaka.media.SegmentReference",O);function P(a,b){this.H=a;this.a=b==$c;this.u=0}n("shaka.util.DataViewReader",P);var $c=1;P.Endianness={ve:0,xe:$c};P.prototype.Z=function(){return this.u<this.H.byteLength};P.prototype.hasMoreData=P.prototype.Z;P.prototype.Vc=function(){return this.u};P.prototype.getPosition=P.prototype.Vc;P.prototype.Qc=function(){return this.H.byteLength};P.prototype.getLength=P.prototype.Qc;P.prototype.Eb=function(){try{var a=this.H.getUint8(this.u)}catch(b){ad()}this.u+=1;return a};P.prototype.readUint8=P.prototype.Eb;
- P.prototype.oc=function(){try{var a=this.H.getUint16(this.u,this.a)}catch(b){ad()}this.u+=2;return a};P.prototype.readUint16=P.prototype.oc;P.prototype.D=function(){try{var a=this.H.getUint32(this.u,this.a)}catch(b){ad()}this.u+=4;return a};P.prototype.readUint32=P.prototype.D;P.prototype.nc=function(){try{var a=this.H.getInt32(this.u,this.a)}catch(b){ad()}this.u+=4;return a};P.prototype.readInt32=P.prototype.nc;
- P.prototype.Pa=function(){try{if(this.a){var a=this.H.getUint32(this.u,!0);var b=this.H.getUint32(this.u+4,!0)}else b=this.H.getUint32(this.u,!1),a=this.H.getUint32(this.u+4,!1)}catch(c){ad()}if(2097151<b)throw new t(2,3,3001);this.u+=8;return b*Math.pow(2,32)+a};P.prototype.readUint64=P.prototype.Pa;P.prototype.Ka=function(a){this.u+a>this.H.byteLength&&ad();var b=this.H.buffer.slice(this.u,this.u+a);this.u+=a;return new Uint8Array(b)};P.prototype.readBytes=P.prototype.Ka;
- P.prototype.I=function(a){this.u+a>this.H.byteLength&&ad();this.u+=a};P.prototype.skip=P.prototype.I;P.prototype.Db=function(){for(var a=this.u;this.Z()&&this.H.getUint8(this.u);)this.u+=1;a=this.H.buffer.slice(a,this.u);this.u+=1;return F(a)};P.prototype.readTerminatedString=P.prototype.Db;function ad(){throw new t(2,3,3E3);};function Q(){this.b=[];this.a=[]}n("shaka.util.Mp4Parser",Q);Q.prototype.C=function(a,b){var c=bd(a);this.b[c]=0;this.a[c]=b;return this};Q.prototype.box=Q.prototype.C;Q.prototype.da=function(a,b){var c=bd(a);this.b[c]=1;this.a[c]=b;return this};Q.prototype.fullBox=Q.prototype.da;Q.prototype.parse=function(a){for(a=new P(new DataView(a),0);a.Z();)this.eb(0,a)};Q.prototype.parse=Q.prototype.parse;
- Q.prototype.eb=function(a,b){var c=b.u,d=b.D(),e=b.D();switch(d){case 0:d=b.H.byteLength-c;break;case 1:d=b.Pa()}var f=this.a[e];if(f){var g=null,h=null;1==this.b[e]&&(h=b.D(),g=h>>>24,h&=16777215);e=c+d-b.u;e=0<e?b.Ka(e).buffer:new ArrayBuffer(0);e=new P(new DataView(e),0);f({Na:this,version:g,Nc:h,s:e,size:d,start:c+a})}else b.I(c+d-b.u)};Q.prototype.parseNext=Q.prototype.eb;function R(a){for(;a.s.Z();)a.Na.eb(a.start,a.s)}Q.children=R;
- function cd(a){for(var b=a.s.D();0<b;--b)a.Na.eb(a.start,a.s)}Q.sampleDescription=cd;function dd(a){return function(b){a(b.s.Ka(b.s.H.byteLength-b.s.u))}}Q.allData=dd;function bd(a){for(var b=0,c=0;c<a.length;c++)b=b<<8|a.charCodeAt(c);return b};function ed(a,b,c,d){var e,f=(new Q).da("sidx",function(a){e=fd(b,d,c,a)});a&&f.parse(a);if(e)return e;throw new t(2,3,3004);}
- function fd(a,b,c,d){var e=[];d.s.I(4);var f=d.s.D();if(!f)throw new t(2,3,3005);if(d.version){var g=d.s.Pa();var h=d.s.Pa()}else g=d.s.D(),h=d.s.D();d.s.I(2);var l=d.s.oc();b=g-b;a=a+d.size+h;for(h=0;h<l;h++){var m=d.s.D();g=(m&2147483648)>>>31;var m=m&2147483647,q=d.s.D();d.s.I(4);if(1==g)throw new t(2,3,3006);e.push(new O(e.length,b/f,(b+q)/f,function(){return c},a,a+m-1));b+=q;a+=m}return e};function S(a){this.a=a}n("shaka.media.SegmentIndex",S);S.prototype.m=function(){this.a=null;return Promise.resolve()};S.prototype.destroy=S.prototype.m;S.prototype.find=function(a){for(var b=this.a.length-1;0<=b;--b){var c=this.a[b];if(a>=c.startTime&&a<c.endTime)return c.position}return this.a.length&&a<this.a[0].startTime?this.a[0].position:null};S.prototype.find=S.prototype.find;S.prototype.get=function(a){if(!this.a.length)return null;a-=this.a[0].position;return 0>a||a>=this.a.length?null:this.a[a]};
- S.prototype.get=S.prototype.get;S.prototype.xb=function(a){for(var b,c,d=[],e=c=0;c<this.a.length&&e<a.length;){var f=this.a[c];b=a[e];f.startTime<b.startTime?(d.push(f),c++):(f.startTime>b.startTime||(.1<Math.abs(f.endTime-b.endTime)?d.push(b):d.push(f),c++),e++)}for(;c<this.a.length;)d.push(this.a[c++]);if(d.length)for(c=d[d.length-1].position+1;e<a.length;)b=a[e++],b=new O(c++,b.startTime,b.endTime,b.a,b.X,b.M),d.push(b);else d=a;this.a=d};S.prototype.merge=S.prototype.xb;
- S.prototype.qb=function(a){for(var b=0;b<this.a.length&&!(this.a[b].endTime>a);++b);this.a.splice(0,b)};S.prototype.evict=S.prototype.qb;function gd(a,b){if(a.a.length){var c=a.a[a.a.length-1];c.startTime>b||(a.a[a.a.length-1]=new O(c.position,c.startTime,b,c.a,c.X,c.M))}};function hd(a){this.b=a;this.a=new P(a,0);id||(id=[new Uint8Array([255]),new Uint8Array([127,255]),new Uint8Array([63,255,255]),new Uint8Array([31,255,255,255]),new Uint8Array([15,255,255,255,255]),new Uint8Array([7,255,255,255,255,255]),new Uint8Array([3,255,255,255,255,255,255]),new Uint8Array([1,255,255,255,255,255,255,255])])}var id;hd.prototype.Z=function(){return this.a.Z()};
- function jd(a){var b=kd(a);if(7<b.length)throw new t(2,3,3002);for(var c=0,d=0;d<b.length;d++)c=256*c+b[d];b=c;c=kd(a);a:{for(d=0;d<id.length;d++)if(ab(c,id[d])){d=!0;break a}d=!1}if(d)c=a.b.byteLength-a.a.u;else{if(8==c.length&&c[1]&224)throw new t(2,3,3001);for(var d=c[0]&(1<<8-c.length)-1,e=1;e<c.length;e++)d=256*d+c[e];c=d}c=a.a.u+c<=a.b.byteLength?c:a.b.byteLength-a.a.u;d=new DataView(a.b.buffer,a.b.byteOffset+a.a.u,c);a.a.I(c);return new ld(b,d)}
- function kd(a){var b=a.a.Eb(),c;for(c=1;8>=c&&!(b&1<<8-c);c++);if(8<c)throw new t(2,3,3002);var d=new Uint8Array(c);d[0]=b;for(b=1;b<c;b++)d[b]=a.a.Eb();return d}function ld(a,b){this.id=a;this.a=b}function md(a){if(8<a.a.byteLength)throw new t(2,3,3002);if(8==a.a.byteLength&&a.a.getUint8(0)&224)throw new t(2,3,3001);for(var b=0,c=0;c<a.a.byteLength;c++)var d=a.a.getUint8(c),b=256*b+d;return b};function nd(){}
- nd.prototype.parse=function(a,b,c,d){var e;b=new hd(new DataView(b));if(440786851!=jd(b).id)throw new t(2,3,3008);var f=jd(b);if(408125543!=f.id)throw new t(2,3,3009);b=f.a.byteOffset;f=new hd(f.a);for(e=null;f.Z();){var g=jd(f);if(357149030==g.id){e=g;break}}if(!e)throw new t(2,3,3010);f=new hd(e.a);e=1E6;for(g=null;f.Z();){var h=jd(f);if(2807729==h.id)e=md(h);else if(17545==h.id)if(g=h,4==g.a.byteLength)g=g.a.getFloat32(0);else if(8==g.a.byteLength)g=g.a.getFloat64(0);else throw new t(2,3,3003);
- }if(null==g)throw new t(2,3,3011);f=e/1E9;e=g*f;a=jd(new hd(new DataView(a)));if(475249515!=a.id)throw new t(2,3,3007);return od(a,b,f,e,c,d)};function od(a,b,c,d,e,f){function g(){return e}var h=[];a=new hd(a.a);for(var l=-1,m=-1;a.Z();){var q=jd(a);if(187==q.id){var r=pd(q);r&&(q=c*(r.re-f),r=b+r.Nd,0<=l&&h.push(new O(h.length,l,q,g,m,r-1)),l=q,m=r)}}0<=l&&h.push(new O(h.length,l,d,g,m,null));return h}
- function pd(a){var b=new hd(a.a);a=jd(b);if(179!=a.id)throw new t(2,3,3013);a=md(a);b=jd(b);if(183!=b.id)throw new t(2,3,3012);for(var b=new hd(b.a),c=0;b.Z();){var d=jd(b);if(241==d.id){c=md(d);break}}return{re:a,Nd:c}};function qd(a,b){var c=Yc(a,b,"Initialization");if(!c)return null;var d=a.w.U,e=c.getAttribute("sourceURL");e&&(d=z(a.w.U,[e]));var e=0,f=null;if(c=N(c,"range",Lc))e=c.start,f=c.end;return new Zc(function(){return d},e,f)}
- function rd(a,b){var c=Xc(a,sd,"presentationTimeOffset"),d=qd(a,sd);var e=Number(c);var f=a.w.contentType,g=a.w.mimeType.split("/")[1];if("text"!=f&&"mp4"!=g&&"webm"!=g)throw new t(2,4,4006);if("webm"==g&&!d)throw new t(2,4,4005);var f=Yc(a,sd,"RepresentationIndex"),h=Xc(a,sd,"indexRange"),l=a.w.U,h=Lc(h||"");if(f){var m=f.getAttribute("sourceURL");m&&(l=z(a.w.U,[m]));h=N(f,"range",Lc,h)}if(!h)throw new t(2,4,4002);e=td(a,b,d,l,h.start,h.end,g,e);return{createSegmentIndex:e.createSegmentIndex,findSegmentPosition:e.findSegmentPosition,
- getSegmentReference:e.getSegmentReference,initSegmentReference:d,presentationTimeOffset:Number(c)||0}}
- function td(a,b,c,d,e,f,g,h){var l=a.presentationTimeline,m=!a.Da||!a.R.ub,q=a.R.duration,r=b,v=null;return{createSegmentIndex:function(){var a=[r(d,e,f),"webm"==g?r(c.a(),c.X,c.M):null];r=null;return Promise.all(a).then(function(a){var b=a[0];a=a[1]||null;b="mp4"==g?ed(b,e,d,h):(new nd).parse(b,a,d,h);l.Ha(0,b);v=new S(b);m&&gd(v,q)})},findSegmentPosition:function(a){return v.find(a)},getSegmentReference:function(a){return v.get(a)}}}function sd(a){return a.Qa};function ud(a,b){var c=qd(a,vd);var d=wd(a);var e=Wc(a,vd),f=e.za;f||(f=1);var g=0;e.P?g=e.P*(f-1):e.F&&0<e.F.length&&(g=e.F[0].start);d={P:e.P,startTime:g,za:f,presentationTimeOffset:e.presentationTimeOffset,F:e.F,Ga:d};if(!d.P&&!d.F&&1<d.Ga.length)throw new t(2,4,4002);if(!d.P&&!a.R.duration&&!d.F&&1==d.Ga.length)throw new t(2,4,4002);if(d.F&&!d.F.length)throw new t(2,4,4002);f=e=null;a.T.id&&a.w.id&&(f=a.T.id+","+a.w.id,e=b[f]);g=xd(a.R.duration,d.za,a.w.U,d);e?(e.xb(g),e.qb(a.presentationTimeline.ma()-
- a.R.start)):(a.presentationTimeline.Ha(0,g),e=new S(g),f&&a.Da&&(b[f]=e));a.Da&&a.R.ub||gd(e,a.R.duration);return{createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:e.find.bind(e),getSegmentReference:e.get.bind(e),initSegmentReference:c,presentationTimeOffset:d.presentationTimeOffset}}function vd(a){return a.oa}
- function xd(a,b,c,d){var e=d.Ga.length;d.F&&d.F.length!=d.Ga.length&&(e=Math.min(d.F.length,d.Ga.length));for(var f=[],g=d.startTime,h=0;h<e;h++){var l=d.Ga[h],m=z(c,[l.cd]);var q=null!=d.P?g+d.P:d.F?d.F[h].end:g+a;f.push(new O(h+b,g,q,function(a){return a}.bind(null,m),l.start,l.end));g=q}return f}
- function wd(a){return[a.w.oa,a.S.oa,a.T.oa].filter(ya).map(function(a){return M(a,"SegmentURL")}).reduce(function(a,c){return 0<a.length?a:c}).map(function(b){b.getAttribute("indexRange")&&!a.$b&&(a.$b=!0);var c=b.getAttribute("media");b=N(b,"mediaRange",Lc,{start:0,end:null});return{cd:c,start:b.start,end:b.end}})};function yd(a,b,c,d){var e=zd(a);var f=Wc(a,Ad);var g=Xc(a,Ad,"media"),h=Xc(a,Ad,"index");f={P:f.P,timescale:f.timescale,za:f.za,presentationTimeOffset:f.presentationTimeOffset,Pb:f.Pb,F:f.F,wb:g,Ma:h};g=0+(f.Ma?1:0);g+=f.F?1:0;g+=f.P?1:0;if(!g)throw new t(2,4,4002);1!=g&&(f.Ma&&(f.F=null),f.P=null);if(!f.Ma&&!f.wb)throw new t(2,4,4002);if(f.Ma){c=a.w.mimeType.split("/")[1];if("mp4"!=c&&"webm"!=c)throw new t(2,4,4006);if("webm"==c&&!e)throw new t(2,4,4005);d=Vc(f.Ma,a.w.id,null,a.bandwidth||null,
- null);d=z(a.w.U,[d]);a=td(a,b,e,d,0,null,c,f.presentationTimeOffset)}else f.P?(d||a.presentationTimeline.yb(f.P),a=Bd(a,f)):(d=b=null,a.T.id&&a.w.id&&(d=a.T.id+","+a.w.id,b=c[d]),g=Cd(a,f),b?(b.xb(g),b.qb(a.presentationTimeline.ma()-a.R.start)):(a.presentationTimeline.Ha(0,g),b=new S(g),d&&a.Da&&(c[d]=b)),a.Da&&a.R.ub||gd(b,a.R.duration),a={createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:b.find.bind(b),getSegmentReference:b.get.bind(b)});return{createSegmentIndex:a.createSegmentIndex,
- findSegmentPosition:a.findSegmentPosition,getSegmentReference:a.getSegmentReference,initSegmentReference:e,presentationTimeOffset:f.presentationTimeOffset}}function Ad(a){return a.Ra}
- function Bd(a,b){var c=a.R.duration,d=b.P,e=b.za,f=b.timescale,g=b.wb,h=a.bandwidth||null,l=a.w.id,m=a.w.U;return{createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:function(a){return 0>a||c&&a>=c?null:Math.floor(a/d)},getSegmentReference:function(a){var b=a*d;return 0>b||c&&b>=c?null:new O(a,b,b+d,function(){var c=Vc(g,l,a+e,h,b*f);return z(m,[c])},0,null)}}}
- function Cd(a,b){for(var c=[],d=0;d<b.F.length;d++){var e=d+b.za;c.push(new O(e,b.F[d].start,b.F[d].end,function(a,b,c,d,e,q){a=Vc(a,b,e,c,q);return z(d,[a]).map(function(a){return a.toString()})}.bind(null,b.wb,a.w.id,a.bandwidth||null,a.w.U,e,b.F[d].qe+b.Pb),0,null))}return c}function zd(a){var b=Xc(a,Ad,"initialization");if(!b)return null;var c=a.w.id,d=a.bandwidth||null,e=a.w.U;return new Zc(function(){var a=Vc(b,c,null,d,null);return z(e,[a])},0,null)};var Dd={},Ed={};n("shaka.media.ManifestParser.registerParserByExtension",function(a,b){Ed[a]=b});n("shaka.media.ManifestParser.registerParserByMime",function(a,b){Dd[a]=b});function Fd(){var a={},b;for(b in Dd)a[b]=!0;for(b in Ed)a[b]=!0;["application/dash+xml","application/x-mpegurl","application/vnd.apple.mpegurl","application/vnd.ms-sstr+xml"].forEach(function(b){a[b]=!!Dd[b]});["mpd","m3u8","ism"].forEach(function(b){a[b]=!!Ed[b]});return a}
- function Gd(a,b,c,d){var e=d;e||(d=(new ia(a)).W.split("/").pop().split("."),1<d.length&&(d=d.pop().toLowerCase(),e=Ed[d]));if(e)return Promise.resolve(e);c=C([a],c);c.method="HEAD";return b.request(0,c).then(function(b){(b=b.headers["content-type"])&&(b=b.toLowerCase());return(e=Dd[b])?e:Promise.reject(new t(2,4,4E3,a))},function(a){a.severity=2;return Promise.reject(a)})};function T(a,b){this.f=a;this.i=b;this.c=this.a=Infinity;this.b=1;this.h=0;this.g=!0}n("shaka.media.PresentationTimeline",T);T.prototype.Y=function(){return this.a};T.prototype.getDuration=T.prototype.Y;T.prototype.pa=function(a){this.a=a};T.prototype.setDuration=T.prototype.pa;T.prototype.Wc=function(){return this.f};T.prototype.getPresentationStartTime=T.prototype.Wc;T.prototype.wc=function(a){this.h=a};T.prototype.setClockOffset=T.prototype.wc;T.prototype.yc=function(a){this.g=a};
- T.prototype.setStatic=T.prototype.yc;T.prototype.Xc=function(){return this.c};T.prototype.getSegmentAvailabilityDuration=T.prototype.Xc;T.prototype.xc=function(a){this.c=a};T.prototype.setSegmentAvailabilityDuration=T.prototype.xc;T.prototype.Ha=function(a,b){b.length&&(this.b=b.reduce(function(a,b){return Math.max(a,b.endTime-b.startTime)},this.b))};T.prototype.notifySegments=T.prototype.Ha;T.prototype.yb=function(a){this.b=Math.max(this.b,a)};T.prototype.notifyMaxSegmentDuration=T.prototype.yb;
- T.prototype.$=function(){return Infinity==this.a&&!this.g};T.prototype.isLive=T.prototype.$;T.prototype.va=function(){return Infinity!=this.a&&!this.g};T.prototype.isInProgress=T.prototype.va;T.prototype.ma=function(){return this.Ea(0)};T.prototype.getSegmentAvailabilityStart=T.prototype.ma;T.prototype.Ea=function(a){if(Infinity==this.c)return 0;var b=this.ua();return Math.max(0,Math.min(b-this.c+a,b))};T.prototype.getSafeAvailabilityStart=T.prototype.Ea;
- T.prototype.ua=function(){return this.$()||this.va()?Math.min(Math.max(0,(Date.now()+this.h)/1E3-this.b-this.f),this.a):this.a};T.prototype.getSegmentAvailabilityEnd=T.prototype.ua;T.prototype.bb=function(){return Math.max(0,this.ua()-(this.$()||this.va()?this.i:0))};T.prototype.getSeekRangeEnd=T.prototype.bb;function Hd(){this.a=this.b=null;this.g=[];this.c=null;this.i=[];this.h=1;this.j={};this.l=0;this.f=null}n("shaka.dash.DashParser",Hd);k=Hd.prototype;k.configure=function(a){this.b=a};k.start=function(a,b){this.g=[a];this.a=b;return Id(this).then(function(){this.a&&Jd(this,0);return this.c}.bind(this))};k.stop=function(){this.b=this.a=null;this.g=[];this.c=null;this.i=[];this.j={};null!=this.f&&(window.clearTimeout(this.f),this.f=null);return Promise.resolve()};k.update=function(){Id(this)["catch"](function(a){if(this.a)this.a.onError(a)}.bind(this))};
- k.onExpirationUpdated=function(){};function Id(a){return a.a.networkingEngine.request(0,C(a.g,a.b.retryParameters)).then(function(a){if(this.a)return Kd(this,a.data,a.uri)}.bind(a))}
- function Kd(a,b,c){var d=F(b),e=new DOMParser,f=null;b=null;try{f=e.parseFromString(d,"text/xml")}catch(v){}f&&"MPD"==f.documentElement.tagName&&(b=f.documentElement);b&&0<b.getElementsByTagName("parsererror").length&&(b=null);if(!b)throw new t(2,4,4001);c=[c];d=M(b,"Location").map(Ic).filter(ya);0<d.length&&(c=a.g=d);d=M(b,"BaseURL").map(Ic);c=z(c,d);var g=N(b,"minBufferTime",Kc);a.l=N(b,"minimumUpdatePeriod",Kc,-1);var h=N(b,"availabilityStartTime",Jc),d=N(b,"timeShiftBufferDepth",Kc),l=N(b,"suggestedPresentationDelay",
- Kc),e=N(b,"maxSegmentDuration",Kc),f=b.getAttribute("type")||"static";if(a.c)var m=a.c.presentationTimeline;else{var q=Math.max(10,1.5*g);m=new T(h,null!=l?l:q)}var h=Ld(a,{Da:"static"!=f,presentationTimeline:m,T:null,R:null,S:null,w:null,bandwidth:void 0,$b:!1},c,b),l=h.duration,r=h.periods;m.yc("static"==f);m.pa(l||Infinity);m.xc(null!=d?d:Infinity);m.yb(e||1);if(a.c)return Promise.resolve();b=M(b,"UTCTiming");return Md(a,c,b,m.$()).then(function(a){this.a&&(m.wc(a),this.c={presentationTimeline:m,
- periods:r,offlineSessionIds:[],minBufferTime:g||0})}.bind(a))}
- function Ld(a,b,c,d){var e=N(d,"mediaPresentationDuration",Kc),f=[],g=0;d=M(d,"Period");for(var h=0;h<d.length;h++){var l=d[h],g=N(l,"start",Kc,g),m=N(l,"duration",Kc),q=null;if(h!=d.length-1){var r=N(d[h+1],"start",Kc);null!=r&&(q=r-g)}else null!=e&&(q=e-g);null==q&&(q=m);l=Nd(a,b,c,{start:g,duration:q,node:l,ub:null==q||h==d.length-1});f.push(l);m=b.T.id;a.i.every(za(m))&&(a.a.filterPeriod(l),a.i.push(m),a.c&&a.c.periods.push(l));if(null==q){g=null;break}g+=q}return null!=e?{periods:f,duration:e}:
- {periods:f,duration:g}}
- function Nd(a,b,c,d){b.T=Od(d.node,null,c);b.R=d;b.T.id||(b.T.id="__shaka_period_"+d.start);M(d.node,"EventStream").forEach(a.Fd.bind(a,d.start,d.duration));c=M(d.node,"AdaptationSet").map(a.Dd.bind(a,b)).filter(ya);var e=c.map(function(a){return a.Pd}).reduce(x,[]),f=e.filter(Aa);if(b.Da&&e.length!=f.length)throw new t(2,4,4018);var g=c.filter(function(a){return!a.Ob});c.filter(function(a){return a.Ob}).forEach(function(a){var b=a.streams[0],c=a.Ob;g.forEach(function(a){a.id==c&&a.streams.forEach(function(a){a.trickModeVideo=
- b})})});e=Pd(g,"video");f=Pd(g,"audio");if(!e.length&&!f.length)throw new t(2,4,4004);f.length||(f=[null]);e.length||(e=[null]);b=[];for(c=0;c<f.length;c++)for(var h=0;h<e.length;h++)Qd(a,f[c],e[h],b);a=Pd(g,"text");e=[];for(c=0;c<a.length;c++)e.push.apply(e,a[c].streams);return{startTime:d.start,textStreams:e,variants:b}}function Pd(a,b){return a.filter(function(a){return a.contentType==b})}
- function Qd(a,b,c,d){if(b||c)if(b&&c){var e=b.drmInfos;var f=c.drmInfos;if(e.length&&f.length?0<sb(e,f).length:1)for(var g=sb(b.drmInfos,c.drmInfos),e=0;e<b.streams.length;e++)for(var h=0;h<c.streams.length;h++)f=c.streams[h].bandwidth+b.streams[e].bandwidth,f={id:a.h++,language:b.language,primary:b.vb||c.vb,audio:b.streams[e],video:c.streams[h],bandwidth:f,drmInfos:g,allowedByApplication:!0,allowedByKeySystem:!0},d.push(f)}else for(g=b||c,e=0;e<g.streams.length;e++)f=g.streams[e].bandwidth,f={id:a.h++,
- language:g.language||"und",primary:g.vb,audio:b?g.streams[e]:null,video:c?g.streams[e]:null,bandwidth:f,drmInfos:g.drmInfos,allowedByApplication:!0,allowedByKeySystem:!0},d.push(f)}
- k.Dd=function(a,b){a.S=Od(b,a.T,null);var c=!1,d=M(b,"Role"),e=d.map(function(a){return a.getAttribute("value")}).filter(ya),f=void 0;"text"==a.S.contentType&&(f="subtitle");for(var g=0;g<d.length;g++){var h=d[g].getAttribute("schemeIdUri");if(null==h||"urn:mpeg:dash:role:2011"==h)switch(h=d[g].getAttribute("value"),h){case "main":c=!0;break;case "caption":case "subtitle":f=h}}var l=null,m=!1;M(b,"EssentialProperty").forEach(function(a){"http://dashif.org/guidelines/trickmode"==a.getAttribute("schemeIdUri")?
- l=a.getAttribute("value"):m=!0});if(m)return null;var d=M(b,"ContentProtection"),q=Rc(d,this.b.dash.customScheme,this.b.dash.ignoreDrmInfo),d=Sb(b.getAttribute("lang")||"und"),h=b.getAttribute("label"),g=M(b,"Representation"),e=g.map(this.Gd.bind(this,a,q,f,d,h,c,e)).filter(function(a){return!!a});if(!e.length)throw new t(2,4,4003);a.S.contentType&&"application"!=a.S.contentType||(a.S.contentType=Rd(e[0].mimeType,e[0].codecs),e.forEach(function(b){b.type=a.S.contentType}));e.forEach(function(a){q.drmInfos.forEach(function(b){a.keyId&&
- b.keyIds.push(a.keyId)})});f=g.map(function(a){return a.getAttribute("id")}).filter(ya);return{id:a.S.id||"__fake__"+this.h++,contentType:a.S.contentType,language:d,vb:c,streams:e,drmInfos:q.drmInfos,Ob:l,Pd:f}};
- k.Gd=function(a,b,c,d,e,f,g,h){a.w=Od(h,a.S,null);if(!Sd(a.w))return null;a.bandwidth=N(h,"bandwidth",Nc)||void 0;var l=this.Qd.bind(this);if(a.w.Qa)l=rd(a,l);else if(a.w.oa)l=ud(a,this.j);else if(a.w.Ra)l=yd(a,l,this.j,!!this.c);else{var m=a.w.U,q=a.R.duration||0;l={createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:function(a){return 0<=a&&a<q?1:null},getSegmentReference:function(a){return 1!=a?null:new O(1,0,q,function(){return m},0,null)},initSegmentReference:null,presentationTimeOffset:0}}h=
- M(h,"ContentProtection");h=Uc(h,this.b.dash.customScheme,b,this.b.dash.ignoreDrmInfo);return{id:this.h++,createSegmentIndex:l.createSegmentIndex,findSegmentPosition:l.findSegmentPosition,getSegmentReference:l.getSegmentReference,initSegmentReference:l.initSegmentReference,presentationTimeOffset:l.presentationTimeOffset,mimeType:a.w.mimeType,codecs:a.w.codecs,frameRate:a.w.frameRate,bandwidth:a.bandwidth,width:a.w.width,height:a.w.height,kind:c,encrypted:0<b.drmInfos.length,keyId:h,language:d,label:e,
- type:a.S.contentType,primary:f,trickModeVideo:null,containsEmsgBoxes:a.w.containsEmsgBoxes,roles:g}};k.he=function(){this.f=null;var a=Date.now();Id(this).then(function(){this.a&&Jd(this,(Date.now()-a)/1E3)}.bind(this))["catch"](function(a){this.a&&(a.severity=1,this.a.onError(a),Jd(this,0))}.bind(this))};function Jd(a,b){0>a.l||(a.f=window.setTimeout(a.he.bind(a),1E3*Math.max(Math.max(3,a.l)-b,0)))}
- function Od(a,b,c){b=b||{contentType:"",mimeType:"",codecs:"",containsEmsgBoxes:!1,frameRate:void 0};c=c||b.U;var d=M(a,"BaseURL").map(Ic),e=a.getAttribute("contentType")||b.contentType,f=a.getAttribute("mimeType")||b.mimeType,g=a.getAttribute("codecs")||b.codecs,h=N(a,"frameRate",Pc)||b.frameRate,l=!!M(a,"InbandEventStream").length;e||(e=Rd(f,g));return{U:z(c,d),Qa:Hc(a,"SegmentBase")||b.Qa,oa:Hc(a,"SegmentList")||b.oa,Ra:Hc(a,"SegmentTemplate")||b.Ra,width:N(a,"width",Oc)||b.width,height:N(a,"height",
- Oc)||b.height,contentType:e,mimeType:f,codecs:g,frameRate:h,containsEmsgBoxes:l||b.containsEmsgBoxes,id:a.getAttribute("id")}}function Sd(a){var b=0+(a.Qa?1:0);b+=a.oa?1:0;b+=a.Ra?1:0;if(!b)return"text"==a.contentType||"application"==a.contentType?!0:!1;1!=b&&(a.Qa&&(a.oa=null),a.Ra=null);return!0}
- function Td(a,b,c,d){b=z(b,[c]);b=C(b,a.b.retryParameters);b.method=d;return a.a.networkingEngine.request(0,b).then(function(a){if("HEAD"==d){if(!a.headers||!a.headers.date)return 0;a=a.headers.date}else a=F(a.data);a=Date.parse(a);return isNaN(a)?0:a-Date.now()})}
- function Md(a,b,c,d){c=c.map(function(a){return{scheme:a.getAttribute("schemeIdUri"),value:a.getAttribute("value")}});var e=a.b.dash.clockSyncUri;d&&!c.length&&e&&c.push({scheme:"urn:mpeg:dash:utc:http-head:2014",value:e});return xa(c,function(a){var c=a.value;switch(a.scheme){case "urn:mpeg:dash:utc:http-head:2014":case "urn:mpeg:dash:utc:http-head:2012":return Td(this,b,c,"HEAD");case "urn:mpeg:dash:utc:http-xsdate:2014":case "urn:mpeg:dash:utc:http-iso:2014":case "urn:mpeg:dash:utc:http-xsdate:2012":case "urn:mpeg:dash:utc:http-iso:2012":return Td(this,
- b,c,"GET");case "urn:mpeg:dash:utc:direct:2014":case "urn:mpeg:dash:utc:direct:2012":return a=Date.parse(c),isNaN(a)?0:a-Date.now();case "urn:mpeg:dash:utc:http-ntp:2014":case "urn:mpeg:dash:utc:ntp:2014":case "urn:mpeg:dash:utc:sntp:2014":return Promise.reject();default:return Promise.reject()}}.bind(a))["catch"](function(){return 0})}
- k.Fd=function(a,b,c){var d=c.getAttribute("schemeIdUri")||"",e=c.getAttribute("value")||"",f=N(c,"timescale",Oc)||1;M(c,"Event").forEach(function(c){var g=N(c,"presentationTime",Oc)||0,l=N(c,"duration",Oc)||0,g=g/f+a,l=g+l/f;null!=b&&(g=Math.min(g,a+b),l=Math.min(l,a+b));c={schemeIdUri:d,value:e,startTime:g,endTime:l,id:c.getAttribute("id")||"",eventElement:c};this.a.onTimelineRegionAdded(c)}.bind(this))};
- k.Qd=function(a,b,c){a=C(a,this.b.retryParameters);null!=b&&(a.headers.Range="bytes="+b+"-"+(null!=c?c:""));return this.a.networkingEngine.request(1,a).then(function(a){return a.data})};function Rd(a,b){return ub[Yb(a,b)]?"text":a.split("/")[0]}Ed.mpd=Hd;Dd["application/dash+xml"]=Hd;function Ud(a,b,c,d){this.uri=a;this.type=b;this.ga=c;this.segments=d||null}function Vd(a,b,c,d){this.id=a;this.name=b;this.a=c;this.value=d||null}Vd.prototype.toString=function(){function a(a){return a.name+'="'+a.value+'"'}return this.value?"#"+this.name+":"+this.value:0<this.a.length?"#"+this.name+":"+this.a.map(a).join(","):"#"+this.name};function Wd(a,b){this.name=a;this.value=b}Vd.prototype.getAttribute=function(a){var b=this.a.filter(function(b){return b.name==a});return b.length?b[0]:null};
- function Xd(a,b,c){c=c||null;return(a=a.getAttribute(b))?a.value:c}function Yd(a,b){this.ga=b;this.uri=a};function Zd(a,b){return a.filter(function(a){return a.name==b})}function $d(a,b){var c=Zd(a,b);return c.length?c[0]:null}function ae(a,b,c){return a.filter(function(a){var d=a.getAttribute("TYPE");a=a.getAttribute("GROUP-ID");return d.value==b&&a.value==c})};function be(a){this.b=a;this.a=0}function ce(a,b){b.lastIndex=a.a;var c=(c=b.exec(a.b))?{position:c.index,length:c[0].length,Sd:c}:null;if(a.a==a.b.length||!c||c.position!=a.a)return null;a.a+=c.length;return c.Sd}function de(a){return a.a==a.b.length?null:(a=ce(a,/[^ \t\n]*/gm))?a[0]:null};function ee(){this.a=0}
- function fe(a,b,c){b=F(b);b=b.replace(/\r\n|\r(?=[^\n]|$)/gm,"\n").trim();var d=b.split(/\n+/m);if(!/^#EXTM3U($|[ \t\n])/m.test(d[0]))throw new t(2,4,4015);b=0;for(var e=[],f=1;f<d.length;)if(/^#(?!EXT)/m.test(d[f]))f+=1;else{var g=d[f];g=ge(a.a++,g);if(0<=he.indexOf(g.name))b=1;else if(0<=ie.indexOf(g.name)){if(1!=b)throw new t(2,4,4017);d=d.splice(f,d.length-f);a=je(a,d);return new Ud(c,b,e,a)}e.push(g);f+=1;"EXT-X-STREAM-INF"==g.name&&(g.a.push(new Wd("URI",d[f])),f+=1)}return new Ud(c,b,e)}
- function je(a,b){var c=[],d=[];b.forEach(function(a){/^(#EXT)/.test(a)?(a=ge(this.a++,a),d.push(a)):/^#(?!EXT)/m.test(a)||(c.push(new Yd(a.trim(),d)),d=[])}.bind(a));return c}function ge(a,b){var c=b.match(/^#(EXT[^:]*)(?::(.*))?$/);if(!c)throw new t(2,4,4016);var d=c[1],e=c[2],c=[];if(e&&0<=e.indexOf("="))for(var e=new be(e),f,g=/([^=]+)=(?:"([^"]*)"|([^",]*))(?:,|$)/g;f=ce(e,g);)c.push(new Wd(f[1],f[2]||f[3]));else if(e)return new Vd(a,d,c,e);return new Vd(a,d,c)}
- var he="EXT-X-TARGETDURATION EXT-X-MEDIA-SEQUENCE EXT-X-DISCONTINUITY-SEQUENCE EXT-X-PLAYLIST-TYPE EXT-X-MAP EXT-X-I-FRAMES-ONLY".split(" "),ie="EXTINF EXT-X-BYTERANGE EXT-X-DISCONTINUITY EXT-X-PROGRAM-DATE-TIME EXT-X-KEY EXT-X-DATERANGE".split(" ");function ke(a){return new Promise(function(b){var c=ke.parse(a);b({uri:a,data:c.data,headers:{"content-type":c.contentType}})})}n("shaka.net.DataUriPlugin",ke);
- ke.parse=function(a){var b=a.split(":");if(2>b.length||"data"!=b[0])throw new t(2,1,1004,a);b=b.slice(1).join(":").split(",");if(2>b.length)throw new t(2,1,1004,a);var c=b[0],b=window.decodeURIComponent(b.slice(1).join(",")),c=c.split(";"),d=null;1<c.length&&(d=c[1]);if("base64"==d)a=Ya(b).buffer;else{if(d)throw new t(2,1,1005,a);a=Ua(b)}return{data:a,contentType:c[0]}};Ea.data=ke;function le(){this.b=this.c=null;this.i=1;this.g={};this.f={};this.a=null;this.j="";this.h=new ee}n("shaka.hls.HlsParser",le);k=le.prototype;k.configure=function(a){this.b=a};k.start=function(a,b){this.c=b;this.j=a;return this.c.networkingEngine.request(0,C([a],this.b.retryParameters)).then(function(b){return ne(this,b.data,a)}.bind(this))};k.stop=function(){this.b=this.c=null;this.g={};return Promise.resolve()};k.update=function(){};k.onExpirationUpdated=function(){};
- function ne(a,b,c){b=fe(a.h,b,c);if(0!=b.type)throw new t(2,4,4022);a.a=new T(null,0);return oe(a,b).then(function(a){this.c.filterPeriod(a);return{presentationTimeline:this.a,periods:[a],offlineSessionIds:[],minBufferTime:0}}.bind(a))}
- function oe(a,b){var c=Zd(b.ga,"EXT-X-STREAM-INF").map(function(a){return pe(this,a,b)}.bind(a)),d=Zd(b.ga,"EXT-X-MEDIA").filter(function(a){return"SUBTITLES"==U(a,"TYPE")}.bind(a)).map(function(a){return qe(this,a,b)}.bind(a));return Promise.all(c).then(function(a){return Promise.all(d).then(function(b){var c=a.reduce(x,[]);re(this,c);return{startTime:0,variants:c,textStreams:b}}.bind(this))}.bind(a))}
- function pe(a,b,c){var d=Number(U(b,"BANDWIDTH")),e=Xd(b,"CODECS","avc1.42E01E,mp4a.40.2").split(","),f=b.getAttribute("RESOLUTION"),g=null,h=null,l=Xd(b,"FRAME-RATE");if(f)var m=f.value.split("x"),g=m[0],h=m[1];var q=se(a,c);c=Zd(c.ga,"EXT-X-MEDIA");var r=Xd(b,"AUDIO"),v=Xd(b,"VIDEO");r?c=ae(c,"AUDIO",r):v&&(c=ae(c,"VIDEO",v));c=c.map(function(a){return te(this,a,e,q)}.bind(a));var u=[],w=[];return Promise.all(c).then(function(a){r?u=a:v&&(w=a);if(u.length||w.length)var c=u.length?"video":"audio";
- else 1==e.length?c=f||l?"video":"audio":(c="video",e=[e.join(",")]);a=e;var d=U(b,"URI");return ue(this,d,a,c,q,"und",!1,null)}.bind(a)).then(function(a){"audio"==a.stream.type?u=[a]:w=[a];return ve(this,u,w,d,g,h,l)}.bind(a))}
- function ve(a,b,c,d,e,f,g){c.forEach(function(a){if(a=a.stream)a.width=Number(e)||void 0,a.height=Number(f)||void 0,a.frameRate=Number(g)||void 0}.bind(a));b.length||(b=[null]);c.length||(c=[null]);for(var h=[],l=0;l<b.length;l++)for(var m=0;m<c.length;m++){var q=b[l]?b[l].stream:null,r=c[m]?c[m].stream:null,v=b[l]?b[l].drmInfos:null,u=c[m]?c[m].drmInfos:null;if(q&&r)if(v.length&&u.length?0<sb(v,u).length:1)var w=sb(v,u);else continue;else q?w=v:r&&(w=u);h.push(xe(a,q,r,d,w))}return h}
- function xe(a,b,c,d,e){return{id:a.i++,language:b?b.language:"und",primary:!!b&&b.primary||!!c&&c.primary,audio:b,video:c,bandwidth:d,drmInfos:e,allowedByApplication:!0,allowedByKeySystem:!0}}function qe(a,b,c){U(b,"TYPE");c=se(a,c);return te(a,b,[],c).then(function(a){return a.stream})}
- function te(a,b,c,d){if(a.g[b.id])return Promise.resolve().then(function(){return this.g[b.id]}.bind(a));var e=U(b,"TYPE").toLowerCase();"subtitles"==e&&(e="text");var f=Sb(Xd(b,"LANGUAGE","und")),g=Xd(b,"NAME"),h=b.getAttribute("DEFAULT"),l=b.getAttribute("AUTOSELECT"),m=U(b,"URI");return ue(a,m,c,e,d,f,!!h||!!l,g).then(function(a){return this.g[b.id]=a}.bind(a))}
- function ue(a,b,c,d,e,f,g,h){b=z([a.j],[b])[0];return a.c.networkingEngine.request(0,C([b],a.b.retryParameters)).then(function(a){a=fe(this.h,a.data,a.uri);if(1!=a.type)throw new t(2,4,4017);e=se(this,a)||e;var b=null;"text"!=d&&(b=ye(a));var l=$d(a.ga,"EXT-X-MEDIA-SEQUENCE"),l=ze(this,a,l?Number(l.value):0);this.a.Ha(0,l);var r=l[l.length-1].endTime-l[0].startTime,v=this.a.Y();(Infinity==v||v<r)&&this.a.pa(r);var u=Ae(d,c),w=void 0;"text"==d&&(w="subtitle");var G=new S(l),pa=[];a.segments.forEach(function(a){a=
- Zd(a.ga,"EXT-X-KEY");pa.push.apply(pa,a)});var Hb=!1,tc=[],me=null;pa.forEach(function(a){if("NONE"!=U(a,"METHOD")){Hb=!0;var b=U(a,"KEYFORMAT");if(a=(b=Be[b])?b(a):null)a.keyIds.length&&(me=a.keyIds[0]),tc.push(a)}});if(Hb&&!tc.length)throw new t(2,4,4026);return Ce(this,d,l[0].a()[0]).then(function(a){a={id:this.i++,createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:G.find.bind(G),getSegmentReference:G.get.bind(G),initSegmentReference:b,presentationTimeOffset:e||0,mimeType:a,codecs:u,
- kind:w,encrypted:Hb,keyId:me,language:f,label:h||null,type:d,primary:g,trickModeVideo:null,containsEmsgBoxes:!1,frameRate:void 0,width:void 0,height:void 0,bandwidth:void 0,roles:[]};this.f[a.id]=G;return{stream:a,Ae:G,drmInfos:tc}}.bind(this))}.bind(a))}
- function ye(a){var b=Zd(a.ga,"EXT-X-MAP");if(!b.length)return null;if(1<b.length)throw new t(2,4,4020);var b=b[0],c=U(b,"URI"),d=z([a.uri],[c])[0];a=0;c=null;if(b=Xd(b,"BYTERANGE"))a=b.split("@"),b=Number(a[0]),a=Number(a[1]),c=a+b-1;return new Zc(function(){return[d]},a,c)}
- function ze(a,b,c){var d=b.segments,e=[];d.forEach(function(a){var f=a.ga,h=z([b.uri],[a.uri])[0],l=De(f).value.split(","),l=Number(l[0]),m;(a=d.indexOf(a))?m=e[a-1].endTime:m=0;var l=m+l,q=0,r=null;if(f=$d(f,"EXT-X-BYTERANGE"))f=f.value.split("@"),r=Number(f[0]),f[1]?q=Number(f[1]):q=e[a-1].M,r=q+r-1,a==d.length-1&&(r=null);e.push(new O(c+a,m,l,function(){return[h]},q,r))}.bind(a));return e}
- function re(a,b){b.forEach(function(a){var b=this.a.Y(),c=a.video;a=a.audio;c&&this.f[c.id]&&gd(this.f[c.id],b);a&&this.f[a.id]&&gd(this.f[a.id],b)}.bind(a))}function Ae(a,b){if(1==b.length)return b[0];if("text"==a)return"";var c=Ee;"audio"==a&&(c=Fe);for(var d=0;d<c.length;d++)for(var e=0;e<b.length;e++)if(c[d].test(b[e].trim()))return b[e].trim();throw new t(2,4,4025,b);}
- function Ce(a,b,c){var d=c.split("."),e=d[d.length-1];if("text"==b)return Promise.resolve("text/vtt");d=Ge;"video"==b&&(d=He);if(b=d[e])return Promise.resolve(b);c=C([c],a.b.retryParameters);c.method="HEAD";return a.c.networkingEngine.request(1,c).then(function(a){a=a.headers["content-type"];if(!a)throw new t(2,4,4021,e);return a})}function se(a,b){var c=$d(b.ga,"EXT-X-START");return c?Number(U(c,"TIME-OFFSET")):a.b.hls.defaultTimeOffset}
- function U(a,b){var c=a.getAttribute(b);if(!c)throw new t(2,4,4023,b);return c.value}function De(a){a=$d(a,"EXTINF");if(!a)throw new t(2,4,4024,"EXTINF");return a}
- var Ee=[/^(avc)/,/^(hvc)/,/^(vp[8-9])$/,/^(av1)$/,/^(mp4v)/],Fe=[/^(vorbis)/,/^(opus)/,/^(mp4a)/,/^(ac-3)$/,/^(ec-3)$/],Ge={mp4:"audio/mp4",m4s:"audio/mp4",m4i:"audio/mp4",m4a:"audio/mp4",ts:"video/mp2t"},He={mp4:"video/mp4",m4s:"video/mp4",m4i:"video/mp4",m4v:"video/mp4",ts:"video/mp2t"},Be={"urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":function(a){if("SAMPLE-AES-CENC"!=U(a,"METHOD"))return null;var b=U(a,"URI"),b=ke.parse(b),b=new Uint8Array(b.data),b=Ba("com.widevine.alpha",[{initDataType:"cenc",
- initData:b}]);if(a=Xd(a,"KEYID"))b.keyIds=[a.substr(2).toLowerCase()];return b}};Ed.m3u8=le;Dd["application/x-mpegurl"]=le;Dd["application/vnd.apple.mpegurl"]=le;function Ie(){}Ie.prototype.parseInit=function(){};
- Ie.prototype.parseMedia=function(a,b){var c=F(a),d=[],e=new DOMParser,f=null;try{f=e.parseFromString(c,"text/xml")}catch(Hb){throw new t(2,2,2005);}if(f){var g=f.getElementsByTagName("tt")[0];if(g){e=g.getAttribute("ttp:frameRate");f=g.getAttribute("ttp:subFrameRate");var h=g.getAttribute("ttp:frameRateMultiplier");var l=g.getAttribute("ttp:tickRate");c=g.getAttribute("xml:space")||"default"}else throw new t(2,2,2005);if("default"!=c&&"preserve"!=c)throw new t(2,2,2005);c="default"==c;e=new Je(e,
- f,h,l);f=Ke(g.getElementsByTagName("styling")[0]);h=Ke(g.getElementsByTagName("layout")[0]);g=Ke(g.getElementsByTagName("body")[0]);for(l=0;l<g.length;l++){var m=g[l],q=b.periodStart,r=e;var v=f;var u=h,w=c;if(m.hasAttribute("begin")||m.hasAttribute("end")||!/^\s*$/.test(m.textContent)){Le(m,w);var w=Me(m.getAttribute("begin"),r),G=Me(m.getAttribute("end"),r),r=Me(m.getAttribute("dur"),r),pa=m.textContent;null==G&&null!=r&&(G=w+r);if(null==w||null==G)throw new t(2,2,2001);if(q=xb(w+q,G+q,pa)){w=Ne(m,
- "region",u);u=q;if(G=Oe(m,w,v,"tts:extent"))if(r=Pe.exec(G))u.size=Number(r[1]);r=Oe(m,w,v,"tts:writingMode");G=!0;"tb"==r||"tblr"==r?u.vertical="lr":"tbrl"==r?u.vertical="rl":G=!1;if(r=Oe(m,w,v,"tts:origin"))if(r=Pe.exec(r))G?(u.position=Number(r[2]),u.line=Number(r[1])):(u.position=Number(r[1]),u.line=Number(r[2])),u.snapToLines=!1;if(v=Oe(m,w,v,"tts:textAlign"))u.align=v,"center"==v&&("center"!=u.align&&(u.align="middle"),u.position="auto"),u.positionAlign=Qe[v],u.lineAlign=Re[v];v=q}else v=null}else v=
- null;v&&d.push(v)}}return d};var Se=/^(\d{2,}):(\d{2}):(\d{2}):(\d{2})\.?(\d+)?$/,Te=/^(?:(\d{2,}):)?(\d{2}):(\d{2})$/,Ue=/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{2,})$/,Ve=/^(\d*\.?\d*)f$/,We=/^(\d*\.?\d*)t$/,Xe=/^(?:(\d*\.?\d*)h)?(?:(\d*\.?\d*)m)?(?:(\d*\.?\d*)s)?(?:(\d*\.?\d*)ms)?$/,Pe=/^(\d{1,2}|100)% (\d{1,2}|100)%$/,Re={left:"start",center:"center",right:"end",start:"start",end:"end"},Qe={left:"line-left",center:"center",right:"line-right"};
- function Ke(a){var b=[];if(!a)return b;for(var c=a.childNodes,d=0;d<c.length;d++){var e="span"==c[d].nodeName&&"p"==a.nodeName;c[d].nodeType!=Node.ELEMENT_NODE||"br"==c[d].nodeName||e||(e=Ke(c[d]),b=b.concat(e))}b.length||b.push(a);return b}function Le(a,b){for(var c=a.childNodes,d=0;d<c.length;d++)if("br"==c[d].nodeName&&0<d)c[d-1].textContent+="\n";else if(0<c[d].childNodes.length)Le(c[d],b);else if(b){var e=c[d].textContent.trim(),e=e.replace(/\s+/g," ");c[d].textContent=e}}
- function Oe(a,b,c,d){for(var e=Ke(b),f=0;f<e.length;f++){var g=e[f].getAttribute(d);if(g)return g}e=Ne;return(a=e(b,"style",c)||e(a,"style",c))?a.getAttribute(d):null}function Ne(a,b,c){if(!a||1>c.length)return null;var d=null,e=a;for(a=null;e&&!(a=e.getAttribute(b))&&(e=e.parentNode,e instanceof Element););if(b=a)for(a=0;a<c.length;a++)if(c[a].getAttribute("xml:id")==b){d=c[a];break}return d}
- function Me(a,b){var c=null;if(Se.test(a))var c=Se.exec(a),d=Number(c[1]),e=Number(c[2]),f=Number(c[3]),g=Number(c[4]),g=g+(Number(c[5])||0)/b.b,f=f+g/b.frameRate,c=f+60*e+3600*d;else Te.test(a)?c=Ye(Te,a):Ue.test(a)?c=Ye(Ue,a):Ve.test(a)?(c=Ve.exec(a),c=Number(c[1])/b.frameRate):We.test(a)?(c=We.exec(a),c=Number(c[1])/b.a):Xe.test(a)&&(c=Ye(Xe,a));return c}
- function Ye(a,b){var c=a.exec(b);return c&&""!=c[0]?(Number(c[4])||0)/1E3+(Number(c[3])||0)+60*(Number(c[2])||0)+3600*(Number(c[1])||0):null}function Je(a,b,c,d){this.frameRate=Number(a)||30;this.b=Number(b)||1;this.a=Number(d);this.a||(this.a=a?this.frameRate*this.b:1);c&&(a=/^(\d+) (\d+)$/g.exec(c))&&(this.frameRate*=a[1]/a[2])}vb("application/ttml+xml",Ie);function Ze(){this.a=new Ie}Ze.prototype.parseInit=function(a){var b=!1;(new Q).C("moov",R).C("trak",R).C("mdia",R).C("minf",R).C("stbl",R).da("stsd",cd).C("stpp",function(){b=!0}).parse(a);if(!b)throw new t(2,2,2007);};Ze.prototype.parseMedia=function(a,b){var c=!1,d=[];(new Q).C("mdat",dd(function(a){c=!0;d=this.a.parseMedia(a.buffer,b)}.bind(this))).parse(a);if(!c)throw new t(2,2,2007);return d};vb('application/mp4; codecs="stpp"',Ze);function $e(){}$e.prototype.parseInit=function(){};
- $e.prototype.parseMedia=function(a,b){var c=F(a),c=c.replace(/\r\n|\r(?=[^\n]|$)/gm,"\n"),c=c.split(/\n{2,}/m);if(!/^WEBVTT($|[ \t\n])/m.test(c[0]))throw new t(2,2,2E3);var d=b.segmentStart;if(0<=c[0].indexOf("X-TIMESTAMP-MAP")){var e=c[0].match(/LOCAL:((?:(\d{1,}):)?(\d{2}):(\d{2})\.(\d{3}))/m),f=c[0].match(/MPEGTS:(\d+)/m);e&&f&&(d=af(new be(e[1])),d=b.periodStart+(Number(f[1])/9E4-d))}f=[];for(e=1;e<c.length;e++){var g=c[e].split("\n"),h=d;if(1==g.length&&!g[0]||/^NOTE($|[ \t])/.test(g[0]))var l=
- null;else{l=null;0>g[0].indexOf("--\x3e")&&(l=g[0],g.splice(0,1));var m=new be(g[0]),q=af(m),r=ce(m,/[ \t]+--\x3e[ \t]+/g),v=af(m);if(null==q||!r||null==v)throw new t(2,2,2001);if(g=xb(q+h,v+h,g.slice(1).join("\n").trim())){ce(m,/[ \t]+/gm);for(h=de(m);h;)bf(g,h),ce(m,/[ \t]+/gm),h=de(m);null!=l&&(g.id=l);l=g}else l=null}l&&f.push(l)}return f};
- function bf(a,b){var c;if(c=/^align:(start|middle|center|end|left|right)$/.exec(b))a.align=c[1],"center"==c[1]&&"center"!=a.align&&(a.position="auto",a.align="middle");else if(c=/^vertical:(lr|rl)$/.exec(b))a.vertical=c[1];else if(c=/^size:(\d{1,2}|100)%$/.exec(b))a.size=Number(c[1]);else if(c=/^position:(\d{1,2}|100)%(?:,(line-left|line-right|center|start|end))?$/.exec(b))a.position=Number(c[1]),c[2]&&(a.positionAlign=c[2]);else if(c=/^line:(\d{1,2}|100)%(?:,(start|end|center))?$/.exec(b))a.snapToLines=
- !1,a.line=Number(c[1]),c[2]&&(a.lineAlign=c[2]);else if(c=/^line:(-?\d+)(?:,(start|end|center))?$/.exec(b))a.snapToLines=!0,a.line=Number(c[1]),c[2]&&(a.lineAlign=c[2])}function af(a){a=ce(a,/(?:(\d{1,}):)?(\d{2}):(\d{2})\.(\d{3})/g);if(!a)return null;var b=Number(a[2]),c=Number(a[3]);return 59<b||59<c?null:Number(a[4])/1E3+c+60*b+3600*(Number(a[1])||0)}vb("text/vtt",$e);vb('text/vtt; codecs="vtt"',$e);function cf(){this.a=null}cf.prototype.parseInit=function(a){var b=!1;(new Q).C("moov",R).C("trak",R).C("mdia",R).da("mdhd",function(a){0==a.version?(a.s.I(4),a.s.I(4),this.a=a.s.D(),a.s.I(4)):(a.s.I(8),a.s.I(8),this.a=a.s.D(),a.s.I(8));a.s.I(4)}.bind(this)).C("minf",R).C("stbl",R).da("stsd",cd).C("wvtt",function(){b=!0}).parse(a);if(!this.a)throw new t(2,2,2008);if(!b)throw new t(2,2,2008);};
- cf.prototype.parseMedia=function(a,b){var c=0,d=[],e=[],f=[],g=!1,h=!1,l=!1;(new Q).C("moof",R).C("traf",R).da("tfdt",function(a){g=!0;c=a.version?a.s.Pa():a.s.D()}).da("trun",function(a){h=!0;var b=a.version,c=a.Nc;a=a.s;var e=a.D();c&1&&a.I(4);c&4&&a.I(4);for(var f=[],g=0;g<e;g++){var l={duration:null,Nb:null};c&256&&(l.duration=a.D());c&512&&a.I(4);c&1024&&a.I(4);c&2048&&(l.Nb=b?a.nc():a.D());f.push(l)}d=f}).C("vtte",function(){e.push(null)}).C("vttc",dd(function(a){e.push(a.buffer)})).C("mdat",
- function(a){l=!0;R(a)}).parse(a);if(!l&&!g&&!h)throw new t(2,2,2008);for(var m=c,q=0;q<d.length;q++){var r=d[q],v=e[q];if(r.duration){var u=r.Nb?c+r.Nb:m,m=u+r.duration;v&&f.push(df(v,b.periodStart+u/this.a,b.periodStart+m/this.a))}}return f};function df(a,b,c){var d,e,f;(new Q).C("payl",dd(function(a){d=F(a)})).C("iden",dd(function(a){e=F(a)})).C("sttg",dd(function(a){f=F(a)})).parse(a);return d?ef(d,e,f,b,c):null}
- function ef(a,b,c,d,e){(a=xb(d,e,a))&&b&&(a.id=b);if(a&&c)for(b=new be(c),c=de(b);c;)bf(a,c),ce(b,/[ \t]+/gm),c=de(b);return a}vb('application/mp4; codecs="wvtt"',cf);function ff(a,b,c,d,e,f){this.a=a;this.c=b;this.l=c;this.A=d;this.J=e;this.G=f;this.b=new D;this.h=!1;this.g=1;this.j=this.f=null;this.B=a.readyState;this.i=!1;this.O=this.v=-1;this.o=!1;0<a.readyState?this.fc():La(this.b,a,"loadedmetadata",this.fc.bind(this));b=this.hc.bind(this);E(this.b,a,"ratechange",this.rd.bind(this));E(this.b,a,"waiting",b);this.j=setInterval(b,250)}k=ff.prototype;
- k.m=function(){var a=this.b.m();this.b=null;null!=this.f&&(window.clearInterval(this.f),this.f=null);null!=this.j&&(window.clearInterval(this.j),this.j=null);this.G=this.J=this.l=this.c=this.a=null;return a};function gf(a,b){0<a.a.readyState?a.a.currentTime=hf(a,b):a.A=b}function jf(a){return 0<a.a.readyState?hf(a,a.a.currentTime):kf(a)}function kf(a){if(a.A)return hf(a,a.A);a=a.c.presentationTimeline;return Infinity>a.Y()?a.ma():a.bb()}k.rb=function(){return this.g};
- function lf(a,b){null!=a.f&&(window.clearInterval(a.f),a.f=null);a.g=b;a.a.playbackRate=a.h||0>b?0:b;!a.h&&0>b&&(a.f=window.setInterval(function(){this.a.currentTime+=b/4}.bind(a),250))}k.Ab=function(){this.o=!0;this.hc()};k.rd=function(){this.a.playbackRate!=(this.h||0>this.g?0:this.g)&&lf(this,this.a.playbackRate)};
- k.fc=function(){var a=kf(this);.001>Math.abs(this.a.currentTime-a)?(E(this.b,this.a,"seeking",this.ic.bind(this)),E(this.b,this.a,"playing",this.gc.bind(this))):(La(this.b,this.a,"seeking",this.td.bind(this)),this.a.currentTime=a)};k.td=function(){E(this.b,this.a,"seeking",this.ic.bind(this));E(this.b,this.a,"playing",this.gc.bind(this))};
- k.hc=function(){if(this.a.readyState){this.a.readyState!=this.B&&(this.i=!1,this.B=this.a.readyState);var a=this.l.smallGapLimit,b=this.a.currentTime,c=this.a.buffered;a:{if(c&&c.length&&!(1==c.length&&1E-6>c.end(0)-c.start(0))){var d=.1;/(Edge|Trident)\//.test(navigator.userAgent)&&(d=.5);for(var e=0;e<c.length;e++)if(c.start(e)>b&&(!e||c.end(e-1)-b<=d)){d=e;break a}}d=null}if(null==d){if(3>this.a.readyState&&0<this.a.playbackRate)if(this.O!=b)this.O=b,this.v=Date.now();else if(this.v<Date.now()-
- 1E3)for(this.v=Date.now()+5E3,d=0;d<c.length;d++)if(b>=c.start(d)&&b<c.end(d)-.5){this.a.currentTime=this.a.currentTime;break}}else if(d||this.o)if(e=c.start(d),!(e>=this.c.presentationTimeline.bb())){var f=e-b,a=f<=a,g=!1;a||this.i||(this.i=!0,f=new I("largegap",{currentTime:b,gapSize:f}),f.cancelable=!0,this.G(f),this.l.jumpLargeGaps&&!f.defaultPrevented&&(g=!0));if(a||g)d&&c.end(d-1),mf(this,b,e)}}};
- k.ic=function(){this.o=!1;var a=this.a.currentTime,b=nf(this,a);.001<Math.abs(b-a)?mf(this,a,b):(this.i=!1,this.J())};k.gc=function(){var a=this.a.currentTime,b=nf(this,a);.001<Math.abs(b-a)&&mf(this,a,b)};function nf(a,b){var c=Bb.bind(null,a.a.buffered),d=1*Math.max(a.c.minBufferTime||0,a.l.rebufferingGoal),e=a.c.presentationTimeline,f=e.ua(),g=e.Ea(d),h=e.Ea(5),d=e.Ea(d+5);return b>f?f:b<e.Ea(0)?c(h)?h:d:b>=g||c(b)?b:d}
- function mf(a,b,c){a.a.currentTime=c;var d=0,e=function(){!this.a||10<=d++||this.a.currentTime!=b||(this.a.currentTime=c,setTimeout(e,100))}.bind(a);setTimeout(e,100)}function hf(a,b){var c=a.c.presentationTimeline.ma();if(b<c)return c;c=a.c.presentationTimeline.ua();return b>c?c:b};function of(a,b,c,d,e,f){this.a=a;this.g=b;this.A=c;this.l=d;this.h=e;this.B=f;this.c=[];this.j=new D;this.b=!1;this.i=-1;this.f=null;pf(this)}of.prototype.m=function(){var a=this.j?this.j.m():Promise.resolve();this.j=null;qf(this);this.B=this.h=this.l=this.A=this.g=this.a=null;this.c=[];return a};
- of.prototype.v=function(a){if(!this.c.some(function(b){return b.info.schemeIdUri==a.schemeIdUri&&b.info.startTime==a.startTime&&b.info.endTime==a.endTime})){var b={info:a,status:1};this.c.push(b);var c=new I("timelineregionadded",{detail:rf(a)});this.h(c);this.o(!0,b)}};function rf(a){var b=Da(a);b.eventElement=a.eventElement;return b}
- of.prototype.o=function(a,b){var c=b.info.startTime>this.a.currentTime?1:b.info.endTime<this.a.currentTime?3:2,d=2==b.status,e=2==c;if(c!=b.status){if(!a||d||e)d||this.h(new I("timelineregionenter",{detail:rf(b.info)})),e||this.h(new I("timelineregionexit",{detail:rf(b.info)}));b.status=c}};function pf(a){qf(a);a.f=window.setTimeout(a.G.bind(a),250)}function qf(a){a.f&&(window.clearTimeout(a.f),a.f=null)}
- of.prototype.G=function(){this.f=null;pf(this);var a=hc(this.g,this.a.currentTime);a!=this.i&&(-1!=this.i&&this.B(),this.i=a);var a=Cb(this.a.buffered,this.a.currentTime),b=Ab(this.a.buffered)>=this.g.presentationTimeline.ua()-.1||this.a.ended;if(this.b){var c=1*Math.max(this.g.minBufferTime||0,this.A.rebufferingGoal);(b||a>=c)&&0!=this.b&&(this.b=!1,this.l(!1))}else!b&&.5>a&&1!=this.b&&(this.b=!0,this.l(!0));this.c.forEach(this.o.bind(this,!1))};function sf(a,b){this.a=b;this.b=a;this.g=null;this.i=1;this.o=Promise.resolve();this.h=[];this.j={};this.c={};this.f=this.l=this.v=!1}k=sf.prototype;k.m=function(){for(var a in this.c)tf(this.c[a]);this.g=this.c=this.j=this.h=this.o=this.b=this.a=null;this.f=!0;return Promise.resolve()};k.configure=function(a){this.g=a};k.init=function(){var a=this.a.bc(this.b.periods[hc(this.b,jf(this.a.Oa))]);return Ma(a)?Promise.reject(new t(2,5,5005)):uf(this,a).then(function(){this.a&&this.a.jd&&this.a.jd()}.bind(this))};
- function V(a){return a.b.periods[hc(a.b,jf(a.a.Oa))]}function vf(a){return Oa(a.c,function(a){return a.na||a.stream})}function wf(a,b){var c={};c.text=b;return uf(a,c)}function xf(a,b){var c=a.c.video;if(c){var d=c.stream;if(d)if(b){var e=d.trickModeVideo;if(e){var f=c.na;f||(yf(a,"video",e,!1),c.na=d)}}else if(f=c.na)c.na=null,yf(a,"video",f,!0)}}
- function yf(a,b,c,d){var e=a.c[b];if(!e&&"text"==b&&a.g.ignoreTextStreamFailures)wf(a,c);else if(e){var f=ic(a.b,c);d&&f!=e.wa?zf(a):(e.na&&(c.trickModeVideo?(e.na=c,c=c.trickModeVideo):e.na=null),"text"==b&&Fb(a.a.K,Yb(c.mimeType,c.codecs)),(b=a.h[f])&&b.La&&(b=a.j[c.id])&&b.La&&e.stream!=c&&(e.stream=c,e.cb=!0,d&&(e.sa?e.kb=!0:e.xa?(e.ra=!0,e.kb=!0):(tf(e),Af(a,e,!0)))))}}
- function Bf(a){var b=jf(a.a.Oa);Object.keys(a.c).every(function(a){var c=this.a.K;"text"==a?(a=c.a,a=b>=a.b&&b<a.a):(a=Ib(c,a),a=Bb(a,b));return a}.bind(a))||zf(a)}function zf(a){for(var b in a.c){var c=a.c[b];c.sa||c.ra||(c.xa?c.ra=!0:null==Gb(a.a.K,b)?null==c.qa&&Cf(a,c,0):(tf(c),Af(a,c,!1)))}}
- function uf(a,b,c){var d=hc(a.b,jf(a.a.Oa)),e=Oa(b,function(a){return Yb(a.mimeType,a.codecs)});a.a.K.init(e);Df(a);e=Na(b);return Ef(a,e).then(function(){if(!this.f)for(var a in b){var e=b[a];this.c[a]||(this.c[a]={stream:e,type:a,Fa:null,ea:null,na:null,cb:!0,wa:d,endOfStream:!1,xa:!1,qa:null,ra:!1,kb:!1,sa:!1,Gb:!1,tb:!1,rc:c||0},Cf(this,this.c[a],0))}}.bind(a))}
- function Ff(a,b){var c=a.h[b];if(c)return c.L;c={L:new A,La:!1};a.h[b]=c;var d=a.b.periods[b].variants.map(function(a){var b=[];a.audio&&b.push(a.audio);a.video&&b.push(a.video);a.video&&a.video.trickModeVideo&&b.push(a.video.trickModeVideo);return b}).reduce(x,[]).filter(Aa);d.push.apply(d,a.b.periods[b].textStreams);a.o=a.o.then(function(){if(!this.f)return Ef(this,d)}.bind(a)).then(function(){this.f||(this.h[b].L.resolve(),this.h[b].La=!0)}.bind(a))["catch"](function(a){this.f||(this.h[b].L.reject(),
- delete this.h[b],this.a.onError(a))}.bind(a));return c.L}
- function Ef(a,b){b.map(function(a){return a.id}).filter(Aa);for(var c=[],d=0;d<b.length;++d){var e=b[d];var f=a.j[e.id];f?c.push(f.L):(a.j[e.id]={L:new A,La:!1},c.push(e.createSegmentIndex()))}return Promise.all(c).then(function(){if(!this.f)for(var a=0;a<b.length;++a){var c=this.j[b[a].id];c.La||(c.L.resolve(),c.La=!0)}}.bind(a))["catch"](function(a){if(!this.f)return this.j[e.id].L.reject(),delete this.j[e.id],Promise.reject(a)}.bind(a))}
- function Df(a){var b=a.b.presentationTimeline.Y();Infinity>b?a.a.K.pa(b):a.a.K.pa(Math.pow(2,32))}k.ke=function(a){if(!this.f&&!a.xa&&null!=a.qa&&!a.sa)if(a.qa=null,a.ra)Af(this,a,a.kb);else{try{var b=Gf(this,a);null!=b&&(Cf(this,a,b),a.tb=!1)}catch(c){this.a.onError(c);return}b=Na(this.c);Hf(this,a);b.every(function(a){return a.endOfStream})&&this.a.K.endOfStream().then(function(){this.b.presentationTimeline.pa(this.a.K.Y())}.bind(this))}};
- function Gf(a,b){var c=jf(a.a.Oa),d=b.Fa&&b.ea?a.b.periods[ic(a.b,b.Fa)].startTime+b.ea.endTime:Math.max(c,b.rc);b.rc=0;var e=ic(a.b,b.stream),f=hc(a.b,d);var g=a.a.K;var h=b.type;"text"==h?(g=g.a,g=null==g.a||g.a<c?0:g.a-Math.max(c,g.b)):(g=Ib(g,h),g=Cb(g,c));h=Math.max(a.i*Math.max(a.b.minBufferTime||0,a.g.rebufferingGoal),a.i*a.g.bufferingGoal);if(d>=a.b.presentationTimeline.Y())return b.endOfStream=!0,null;b.endOfStream=!1;b.wa=f;if(f!=e)return null;if(g>=h)return.5;d=a.a.K;f=b.type;d="text"==
- f?d.a.a:Ab(Ib(d,f));b.ea&&b.stream==b.Fa?(f=b.ea.position+1,d=If(a,b,e,f)):(f=b.ea?b.stream.findSegmentPosition(Math.max(0,a.b.periods[ic(a.b,b.Fa)].startTime+b.ea.endTime-a.b.periods[e].startTime)):b.stream.findSegmentPosition(Math.max(0,(d||c)-a.b.periods[e].startTime)),null==f?d=null:(g=null,null==d&&(g=If(a,b,e,Math.max(0,f-1))),d=g||If(a,b,e,f)));if(!d)return 1;Jf(a,b,c,e,d);return null}
- function If(a,b,c,d){c=a.b.periods[c];b=b.stream.getSegmentReference(d);if(!b)return null;a=a.b.presentationTimeline;d=a.ua();return c.startTime+b.endTime<a.ma()||c.startTime+b.startTime>d?null:b}
- function Jf(a,b,c,d,e){var f=a.b.periods[d],g=b.stream,h=a.b.periods[d+1],l=null,l=h?h.startTime:a.b.presentationTimeline.Y();d=Kf(a,b,d,l);b.xa=!0;b.cb=!1;h=Lf(a,e);Promise.all([d,h]).then(function(a){if(!this.f&&!this.l)return Mf(this,b,c,f,g,e,a[1])}.bind(a)).then(function(){this.f||this.l||(b.xa=!1,b.Gb=!1,b.ra||this.a.Ab(),Cf(this,b,0),Nf(this,g))}.bind(a))["catch"](function(a){this.f||this.l||(b.xa=!1,this.b.presentationTimeline.$()&&this.g.infiniteRetriesForLiveStreams&&(1001==a.code||1002==
- a.code||1003==a.code)?"text"==b.type&&this.g.ignoreTextStreamFailures&&1001==a.code?delete this.c.text:(a.severity=1,this.a.onError(a),Cf(this,b,4)):3017==a.code?Of(this,b,a):"text"==b.type&&this.g.ignoreTextStreamFailures?delete this.c.text:(b.tb=!0,a.severity=2,this.a.onError(a)))}.bind(a))}function Of(a,b,c){if(!Na(a.c).some(function(a){return a!=b&&a.Gb})){var d=Math.round(100*a.i);if(20<d)a.i-=.2;else if(4<d)a.i-=.04;else{b.tb=!0;a.l=!0;a.a.onError(c);return}b.Gb=!0}Cf(a,b,4)}
- function Kf(a,b,c,d){if(!b.cb)return Promise.resolve();c=Mb(a.a.K,b.type,a.b.periods[c].startTime-b.stream.presentationTimeOffset,d);if(!b.stream.initSegmentReference)return c;a=Lf(a,b.stream.initSegmentReference).then(function(a){if(!this.f)return Jb(this.a.K,b.type,a,null,null)}.bind(a))["catch"](function(a){b.cb=!0;return Promise.reject(a)});return Promise.all([c,a])}
- function Mf(a,b,c,d,e,f,g){e.containsEmsgBoxes&&(new Q).da("emsg",a.Ed.bind(a,d,f)).parse(g);return Pf(a,b,c).then(function(){if(!this.f)return Jb(this.a.K,b.type,g,f.startTime+d.startTime,f.endTime+d.startTime)}.bind(a)).then(function(){if(!this.f)return b.Fa=e,b.ea=f,Promise.resolve()}.bind(a))}
- k.Ed=function(a,b,c){var d=c.s.Db(),e=c.s.Db(),f=c.s.D(),g=c.s.D(),h=c.s.D(),l=c.s.D();c=c.s.Ka(c.s.H.byteLength-c.s.u);a=a.startTime+b.startTime+g/f;if("urn:mpeg:dash:event:2012"==d)this.a.kd();else this.a.onEvent(new I("emsg",{detail:{startTime:a,endTime:a+h/f,schemeIdUri:d,value:e,timescale:f,presentationTimeDelta:g,eventDuration:h,id:l,messageData:c}}))};
- function Pf(a,b,c){var d=Gb(a.a.K,b.type);if(null==d)return Promise.resolve();c=c-d-a.g.bufferBehind;return 0>=c?Promise.resolve():a.a.K.remove(b.type,d,d+c).then(function(){}.bind(a))}function Nf(a,b){if(!a.v&&(a.v=Na(a.c).every(function(a){return"text"==a.type?!0:!a.ra&&!a.sa&&a.ea}),a.v)){var c=ic(a.b,b);a.h[c]||Ff(a,c).then(function(){this.a.ac()}.bind(a))["catch"](y);for(c=0;c<a.b.periods.length;++c)Ff(a,c)["catch"](y);a.a.wd&&a.a.wd()}}
- function Hf(a,b){if(b.wa!=ic(a.b,b.stream)){var c=b.wa,d=Na(a.c);d.every(function(a){return a.wa==c})&&d.every(Qf)&&Ff(a,c).then(function(){if(!this.f&&d.every(function(a){var b=ic(this.b,a.stream);return Qf(a)&&a.wa==c&&b!=c}.bind(this))){var a=this.b.periods[c],b=this.a.bc(a),g;for(g in this.c)if(!b[g]&&"text"!=g){this.a.onError(new t(2,5,5005));return}for(g in b)if(!this.c[g])if("text"==g)uf(this,{text:b.text},a.startTime),delete b[g];else{this.a.onError(new t(2,5,5005));return}for(g in this.c)(a=
- b[g])?(yf(this,g,a,!1),Cf(this,this.c[g],0)):delete this.c[g];this.a.ac()}}.bind(a))["catch"](y)}}function Qf(a){return!a.xa&&null==a.qa&&!a.ra&&!a.sa}function Lf(a,b){var c=C(b.a(),a.g.retryParameters);if(b.X||null!=b.M){var d="bytes="+b.X+"-";null!=b.M&&(d+=b.M);c.headers.Range=d}return a.a.dd.request(1,c).then(function(a){return a.data})}
- function Af(a,b,c){b.ra=!1;b.kb=!1;b.sa=!0;Lb(a.a.K,b.type).then(function(){if(!this.f&&c){var a=this.a.K,e=b.type;return"text"==e?Promise.resolve():Kb(a,e,a.Oc.bind(a,e))}}.bind(a)).then(function(){this.f||(b.Fa=null,b.ea=null,b.sa=!1,b.endOfStream=!1,Cf(this,b,0))}.bind(a))}function Cf(a,b,c){b.qa=window.setTimeout(a.ke.bind(a,b),1E3*c)}function tf(a){null!=a.qa&&(window.clearTimeout(a.qa),a.qa=null)};function Rf(a,b){return new Promise(function(c,d){var e=new XMLHttpRequest;e.open(b.method,a,!0);e.responseType="arraybuffer";e.timeout=b.retryParameters.timeout;e.withCredentials=b.allowCrossSiteCredentials;e.onload=function(b){b=b.target;var e=b.getAllResponseHeaders().split("\r\n").reduce(function(a,b){var c=b.split(": ");a[c[0].toLowerCase()]=c.slice(1).join(": ");return a},{});if(200<=b.status&&299>=b.status&&202!=b.status)b.responseURL&&(a=b.responseURL),c({uri:a,data:b.response,headers:e,fromCache:!!e["x-shaka-from-cache"]});
- else{var f=null;try{f=Ta(b.response)}catch(m){}d(new t(401==b.status||403==b.status?2:1,1,1001,a,b.status,f,e))}};e.onerror=function(){d(new t(1,1,1002,a))};e.ontimeout=function(){d(new t(1,1,1003,a))};for(var f in b.headers)e.setRequestHeader(f,b.headers[f]);e.send(b.body)})}n("shaka.net.HttpPlugin",Rf);Ea.http=Rf;Ea.https=Rf;function Sf(){this.a=null;this.b=[];this.c={}}k=Sf.prototype;k.init=function(a,b){return Tf(this,a,b).then(function(){var b=Object.keys(a);return Promise.all(b.map(function(a){return Uf(this,a).then(function(b){this.c[a]=b}.bind(this))}.bind(this)))}.bind(this))};k.m=function(){return Promise.all(this.b.map(function(a){try{a.transaction.abort()}catch(b){}return a.L["catch"](y)})).then(function(){this.a&&(this.a.close(),this.a=null)}.bind(this))};
- k.get=function(a,b){var c;return Vf(this,a,"readonly",function(a){c=a.get(b)}).then(function(){return c.result})};k.forEach=function(a,b){return Vf(this,a,"readonly",function(a){a.openCursor().onsuccess=function(a){if(a=a.target.result)b(a.value),a["continue"]()}})};function Wf(a,b,c){return Vf(a,b,"readwrite",function(a){a.put(c)})}k.remove=function(a,b){return Vf(this,a,"readwrite",function(a){a["delete"](b)})};
- function Xf(a,b,c){return Vf(a,"segment","readwrite",function(a){for(var d=0;d<b.length;d++)a["delete"](b[d]).onsuccess=c||function(){}})}function Uf(a,b){var c=0;return Vf(a,b,"readonly",function(a){a.openCursor(null,"prev").onsuccess=function(a){(a=a.target.result)&&(c=a.key+1)}}).then(function(){return c})}
- function Vf(a,b,c,d){var e={transaction:a.a.transaction([b],c),L:new A};e.transaction.oncomplete=function(){this.b.splice(this.b.indexOf(e),1);e.L.resolve()}.bind(a);e.transaction.onabort=function(a){this.b.splice(this.b.indexOf(e),1);Yf(e.transaction,e.L,a)}.bind(a);e.transaction.onerror=function(a){a.preventDefault()}.bind(a);b=e.transaction.objectStore(b);d(b);a.b.push(e);return e.L}
- function Tf(a,b,c){var d=window.indexedDB.open("shaka_offline_db",1),e=!1,f=new A;d.onupgradeneeded=function(a){e=!0;a=a.target.result;for(var c in b)a.createObjectStore(c,{keyPath:b[c]})};d.onsuccess=function(a){c&&!e?(a.target.result.close(),setTimeout(function(){Tf(this,b,c-1).then(f.resolve,f.reject)}.bind(this),1E3)):(this.a=a.target.result,f.resolve())}.bind(a);d.onerror=Yf.bind(null,d,f);return f}
- function Yf(a,b,c){a.error?b.reject(new t(2,9,9001,a.error)):b.reject(new t(2,9,9002));c.preventDefault()};var Zf={manifest:"key",segment:"key"};function $f(a){var b=ag(a.periods[0],[],new T(null,0)),c=Zb(b,null,null),b=ac(b,null);c.push.apply(c,b);return{offlineUri:"offline:"+a.key,originalManifestUri:a.originalManifestUri,duration:a.duration,size:a.size,expiration:void 0==a.expiration?Infinity:a.expiration,tracks:c,appMetadata:a.appMetadata}}
- function ag(a,b,c){var d=a.streams.filter(function(a){return"text"==a.contentType}),e=a.streams.filter(function(a){return"audio"==a.contentType}),f=a.streams.filter(function(a){return"video"==a.contentType});b=bg(e,f,b);d=d.map(cg);a.streams.forEach(function(a){a=dg(a);c.Ha(0,a)});return{startTime:a.startTime,variants:b,textStreams:d}}function dg(a){return a.segments.map(function(a,c){return new O(c,a.startTime,a.endTime,function(){return[a.uri]},0,null)})}
- function bg(a,b,c){var d=[];if(!a.length&&!b.length)return d;a.length?b.length||(b=[null]):a=[null];for(var e=0,f=0;f<a.length;f++)for(var g=0;g<b.length;g++)if(eg(a[f],b[g])){var h=a[f];var l=b[g],m=c;h={id:e++,language:h?h.language:"",primary:!!h&&h.primary||!!l&&l.primary,audio:cg(h),video:cg(l),bandwidth:0,drmInfos:m,allowedByApplication:!0,allowedByKeySystem:!0};d.push(h)}return d}
- function eg(a,b){if(!(a&&b&&a.variantIds&&b.variantIds))return!0;for(var c=0;c<a.variantIds.length;c++)if(b.variantIds.some(function(b){return b==a.variantIds[c]}))return!0;return!1}
- function cg(a){if(!a)return null;var b=dg(a),b=new S(b);return{id:a.id,createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:b.find.bind(b),getSegmentReference:b.get.bind(b),initSegmentReference:a.initSegmentUri?new Zc(function(){return[a.initSegmentUri]},0,null):null,presentationTimeOffset:a.presentationTimeOffset,mimeType:a.mimeType,codecs:a.codecs,width:a.width||void 0,height:a.height||void 0,frameRate:a.frameRate||void 0,kind:a.kind,encrypted:a.encrypted,keyId:a.keyId,language:a.language,
- label:a.label||null,type:a.contentType,primary:a.primary,trickModeVideo:null,containsEmsgBoxes:!1,roles:[]}}function fg(){return window.indexedDB?new Sf:null};function gg(a,b,c,d){this.b={};this.l=[];this.o=d;this.j=a;this.v=b;this.A=c;this.i=this.a=null;this.f=this.g=this.h=this.c=0}gg.prototype.m=function(){var a=this.j,b=this.l,c=this.i||Promise.resolve(),c=c.then(function(){return Xf(a,b)});this.b={};this.l=[];this.i=this.a=this.A=this.v=this.j=this.o=null;return c};function hg(a,b,c,d,e){a.b[b]=a.b[b]||[];a.b[b].push({uris:c.a(),X:c.X,M:c.M,Rb:d,Hb:e})}
- function ig(a,b){a.c=0;a.h=0;a.g=0;a.f=0;Na(a.b).forEach(function(a){a.forEach(function(a){null!=a.M?this.c+=a.M-a.X+1:this.g+=a.Rb}.bind(this))}.bind(a));a.a=b;a.a.size=a.c;var c=Na(a.b).map(function(a){var b=0,c=function(){if(!this.o)return Promise.reject(new t(2,9,9002));if(b>=a.length)return Promise.resolve();var d=a[b++];return jg(this,d).then(c)}.bind(this);return c()}.bind(a));a.b={};a.i=Promise.all(c).then(function(){return Wf(this.j,"manifest",b)}.bind(a)).then(function(){this.l=[]}.bind(a));
- return a.i}
- function jg(a,b){var c=C(b.uris,a.A);if(b.X||null!=b.M)c.headers.Range="bytes="+b.X+"-"+(null==b.M?"":b.M);var d;return a.v.request(1,c).then(function(a){if(!this.a)return Promise.reject(new t(2,9,9002));d=a.data.byteLength;this.l.push(b.Hb.key);b.Hb.data=a.data;return Wf(this.j,"segment",b.Hb)}.bind(a)).then(function(){if(!this.a)return Promise.reject(new t(2,9,9002));null==b.M?(this.a.size+=d,this.f+=b.Rb):this.h+=d;var a=(this.h+this.f)/(this.c+this.g),c=$f(this.a);this.o.progressCallback(c,a)}.bind(a))}
- ;function kg(){this.a=-1}k=kg.prototype;k.configure=function(){};k.start=function(a){var b=/^offline:([0-9]+)$/.exec(a);if(!b)return Promise.reject(new t(2,1,9004,a));var c=Number(b[1]),d=fg();this.a=c;return d?d.init(Zf).then(function(){return d.get("manifest",c)}).then(function(a){if(!a)throw new t(2,9,9003,c);return lg(a)}).then(function(a){return d.m().then(function(){return a})},function(a){return d.m().then(function(){throw a;})}):Promise.reject(new t(2,9,9E3))};k.stop=function(){return Promise.resolve()};
- k.update=function(){};k.onExpirationUpdated=function(a,b){var c=fg();c.init(Zf).then(function(){return c.get("manifest",this.a)}.bind(this)).then(function(d){if(d&&!(0>d.sessionIds.indexOf(a))&&(void 0==d.expiration||d.expiration>b))return d.expiration=b,Wf(c,"manifest",d)})["catch"](function(){}).then(function(){return c.m()})};
- function lg(a){var b=new T(null,0);b.pa(a.duration);var c=a.drmInfo?[a.drmInfo]:[];return{presentationTimeline:b,minBufferTime:10,offlineSessionIds:a.sessionIds,periods:a.periods.map(function(a){return ag(a,c,b)})}}Dd["application/x-offline-manifest"]=kg;function mg(a){if(/^offline:([0-9]+)$/.exec(a)){var b={uri:a,data:new ArrayBuffer(0),headers:{"content-type":"application/x-offline-manifest"}};return Promise.resolve(b)}if(b=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a)){var c=Number(b[1]),d=fg();return d?d.init(Zf).then(function(){return d.get("segment",c)}).then(function(b){return d.m().then(function(){if(!b)throw new t(2,9,9003,c);return{uri:a,data:b.data,headers:{}}})}):Promise.reject(new t(2,9,9E3))}return Promise.reject(new t(2,1,9004,a))}
- n("shaka.offline.OfflineScheme",mg);Ea.offline=mg;function ng(){this.a=Promise.resolve();this.b=this.c=this.f=!1;this.i=new Promise(function(a){this.g=a}.bind(this))}ng.prototype.then=function(a){this.a=this.a.then(a).then(function(a){return this.b?(this.g(),Promise.reject(this.h)):Promise.resolve(a)}.bind(this));return this};function og(a){a.f||(a.a=a.a.then(function(a){this.c=!0;return Promise.resolve(a)}.bind(a),function(a){this.c=!0;return this.b?(this.g(),Promise.reject(this.h)):Promise.reject(a)}.bind(a)));a.f=!0;return a.a}
- ng.prototype.cancel=function(a){if(this.c)return Promise.resolve();this.b=!0;this.h=a;return this.i};function W(a,b){p.call(this);this.O=!1;this.f=a;this.A=null;this.l=new D;this.Qb=new H;this.Ya=this.c=this.h=this.a=this.v=this.g=this.Wa=this.ja=this.N=this.j=this.o=null;this.Dc=1E9;this.Va=[];this.ka=!1;this.Za=!0;this.la=this.J=null;this.G={};this.Xa=[];this.B={};this.b=pg(this);this.ob={width:Infinity,height:Infinity};this.i=qg();this.Ua=0;this.ia=this.b.preferredAudioLanguage;this.Ca=this.b.preferredTextLanguage;this.lb=this.mb="";b&&b(this);this.o=new B(this.de.bind(this));this.Wa=rg(this);
- for(var c=0;c<this.f.textTracks.length;++c){var d=this.f.textTracks[c];d.mode="disabled";"Shaka Player TextTrack"==d.label&&(this.A=d)}this.A||(this.A=this.f.addTextTrack("subtitles","Shaka Player TextTrack"));this.A.mode="hidden";E(this.l,this.f,"error",this.yd.bind(this))}ba(W);n("shaka.Player",W);
- W.prototype.m=function(){this.O=!0;var a=Promise.resolve();this.J&&(a=this.J.cancel(new t(2,7,7E3)));return a.then(function(){var a=Promise.all([this.la,sg(this),this.l?this.l.m():null,this.o?this.o.m():null]);this.b=this.o=this.Qb=this.l=this.A=this.f=null;return a}.bind(this))};W.prototype.destroy=W.prototype.m;W.version="v2.1.4";var tg={};W.registerSupportPlugin=function(a,b){tg[a]=b};
- W.isBrowserSupported=function(){return!!window.Promise&&!!window.Uint8Array&&!!Array.prototype.forEach&&!!window.MediaSource&&!!window.MediaSource.isTypeSupported&&!!window.MediaKeys&&!!window.navigator&&!!window.navigator.requestMediaKeySystemAccess&&!!window.MediaKeySystemAccess&&!!window.MediaKeySystemAccess.prototype.getConfiguration};W.probeSupport=function(){return qb().then(function(a){var b=Fd(),c=Eb();a={manifest:b,media:c,drm:a};for(var d in tg)a[d]=tg[d]();return a})};
- W.prototype.load=function(a,b,c){var d=this.hb(),e=new ng;this.J=e;this.dispatchEvent(new I("loading"));var f=Date.now();return og(e.then(function(){return d}).then(function(){this.i=qg();E(this.l,this.f,"playing",this.Sa.bind(this));E(this.l,this.f,"pause",this.Sa.bind(this));E(this.l,this.f,"ended",this.Sa.bind(this));return Gd(a,this.o,this.b.manifest.retryParameters,c)}.bind(this)).then(function(b){this.h=new b;this.h.configure(this.b.manifest);b={networkingEngine:this.o,filterPeriod:this.fb.bind(this),
- onTimelineRegionAdded:this.xd.bind(this),onEvent:this.gb.bind(this),onError:this.ya.bind(this)};return 2<this.h.start.length?this.h.start(a,this.o,b.filterPeriod,b.onError,b.onEvent):this.h.start(a,b)}.bind(this)).then(function(b){if(0==b.periods.length)throw new t(2,4,4014);this.c=b;this.Ya=a;this.j=new bb(this.o,this.ya.bind(this),this.be.bind(this),this.ae.bind(this));this.j.configure(this.b.drm);return this.j.init(b,!1)}.bind(this)).then(function(){this.c.periods.forEach(this.fb.bind(this));this.Ua=
- Date.now()/1E3;this.ia=this.b.preferredAudioLanguage;this.Ca=this.b.preferredTextLanguage;return Promise.all([eb(this.j,this.f),this.Wa])}.bind(this)).then(function(){this.b.abr.manager.init(this.Lb.bind(this));this.g=new ff(this.f,this.c,this.b.streaming,b||null,this.ce.bind(this),this.gb.bind(this));this.v=new of(this.f,this.c,this.b.streaming,this.zc.bind(this),this.gb.bind(this),this.$d.bind(this));this.ja=new Db(this.f,this.N,this.A);this.a=new sf(this.c,{Oa:this.g,K:this.ja,dd:this.o,bc:this.ed.bind(this),
- ac:this.Gc.bind(this),onError:this.ya.bind(this),onEvent:this.gb.bind(this),kd:this.ld.bind(this),Ab:this.ud.bind(this)});this.a.configure(this.b.streaming);ug(this);return this.a.init()}.bind(this)).then(function(){if(this.b.streaming.startAtSegmentBoundary){var a=vg(this,jf(this.g));gf(this.g,a)}this.c.periods.forEach(this.fb.bind(this));wg(this);xg(this);var a=V(this.a),b=dc(a,this.ia);this.b.abr.manager.setVariants(b);a.variants.some(function(a){return a.primary});this.Xa.forEach(this.v.v.bind(this.v));
- this.Xa=[];La(this.l,this.f,"loadeddata",function(){this.i.loadLatency=(Date.now()-f)/1E3}.bind(this));this.J=null}.bind(this)))["catch"](function(a){this.J==e&&(this.J=null,this.dispatchEvent(new I("unloading")));return Promise.reject(a)}.bind(this))};W.prototype.load=W.prototype.load;
- function ug(a){function b(a){return(a.video?a.video.codecs.split(".")[0]:"")+"-"+(a.audio?a.audio.codecs.split(".")[0]:"")}var c={};a.c.periods.forEach(function(a){a.variants.forEach(function(a){var d=b(a);d in c||(c[d]=[]);c[d].push(a)})});var d=null,e=Infinity;Qa(c,function(a,b){var c=0,f=0;b.forEach(function(a){c+=a.bandwidth;++f});var g=c/f;g<e&&(d=a,e=g)});a.c.periods.forEach(function(a){a.variants=a.variants.filter(function(a){return b(a)==d?!0:!1})})}
- function rg(a){a.N=new MediaSource;var b=new A;E(a.l,a.N,"sourceopen",b.resolve);a.f.src=window.URL.createObjectURL(a.N);return b}W.prototype.configure=function(a){a.abr&&a.abr.manager&&a.abr.manager!=this.b.abr.manager&&(this.b.abr.manager.stop(),a.abr.manager.init(this.Lb.bind(this)));Ca(this.b,a,pg(this),yg(),"");zg(this)};W.prototype.configure=W.prototype.configure;
- function zg(a){a.h&&a.h.configure(a.b.manifest);a.j&&a.j.configure(a.b.drm);if(a.a){a.a.configure(a.b.streaming);try{a.c.periods.forEach(a.fb.bind(a))}catch(b){a.ya(b)}Ag(a,V(a.a))}a.b.abr.enabled&&!a.Za?a.b.abr.manager.enable():a.b.abr.manager.disable();a.b.abr.manager.setDefaultEstimate(a.b.abr.defaultBandwidthEstimate);a.b.abr.manager.setRestrictions(a.b.abr.restrictions)}W.prototype.getConfiguration=function(){var a=pg(this);Ca(a,this.b,pg(this),yg(),"");return a};
- W.prototype.getConfiguration=W.prototype.getConfiguration;W.prototype.Rd=function(){var a=pg(this);a.abr&&a.abr.manager&&a.abr.manager!=this.b.abr.manager&&(this.b.abr.manager.stop(),a.abr.manager.init(this.Lb.bind(this)));this.b=pg(this);zg(this)};W.prototype.resetConfiguration=W.prototype.Rd;W.prototype.Sc=function(){return this.f};W.prototype.getMediaElement=W.prototype.Sc;W.prototype.Wb=function(){return this.o};W.prototype.getNetworkingEngine=W.prototype.Wb;W.prototype.Rc=function(){return this.Ya};
- W.prototype.getManifestUri=W.prototype.Rc;W.prototype.$=function(){return this.c?this.c.presentationTimeline.$():!1};W.prototype.isLive=W.prototype.$;W.prototype.va=function(){return this.c?this.c.presentationTimeline.va():!1};W.prototype.isInProgress=W.prototype.va;W.prototype.Td=function(){var a=0,b=0;this.c&&(b=this.c.presentationTimeline,a=b.ma(),b=b.bb());return{start:a,end:b}};W.prototype.seekRange=W.prototype.Td;W.prototype.keySystem=function(){return this.j?this.j.keySystem():""};
- W.prototype.keySystem=W.prototype.keySystem;W.prototype.drmInfo=function(){return this.j?this.j.b:null};W.prototype.drmInfo=W.prototype.drmInfo;W.prototype.ab=function(){return this.j?this.j.ab():Infinity};W.prototype.getExpiration=W.prototype.ab;W.prototype.$c=function(){return this.ka};W.prototype.isBuffering=W.prototype.$c;
- W.prototype.hb=function(){if(this.O)return Promise.resolve();this.dispatchEvent(new I("unloading"));var a=Promise.resolve();this.J&&(a=this.J.cancel(new t(2,7,7E3)));return a.then(function(){this.la||(this.la=Bg(this).then(function(){this.la=null}.bind(this)));return this.la}.bind(this))};W.prototype.unload=W.prototype.hb;W.prototype.rb=function(){return this.g?this.g.rb():0};W.prototype.getPlaybackRate=W.prototype.rb;W.prototype.ne=function(a){this.g&&lf(this.g,a);this.a&&xf(this.a,1!=a)};
- W.prototype.trickPlay=W.prototype.ne;W.prototype.Hc=function(){this.g&&lf(this.g,1);this.a&&xf(this.a,!1)};W.prototype.cancelTrickPlay=W.prototype.Hc;W.prototype.getTracks=function(){return this.Yb().concat(this.Xb())};W.prototype.getTracks=W.prototype.getTracks;W.prototype.Wd=function(a,b){"text"==a.type?this.tc(a):(this.configure({abr:{enabled:!1}}),this.uc(a,b))};W.prototype.selectTrack=W.prototype.Wd;
- W.prototype.Yb=function(){if(!this.c)return[];var a=hc(this.c,jf(this.g)),b=this.B[a]||{};return Zb(this.c.periods[a],b.audio,b.video)};W.prototype.getVariantTracks=W.prototype.Yb;W.prototype.Xb=function(){if(!this.c)return[];var a=hc(this.c,jf(this.g));return ac(this.c.periods[a],(this.B[a]||{}).text).filter(function(a){return 0>this.Va.indexOf(a.id)}.bind(this))};W.prototype.getTextTracks=W.prototype.Xb;
- W.prototype.tc=function(a){if(this.a&&(a=cc(V(this.a),a))){Cg(this,a,!1);var b={};b.text=a;Dg(this,b,!0)}};W.prototype.selectTextTrack=W.prototype.tc;
- W.prototype.uc=function(a,b){if(this.a){var c={},d=bc(V(this.a),a),e=vf(this.a);if(d){if(!d.allowedByApplication||!d.allowedByKeySystem)return;d.audio&&(Eg(this,d.audio),d.audio!=e.audio&&(c.audio=d.audio));d.video&&(Eg(this,d.video),d.video!=e.video&&(c.video=d.video))}Na(c).forEach(function(a){Cg(this,a,!1)}.bind(this));(d=e.text)&&(c.text=d);Dg(this,c,b)}};W.prototype.selectVariantTrack=W.prototype.uc;
- W.prototype.Pc=function(){return this.a?$b(V(this.a).variants).map(function(a){return a.language}).filter(Aa):[]};W.prototype.getAudioLanguages=W.prototype.Pc;W.prototype.Yc=function(){return this.a?V(this.a).textStreams.map(function(a){return a.language}).filter(Aa):[]};W.prototype.getTextLanguages=W.prototype.Yc;W.prototype.Ud=function(a,b){if(this.a){var c=V(this.a);this.ia=a;this.mb=b||"";Ag(this,c)}};W.prototype.selectAudioLanguage=W.prototype.Ud;
- W.prototype.Vd=function(a,b){if(this.a){var c=V(this.a);this.Ca=a;this.lb=b||"";Ag(this,c)}};W.prototype.selectTextLanguage=W.prototype.Vd;W.prototype.bd=function(){return"showing"==this.A.mode};W.prototype.isTextTrackVisible=W.prototype.bd;W.prototype.Yd=function(a){this.A.mode=a?"showing":"hidden";Fg(this)};W.prototype.setTextTrackVisibility=W.prototype.Yd;W.prototype.Uc=function(){return this.c?new Date(1E3*this.c.presentationTimeline.f+1E3*this.f.currentTime):null};
- W.prototype.getPlayheadTimeAsDate=W.prototype.Uc;
- W.prototype.getStats=function(){Gg(this);this.Sa();var a=null,b=null,c=this.f&&this.f.getVideoPlaybackQuality?this.f.getVideoPlaybackQuality():{};this.g&&this.c&&(a=hc(this.c,jf(this.g)),b=this.B[a],b=gc(b.audio,b.video,this.c.periods[a].variants),a=b.video||{});a||(a={});b||(b={});return{width:a.width||0,height:a.height||0,streamBandwidth:b.bandwidth||0,decodedFrames:Number(c.totalVideoFrames),droppedFrames:Number(c.droppedVideoFrames),estimatedBandwidth:this.b.abr.manager.getBandwidthEstimate(),loadLatency:this.i.loadLatency,
- playTime:this.i.playTime,bufferingTime:this.i.bufferingTime,switchHistory:Da(this.i.switchHistory),stateHistory:Da(this.i.stateHistory)}};W.prototype.getStats=W.prototype.getStats;
- W.prototype.addTextTrack=function(a,b,c,d,e,f){if(!this.a)return Promise.reject();for(var g=V(this.a),h,l=0;l<this.c.periods.length;l++)if(this.c.periods[l]==g){if(l==this.c.periods.length-1){if(h=this.c.presentationTimeline.Y()-g.startTime,Infinity==h)return Promise.reject()}else h=this.c.periods[l+1].startTime-g.startTime;break}var m={id:this.Dc++,createSegmentIndex:Promise.resolve.bind(Promise),findSegmentPosition:function(){return 1},getSegmentReference:function(b){return 1!=b?null:new O(1,0,
- h,function(){return[a]},0,null)},initSegmentReference:null,presentationTimeOffset:0,mimeType:d,codecs:e||"",kind:c,encrypted:!1,keyId:null,language:b,label:f||null,type:"text",primary:!1,trickModeVideo:null,containsEmsgBoxes:!1,roles:[]};this.Va.push(m.id);g.textStreams.push(m);return wf(this.a,m).then(function(){if(!this.O){var a=this.c.periods.indexOf(g),d=vf(this.a);d.text&&(this.B[a].text=d.text.id);this.Va.splice(this.Va.indexOf(m.id),1);Ag(this,g);wg(this);return{id:m.id,active:!1,type:"text",
- bandwidth:0,language:b,label:f||null,kind:c,width:null,height:null}}}.bind(this))};W.prototype.addTextTrack=W.prototype.addTextTrack;W.prototype.Jb=function(a,b){this.ob.width=a;this.ob.height=b};W.prototype.setMaxHardwareResolution=W.prototype.Jb;function Cg(a,b,c){a.i.switchHistory.push({timestamp:Date.now()/1E3,id:b.id,type:b.type,fromAdaptation:c});Eg(a,b)}function Eg(a,b){var c=ic(a.c,b);a.B[c]||(a.B[c]={});a.B[c][b.type]=b.id}
- function sg(a){a.l&&(a.l.ha(a.N,"sourceopen"),a.l.ha(a.f,"loadeddata"),a.l.ha(a.f,"playing"),a.l.ha(a.f,"pause"),a.l.ha(a.f,"ended"));a.f&&(a.f.removeAttribute("src"),a.f.load());var b=Promise.all([a.b?a.b.abr.manager.stop():null,a.j?a.j.m():null,a.ja?a.ja.m():null,a.g?a.g.m():null,a.v?a.v.m():null,a.a?a.a.m():null,a.h?a.h.stop():null]);a.j=null;a.ja=null;a.g=null;a.v=null;a.a=null;a.h=null;a.c=null;a.Ya=null;a.Wa=null;a.N=null;a.Xa=[];a.B={};a.G={};a.i=qg();return b}
- function Bg(a){return a.h?sg(a).then(function(){this.O||(this.zc(!1),this.Wa=rg(this))}.bind(a)):Promise.resolve()}function yg(){return{".drm.servers":"",".drm.clearKeys":"",".drm.advanced":{distinctiveIdentifierRequired:!1,persistentStateRequired:!1,videoRobustness:"",audioRobustness:"",serverCertificate:null}}}
- function pg(a){return{drm:{retryParameters:Fa(),servers:{},clearKeys:{},advanced:{},delayLicenseRequestUntilPlayed:!1},manifest:{retryParameters:Fa(),dash:{customScheme:function(a){if(a)return null},clockSyncUri:"",ignoreDrmInfo:!1},hls:{defaultTimeOffset:0}},streaming:{retryParameters:Fa(),infiniteRetriesForLiveStreams:!0,rebufferingGoal:2,bufferingGoal:10,bufferBehind:30,ignoreTextStreamFailures:!1,startAtSegmentBoundary:!1,smallGapLimit:.5,jumpLargeGaps:!1},abr:{manager:a.Qb,enabled:!0,defaultBandwidthEstimate:5E5,
- restrictions:{minWidth:0,maxWidth:Infinity,minHeight:0,maxHeight:Infinity,minPixels:0,maxPixels:Infinity,minBandwidth:0,maxBandwidth:Infinity}},preferredAudioLanguage:"",preferredTextLanguage:"",restrictions:{minWidth:0,maxWidth:Infinity,minHeight:0,maxHeight:Infinity,minPixels:0,maxPixels:Infinity,minBandwidth:0,maxBandwidth:Infinity}}}
- function qg(){return{width:NaN,height:NaN,streamBandwidth:NaN,decodedFrames:NaN,droppedFrames:NaN,estimatedBandwidth:NaN,loadLatency:NaN,playTime:0,bufferingTime:0,switchHistory:[],stateHistory:[]}}k=W.prototype;k.fb=function(a){var b=this.a?vf(this.a):{};Wb(this.j,b,a);b=0<$b(a.variants).length;Vb(a,this.b.restrictions,this.ob)&&this.a&&V(this.a)==a&&wg(this);a=1>$b(a.variants).length;if(!b)throw new t(2,4,4011);if(a)throw new t(2,4,4012);};
- function Dg(a,b,c){for(var d in b){var e=b[d],f=c||!1;"text"==d&&(f=!0);a.Za?a.G[d]={stream:e,Kc:f}:yf(a.a,d,e,f)}}function Gg(a){if(a.c){var b=Date.now()/1E3;a.ka?a.i.bufferingTime+=b-a.Ua:a.i.playTime+=b-a.Ua;a.Ua=b}}
- function vg(a,b){function c(a,b){if(!a)return null;var c=a.findSegmentPosition(b-e.startTime);return null==c?null:(c=a.getSegmentReference(c))?c.startTime+e.startTime:null}var d=vf(a.a),e=V(a.a),f=c(d.video,b),d=c(d.audio,b);return null!=f&&null!=d?Math.max(f,d):null!=f?f:null!=d?d:b}k.de=function(a,b){this.b.abr.manager.segmentDownloaded(a,b)};k.zc=function(a){Gg(this);this.ka=a;this.Sa();if(this.g){var b=this.g;a!=b.h&&(b.h=a,lf(b,b.g))}this.dispatchEvent(new I("buffering",{buffering:a}))};
- k.$d=function(){wg(this)};k.Sa=function(){if(!this.O){var a=this.ka?"buffering":this.f.ended?"ended":this.f.paused?"paused":"playing";var b=Date.now()/1E3;if(this.i.stateHistory.length){var c=this.i.stateHistory[this.i.stateHistory.length-1];c.duration=b-c.timestamp;if(a==c.state)return}this.i.stateHistory.push({timestamp:b,state:a,duration:0})}};k.ce=function(){if(this.v){var a=this.v;a.c.forEach(a.o.bind(a,!0))}this.a&&Bf(this.a)};
- function Hg(a,b,c,d,e){if(!c||1>c.length)return a.ya(new t(2,4,4012)),{};a.b.abr.manager.setVariants(c);a.b.abr.manager.setTextStreams(d);var f=[];e&&(f=["video","audio"],b.textStreams.length&&f.push("text"));e=vf(a.a);var g=a.a;var h=g.c.video||g.c.audio;g=h?g.b.periods[h.wa]:null;if(b=fc(e.audio,e.video,g?g.variants:b.variants)){b.allowedByApplication&&b.allowedByKeySystem||(f.push("audio"),f.push("video"));for(var l in e)b=e[l],"audio"==b.type&&b.language!=c[0].language?f.push(l):"text"==b.type&&
- 0<d.length&&b.language!=d[0].language&&f.push(l)}f=f.filter(Aa);if(0<f.length){c={};try{c=a.b.abr.manager.chooseStreams(f)}catch(m){a.ya(m)}return c}return{}}function Ag(a,b){var c={audio:!1,text:!1},d=dc(b,a.ia,c,a.mb),e=ec(b,a.Ca,c,a.lb),d=Hg(a,b,d,e),f;for(f in d)Cg(a,d[f],!0);Dg(a,d,!0);xg(a);d.text&&d.audio&&c.text&&d.text.language!=d.audio.language&&(a.A.mode="showing",Fg(a))}
- k.ed=function(a){this.Za=!0;this.b.abr.manager.disable();var b=dc(a,this.ia,void 0,this.mb),c=ec(a,this.Ca,void 0,this.lb);a=Hg(this,a,b,c,!0);for(var d in this.G)a[d]=this.G[d].stream;this.G={};for(d in a)Cg(this,a[d],!0);return a};k.Gc=function(){this.Za=!1;this.b.abr.enabled&&this.b.abr.manager.enable();for(var a in this.G){var b=this.G[a];yf(this.a,a,b.stream,b.Kc)}this.G={}};k.ld=function(){this.h&&this.h.update&&this.h.update()};k.ud=function(){this.g&&this.g.Ab()};
- k.Lb=function(a,b){var c=vf(this.a),d;for(d in a){var e=a[d];c[d]!=e?Cg(this,e,!0):delete a[d]}if(!Ma(a)&&this.a){for(d in a)yf(this.a,d,a[d],b||!1);xg(this)}};function xg(a){Promise.resolve().then(function(){this.O||this.dispatchEvent(new I("adaptation"))}.bind(a))}function wg(a){Promise.resolve().then(function(){this.O||this.dispatchEvent(new I("trackschanged"))}.bind(a))}function Fg(a){a.dispatchEvent(new I("texttrackvisibility"))}k.ya=function(a){this.O||this.dispatchEvent(new I("error",{detail:a}))};
- k.xd=function(a){this.v?this.v.v(a):this.Xa.push(a)};k.gb=function(a){this.dispatchEvent(a)};k.yd=function(){if(this.f.error){var a=this.f.error.code;if(1!=a){var b=this.f.error.msExtendedCode;b&&(0>b&&(b+=Math.pow(2,32)),b=b.toString(16));this.ya(new t(2,3,3016,a,b))}}};
- k.be=function(a){var b=["output-restricted","internal-error"],c=V(this.a),d=!1;c.variants.forEach(function(c){var e=[];c.audio&&e.push(c.audio);c.video&&e.push(c.video);e.forEach(function(e){var f=c.allowedByKeySystem;e.keyId&&(e=a[e.keyId],c.allowedByKeySystem=!!e&&0>b.indexOf(e));f!=c.allowedByKeySystem&&(d=!0)})});var e=vf(this.a);(e=fc(e.audio,e.video,c.variants))&&!e.allowedByKeySystem&&Ag(this,c);d&&wg(this)};
- k.ae=function(a,b){if(this.h&&this.h.onExpirationUpdated)this.h.onExpirationUpdated(a,b);this.dispatchEvent(new I("expirationupdated"))};function X(a){if(!a||a.constructor!=W)throw new t(2,9,9008);this.a=fg();this.f=a;this.i=Ig(this);this.b=null;this.v=!1;this.j=null;this.g=-1;this.l=0;this.c=null;this.h=new gg(this.a,a.o,a.getConfiguration().streaming.retryParameters,this.i)}n("shaka.offline.Storage",X);function Jg(){return!!window.indexedDB}X.support=Jg;X.prototype.m=function(){var a=this.a,b=this.h?this.h.m()["catch"](function(){}).then(function(){if(a)return a.m()}):Promise.resolve();this.i=this.f=this.h=this.a=null;return b};
- X.prototype.destroy=X.prototype.m;X.prototype.configure=function(a){Ca(this.i,a,Ig(this),{},"")};X.prototype.configure=X.prototype.configure;
- X.prototype.le=function(a,b,c){function d(a){f=a}if(this.v)return Promise.reject(new t(2,9,9006));this.v=!0;var e,f=null;return Kg(this).then(function(){Y(this);return Lg(this,a,d,c)}.bind(this)).then(function(c){Y(this);this.c=c.manifest;this.b=c.Lc;if(this.c.presentationTimeline.$()||this.c.presentationTimeline.va())throw new t(2,9,9005,a);this.c.periods.forEach(this.o.bind(this));this.g=this.a.c.manifest++;this.l=0;c=this.c.periods.map(this.B.bind(this));var d=this.b.b,f=jb(this.b);if(d){if(!f.length)throw new t(2,
- 9,9007,a);d.initData=[]}e={key:this.g,originalManifestUri:a,duration:this.l,size:0,expiration:this.b.ab(),periods:c,sessionIds:f,drmInfo:d,appMetadata:b};return ig(this.h,e)}.bind(this)).then(function(){Y(this);if(f)throw f;return Mg(this)}.bind(this)).then(function(){return $f(e)}.bind(this))["catch"](function(a){return Mg(this)["catch"](y).then(function(){throw a;})}.bind(this))};X.prototype.store=X.prototype.le;
- X.prototype.remove=function(a){function b(a){6013!=a.code&&(e=a)}var c=a.offlineUri,d=/^offline:([0-9]+)$/.exec(c);if(!d)return Promise.reject(new t(2,9,9004,c));var e=null,f,g,h=Number(d[1]);return Kg(this).then(function(){Y(this);return this.a.get("manifest",h)}.bind(this)).then(function(a){Y(this);if(!a)throw new t(2,9,9003,c);f=a;a=lg(f);g=new bb(this.f.o,b,function(){},function(){});g.configure(this.f.getConfiguration().drm);return g.init(a,!0)}.bind(this)).then(function(){return gb(g,f.sessionIds)}.bind(this)).then(function(){return g.m()}.bind(this)).then(function(){Y(this);
- if(e)throw e;var b=f.periods.map(function(a){return a.streams.map(function(a){var b=a.segments.map(function(a){a=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a.uri);return Number(a[1])});a.initSegmentUri&&(a=/^offline:[0-9]+\/[0-9]+\/([0-9]+)$/.exec(a.initSegmentUri),b.push(Number(a[1])));return b}).reduce(x,[])}).reduce(x,[]),c=0,d=b.length,g=this.i.progressCallback;return Xf(this.a,b,function(){c++;g(a,c/d)})}.bind(this)).then(function(){Y(this);this.i.progressCallback(a,1);return this.a.remove("manifest",
- h)}.bind(this))};X.prototype.remove=X.prototype.remove;X.prototype.list=function(){var a=[];return Kg(this).then(function(){Y(this);return this.a.forEach("manifest",function(b){a.push($f(b))})}.bind(this)).then(function(){return a})};X.prototype.list=X.prototype.list;
- function Lg(a,b,c,d){function e(){}var f=a.f.o,g=a.f.getConfiguration(),h,l,m;return Gd(b,f,g.manifest.retryParameters,d).then(function(a){Y(this);m=new a;m.configure(g.manifest);return m.start(b,{networkingEngine:f,filterPeriod:this.o.bind(this),onTimelineRegionAdded:function(){},onEvent:function(){},onError:c})}.bind(a)).then(function(a){Y(this);h=a;l=new bb(f,c,e,function(){});l.configure(g.drm);return l.init(h,!0)}.bind(a)).then(function(){Y(this);return Ng(h)}.bind(a)).then(function(){Y(this);
- return fb(l)}.bind(a)).then(function(){Y(this);return m.stop()}.bind(a)).then(function(){Y(this);return{manifest:h,Lc:l}}.bind(a))["catch"](function(a){if(m)return m.stop().then(function(){throw a;});throw a;})}
- X.prototype.A=function(a){for(var b=[],c=Sb(this.f.getConfiguration().preferredAudioLanguage),d=[0,Qb,Rb],e=a.filter(function(a){return"variant"==a.type}),d=d.map(function(a){return e.filter(function(b){b=Sb(b.language);return Pb(a,c,b)})}),f,g=0;g<d.length;g++)if(d[g].length){f=d[g];break}f||(d=e.filter(function(a){return a.primary}),d.length&&(f=d));f||(f=e,e.map(function(a){return a.language}).filter(Aa));var h=f.filter(function(a){return a.height&&480>=a.height});h.length&&(h.sort(function(a,
- b){return b.height-a.height}),f=h.filter(function(a){return a.height==h[0].height}));f.sort(function(a,b){return a.bandwidth-b.bandwidth});f.length&&b.push(f[Math.floor(f.length/2)]);b.push.apply(b,a.filter(function(a){return"text"==a.type}));return b};function Ig(a){return{trackSelectionCallback:a.A.bind(a),progressCallback:function(a,c){if(a||c)return null}}}function Kg(a){return a.a?a.a.a?Promise.resolve():a.a.init(Zf):Promise.reject(new t(2,9,9E3))}
- X.prototype.o=function(a){var b={};if(this.j){var c=this.j.filter(function(a){return"variant"==a.type}),d=null;c.length&&(d=bc(a,c[0]));d&&(d.video&&(b.video=d.video),d.audio&&(b.audio=d.audio))}Wb(this.b,b,a);Vb(a,this.f.getConfiguration().restrictions,{width:Infinity,height:Infinity})};function Mg(a){var b=a.b?a.b.m():Promise.resolve();a.b=null;a.c=null;a.v=!1;a.j=null;a.g=-1;return b}
- function Ng(a){var b=a.periods.map(function(a){return a.variants}).reduce(x,[]).map(function(a){var b=[];a.audio&&b.push(a.audio);a.video&&b.push(a.video);return b}).reduce(x,[]).filter(Aa);a=a.periods.map(function(a){return a.textStreams}).reduce(x,[]);b.push.apply(b,a);return Promise.all(b.map(function(a){return a.createSegmentIndex()}))}
- X.prototype.B=function(a){var b,c,d=Zb(a,null,null),e=ac(a,null),d=this.i.trackSelectionCallback(d.concat(e));this.j||(this.j=d,this.c.periods.forEach(this.o.bind(this)));for(e=d.length-1;0<e;--e){var f=!1;for(c=e-1;0<=c;--c)if(d[e].type==d[c].type&&d[e].kind==d[c].kind&&d[e].language==d[c].language){f=!0;break}if(f)break}f=[];for(e=0;e<d.length;e++)(b=bc(a,d[e]))?(b.audio&&((c=f.filter(function(a){return a.id==b.audio.id})[0])?c.variantIds.push(b.id):(c=b.video?b.bandwidth/2:b.bandwidth,f.push(Og(this,
- a,b.audio,c,b.id)))),b.video&&((c=f.filter(function(a){return a.id==b.video.id})[0])?c.variantIds.push(b.id):(c=b.audio?b.bandwidth/2:b.bandwidth,f.push(Og(this,a,b.video,c,b.id))))):f.push(Og(this,a,cc(a,d[e]),0));return{startTime:a.startTime,streams:f}};
- function Og(a,b,c,d,e){var f=[],g=a.c.presentationTimeline.ma();var h=g;for(var l=c.findSegmentPosition(g),m=null!=l?c.getSegmentReference(l):null;m;)h=a.a.c.segment++,hg(a.h,c.type,m,(m.endTime-m.startTime)*d/8,{key:h,data:null,manifestKey:a.g,streamNumber:c.id,segmentNumber:h}),f.push({startTime:m.startTime,endTime:m.endTime,uri:"offline:"+a.g+"/"+c.id+"/"+h}),h=m.endTime+b.startTime,m=c.getSegmentReference(++l);a.l=Math.max(a.l,h-g);b=null;c.initSegmentReference&&(h=a.a.c.segment++,b="offline:"+
- a.g+"/"+c.id+"/"+h,hg(a.h,c.contentType,c.initSegmentReference,0,{key:h,data:null,manifestKey:a.g,streamNumber:c.id,segmentNumber:-1}));a=[];null!=e&&a.push(e);return{id:c.id,primary:c.primary,presentationTimeOffset:c.presentationTimeOffset||0,contentType:c.type,mimeType:c.mimeType,codecs:c.codecs,frameRate:c.frameRate,kind:c.kind,language:c.language,label:c.label,width:c.width||null,height:c.height||null,initSegmentUri:b,encrypted:c.encrypted,keyId:c.keyId,segments:f,variantIds:a}}
- function Y(a){if(!a.f)throw new t(2,9,9002);}tg.offline=Jg;n("shaka.polyfill.installAll",function(){for(var a=0;a<Pg.length;++a)Pg[a]()});var Pg=[];function Qg(a){Pg.push(a)}n("shaka.polyfill.register",Qg);function Rg(a){var b=a.type.replace(/^(webkit|moz|MS)/,"").toLowerCase();if("function"===typeof Event)var c=new Event(b,a);else c=document.createEvent("Event"),c.initEvent(b,a.bubbles,a.cancelable);a.target.dispatchEvent(c)}
- Qg(function(){if(window.Document){var a=Element.prototype;a.requestFullscreen=a.requestFullscreen||a.mozRequestFullScreen||a.msRequestFullscreen||a.webkitRequestFullscreen;a=Document.prototype;a.exitFullscreen=a.exitFullscreen||a.mozCancelFullScreen||a.msExitFullscreen||a.webkitExitFullscreen;"fullscreenElement"in document||(Object.defineProperty(document,"fullscreenElement",{get:function(){return document.mozFullScreenElement||document.msFullscreenElement||document.webkitFullscreenElement}}),Object.defineProperty(document,
- "fullscreenEnabled",{get:function(){return document.mozFullScreenEnabled||document.msFullscreenEnabled||document.webkitFullscreenEnabled}}));document.addEventListener("webkitfullscreenchange",Rg);document.addEventListener("webkitfullscreenerror",Rg);document.addEventListener("mozfullscreenchange",Rg);document.addEventListener("mozfullscreenerror",Rg);document.addEventListener("MSFullscreenChange",Rg);document.addEventListener("MSFullscreenError",Rg)}});Qg(function(){var a=navigator.userAgent;a&&0<=a.indexOf("CrKey")&&delete window.indexedDB});Qg(function(){if(4503599627370497!=Math.round(4503599627370497)){var a=Math.round;Math.round=function(b){var c=b;4503599627370496>=b&&(c=a(b));return c}}});function Sg(a){this.f=[];this.b=[];this.a=[];(new Q).da("pssh",this.c.bind(this)).parse(a.buffer)}Sg.prototype.c=function(a){if(!(1<a.version)){var b=$a(a.s.Ka(16)),c=[];if(0<a.version)for(var d=a.s.D(),e=0;e<d;++e){var f=$a(a.s.Ka(16));c.push(f)}d=a.s.D();a.s.I(d);this.b.push.apply(this.b,c);this.f.push(b);this.a.push({start:a.start,end:a.start+a.size-1})}};function Tg(a,b){try{var c=new Ug(a,b);return Promise.resolve(c)}catch(d){return Promise.reject(d)}}
- function Ug(a,b){this.keySystem=a;for(var c=!1,d=0;d<b.length;++d){var e=b[d];var f={audioCapabilities:[],videoCapabilities:[],persistentState:"optional",distinctiveIdentifier:"optional",initDataTypes:e.initDataTypes,sessionTypes:["temporary"],label:e.label},g=!1;if(e.audioCapabilities)for(var h=0;h<e.audioCapabilities.length;++h){var l=e.audioCapabilities[h];if(l.contentType){g=!0;var m=l.contentType.split(";")[0];MSMediaKeys.isTypeSupported(this.keySystem,m)&&(f.audioCapabilities.push(l),c=!0)}}if(e.videoCapabilities)for(h=
- 0;h<e.videoCapabilities.length;++h)l=e.videoCapabilities[h],l.contentType&&(g=!0,m=l.contentType.split(";")[0],MSMediaKeys.isTypeSupported(this.keySystem,m)&&(f.videoCapabilities.push(l),c=!0));g||(c=MSMediaKeys.isTypeSupported(this.keySystem,"video/mp4"));"required"==e.persistentState&&(f.persistentState="required",f.sessionTypes=["persistent-license"]);if(c){this.a=f;return}}e=Error("Unsupported keySystem");e.name="NotSupportedError";e.code=DOMException.NOT_SUPPORTED_ERR;throw e;}
- Ug.prototype.createMediaKeys=function(){var a=new Vg(this.keySystem);return Promise.resolve(a)};Ug.prototype.getConfiguration=function(){return this.a};function Wg(a){var b=this.mediaKeys;b&&b!=a&&Xg(b,null);delete this.mediaKeys;return(this.mediaKeys=a)?Xg(a,this):Promise.resolve()}function Vg(a){this.a=new MSMediaKeys(a);this.b=new D}Vg.prototype.createSession=function(a){if("temporary"!=(a||"temporary"))throw new TypeError("Session type "+a+" is unsupported on this platform.");return new Yg(this.a)};
- Vg.prototype.setServerCertificate=function(){return Promise.resolve(!1)};function Xg(a,b){function c(){b.msSetMediaKeys(d.a);b.removeEventListener("loadedmetadata",c)}Ja(a.b);if(!b)return Promise.resolve();E(a.b,b,"msneedkey",Zg);var d=a;try{return 1<=b.readyState?b.msSetMediaKeys(a.a):b.addEventListener("loadedmetadata",c),Promise.resolve()}catch(e){return Promise.reject(e)}}
- function Yg(a){p.call(this);this.c=null;this.g=a;this.b=this.a=null;this.f=new D;this.sessionId="";this.expiration=NaN;this.closed=new A;this.keyStatuses=new $g}ba(Yg);k=Yg.prototype;k.generateRequest=function(a,b){this.a=new A;try{this.c=this.g.createSession("video/mp4",new Uint8Array(b),null),E(this.f,this.c,"mskeymessage",this.pd.bind(this)),E(this.f,this.c,"mskeyadded",this.nd.bind(this)),E(this.f,this.c,"mskeyerror",this.od.bind(this)),ah(this,"status-pending")}catch(c){this.a.reject(c)}return this.a};
- k.load=function(){return Promise.reject(Error("MediaKeySession.load not yet supported"))};k.update=function(a){this.b=new A;try{this.c.update(new Uint8Array(a))}catch(b){this.b.reject(b)}return this.b};k.close=function(){try{this.c.close(),this.closed.resolve(),Ja(this.f)}catch(a){this.closed.reject(a)}return this.closed};k.remove=function(){return Promise.reject(Error("MediaKeySession.remove is only applicable for persistent licenses, which are not supported on this platform"))};
- function Zg(a){var b=document.createEvent("CustomEvent");b.initCustomEvent("encrypted",!1,!1,null);b.initDataType="cenc";var c=a.initData;if(c){var d=new Sg(c);if(1>=d.a.length)a=c;else{var e=[];for(a=0;a<d.a.length;a++)e.push(c.subarray(d.a[a].start,d.a[a].end+1));c=Ga(e,bh);for(a=d=0;a<c.length;a++)d+=c[a].length;d=new Uint8Array(d);for(a=e=0;a<c.length;a++)d.set(c[a],e),e+=c[a].length;a=d}}else a=c;b.initData=a;this.dispatchEvent(b)}function bh(a,b){return ab(a,b)}
- k.pd=function(a){this.a&&(this.a.resolve(),this.a=null);this.dispatchEvent(new I("message",{messageType:void 0==this.keyStatuses.sb()?"licenserequest":"licenserenewal",message:a.message.buffer}))};k.nd=function(){this.a?(ah(this,"usable"),this.a.resolve(),this.a=null):this.b&&(ah(this,"usable"),this.b.resolve(),this.b=null)};
- k.od=function(){var a=Error("EME PatchedMediaKeysMs key error");a.errorCode=this.c.error;if(this.a)this.a.reject(a),this.a=null;else if(this.b)this.b.reject(a),this.b=null;else switch(this.c.error.code){case MSMediaKeyError.MS_MEDIA_KEYERR_OUTPUT:case MSMediaKeyError.MS_MEDIA_KEYERR_HARDWARECHANGE:ah(this,"output-not-allowed");default:ah(this,"internal-error")}};function ah(a,b){a.keyStatuses.Kb(b);a.dispatchEvent(new I("keystatuseschange"))}function $g(){this.size=0;this.a=void 0}var ch;k=$g.prototype;
- k.Kb=function(a){this.size=void 0==a?0:1;this.a=a};k.sb=function(){return this.a};k.forEach=function(a){this.a&&a(this.a,ch)};k.get=function(a){if(this.has(a))return this.a};k.has=function(a){var b=ch;return this.a&&ab(new Uint8Array(a),new Uint8Array(b))?!0:!1};k.entries=function(){};k.keys=function(){};k.values=function(){};function dh(){return Promise.reject(Error("The key system specified is not supported."))}function eh(a){return a?Promise.reject(Error("MediaKeys not supported.")):Promise.resolve()}function fh(){throw new TypeError("Illegal constructor.");}fh.prototype.createSession=function(){};fh.prototype.setServerCertificate=function(){};function gh(){throw new TypeError("Illegal constructor.");}gh.prototype.getConfiguration=function(){};gh.prototype.createMediaKeys=function(){};var hh="";function ih(a){hh=a;jh=(new Uint8Array([0])).buffer;navigator.requestMediaKeySystemAccess=kh;delete HTMLMediaElement.prototype.mediaKeys;HTMLMediaElement.prototype.mediaKeys=null;HTMLMediaElement.prototype.setMediaKeys=lh;window.MediaKeys=mh;window.MediaKeySystemAccess=nh}function oh(a){var b=hh;return b?b+a.charAt(0).toUpperCase()+a.slice(1):a}function kh(a,b){try{var c=new nh(a,b);return Promise.resolve(c)}catch(d){return Promise.reject(d)}}
- function lh(a){var b=this.mediaKeys;b&&b!=a&&ph(b,null);delete this.mediaKeys;(this.mediaKeys=a)&&ph(a,this);return Promise.resolve()}
- function nh(a,b){this.a=this.keySystem=a;var c=!0;"org.w3.clearkey"==a&&(this.a="webkit-org.w3.clearkey",c=!1);var d=!1;var e=document.getElementsByTagName("video");var f=e.length?e[0]:document.createElement("video");for(var g=0;g<b.length;++g){e=b[g];var h={audioCapabilities:[],videoCapabilities:[],persistentState:"optional",distinctiveIdentifier:"optional",initDataTypes:e.initDataTypes,sessionTypes:["temporary"],label:e.label},l=!1;if(e.audioCapabilities)for(var m=0;m<e.audioCapabilities.length;++m){var q=
- e.audioCapabilities[m];if(q.contentType){var l=!0,r=q.contentType.split(";")[0];f.canPlayType(r,this.a)&&(h.audioCapabilities.push(q),d=!0)}}if(e.videoCapabilities)for(m=0;m<e.videoCapabilities.length;++m)q=e.videoCapabilities[m],q.contentType&&(l=!0,f.canPlayType(q.contentType,this.a)&&(h.videoCapabilities.push(q),d=!0));l||(d=f.canPlayType("video/mp4",this.a)||f.canPlayType("video/webm",this.a));"required"==e.persistentState&&(c?(h.persistentState="required",h.sessionTypes=["persistent-license"]):
- d=!1);if(d){this.b=h;return}}c="Unsupported keySystem";if("org.w3.clearkey"==a||"com.widevine.alpha"==a)c="None of the requested configurations were supported.";c=Error(c);c.name="NotSupportedError";c.code=DOMException.NOT_SUPPORTED_ERR;throw c;}nh.prototype.createMediaKeys=function(){var a=new mh(this.a);return Promise.resolve(a)};nh.prototype.getConfiguration=function(){return this.b};function mh(a){this.g=a;this.b=null;this.a=new D;this.c=[];this.f={}}
- function ph(a,b){a.b=b;Ja(a.a);var c=hh;b&&(E(a.a,b,c+"needkey",a.Cd.bind(a)),E(a.a,b,c+"keymessage",a.Bd.bind(a)),E(a.a,b,c+"keyadded",a.zd.bind(a)),E(a.a,b,c+"keyerror",a.Ad.bind(a)))}k=mh.prototype;k.createSession=function(a){var b=a||"temporary";if("temporary"!=b&&"persistent-license"!=b)throw new TypeError("Session type "+a+" is unsupported on this platform.");a=this.b||document.createElement("video");a.src||(a.src="about:blank");b=new qh(a,this.g,b);this.c.push(b);return b};
- k.setServerCertificate=function(){return Promise.resolve(!1)};k.Cd=function(a){var b=document.createEvent("CustomEvent");b.initCustomEvent("encrypted",!1,!1,null);b.initDataType="webm";b.initData=a.initData;this.b.dispatchEvent(b)};k.Bd=function(a){var b=rh(this,a.sessionId);b&&(a=new I("message",{messageType:void 0==b.keyStatuses.sb()?"licenserequest":"licenserenewal",message:a.message}),b.b&&(b.b.resolve(),b.b=null),b.dispatchEvent(a))};
- k.zd=function(a){if(a=rh(this,a.sessionId))sh(a,"usable"),a.a&&a.a.resolve(),a.a=null};
- k.Ad=function(a){var b=rh(this,a.sessionId);if(b){var c=Error("EME v0.1b key error");c.errorCode=a.errorCode;c.errorCode.systemCode=a.systemCode;!a.sessionId&&b.b?(c.method="generateRequest",45==a.systemCode&&(c.message="Unsupported session type."),b.b.reject(c),b.b=null):a.sessionId&&b.a?(c.method="update",b.a.reject(c),b.a=null):(c=a.systemCode,a.errorCode.code==MediaKeyError.MEDIA_KEYERR_OUTPUT?sh(b,"output-restricted"):1==c?sh(b,"expired"):sh(b,"internal-error"))}};
- function rh(a,b){var c=a.f[b];return c?c:(c=a.c.shift())?(c.sessionId=b,a.f[b]=c):null}function qh(a,b,c){p.call(this);this.f=a;this.h=!1;this.a=this.b=null;this.c=b;this.g=c;this.sessionId="";this.expiration=NaN;this.closed=new A;this.keyStatuses=new th}ba(qh);
- function uh(a,b,c){if(a.h)return Promise.reject(Error("The session is already initialized."));a.h=!0;try{if("persistent-license"==a.g)if(c)var d=new Uint8Array(Ua("LOAD_SESSION|"+c));else{var e=Ua("PERSISTENT|"),f=new Uint8Array(e.byteLength+b.byteLength);f.set(new Uint8Array(e),0);f.set(new Uint8Array(b),e.byteLength);d=f}else d=new Uint8Array(b)}catch(h){return Promise.reject(h)}a.b=new A;var g=oh("generateKeyRequest");try{a.f[g](a.c,d)}catch(h){if("InvalidStateError"!=h.name)return a.b=null,Promise.reject(h);
- setTimeout(function(){try{this.f[g](this.c,d)}catch(l){this.b.reject(l),this.b=null}}.bind(a),10)}return a.b}k=qh.prototype;
- k.Mb=function(a,b){if(this.a)this.a.then(this.Mb.bind(this,a,b))["catch"](this.Mb.bind(this,a,b));else{this.a=a;if("webkit-org.w3.clearkey"==this.c){var c=F(b);var d=JSON.parse(c);"oct"!=d.keys[0].kty&&(this.a.reject(Error("Response is not a valid JSON Web Key Set.")),this.a=null);c=Ya(d.keys[0].k);d=Ya(d.keys[0].kid)}else c=new Uint8Array(b),d=null;var e=oh("addKey");try{this.f[e](this.c,c,d,this.sessionId)}catch(f){this.a.reject(f),this.a=null}}};
- function sh(a,b){a.keyStatuses.Kb(b);a.dispatchEvent(new I("keystatuseschange"))}k.generateRequest=function(a,b){return uh(this,b,null)};k.load=function(a){return"persistent-license"==this.g?uh(this,null,a):Promise.reject(Error("Not a persistent session."))};k.update=function(a){var b=new A;this.Mb(b,a);return b};
- k.close=function(){if("persistent-license"!=this.g){if(!this.sessionId)return this.closed.reject(Error("The session is not callable.")),this.closed;var a=oh("cancelKeyRequest");try{this.f[a](this.c,this.sessionId)}catch(b){}}this.closed.resolve();return this.closed};k.remove=function(){return"persistent-license"!=this.g?Promise.reject(Error("Not a persistent session.")):this.close()};function th(){this.size=0;this.a=void 0}var jh;k=th.prototype;k.Kb=function(a){this.size=void 0==a?0:1;this.a=a};
- k.sb=function(){return this.a};k.forEach=function(a){this.a&&a(this.a,jh)};k.get=function(a){if(this.has(a))return this.a};k.has=function(a){var b=jh;return this.a&&ab(new Uint8Array(a),new Uint8Array(b))?!0:!1};k.entries=function(){};k.keys=function(){};k.values=function(){};Qg(function(){!window.HTMLVideoElement||navigator.requestMediaKeySystemAccess&&MediaKeySystemAccess.prototype.getConfiguration||(HTMLMediaElement.prototype.webkitGenerateKeyRequest?ih("webkit"):HTMLMediaElement.prototype.generateKeyRequest?ih(""):window.MSMediaKeys?(ch=(new Uint8Array([0])).buffer,delete HTMLMediaElement.prototype.mediaKeys,HTMLMediaElement.prototype.mediaKeys=null,HTMLMediaElement.prototype.setMediaKeys=Wg,window.MediaKeys=Vg,window.MediaKeySystemAccess=Ug,navigator.requestMediaKeySystemAccess=
- Tg):(navigator.requestMediaKeySystemAccess=dh,delete HTMLMediaElement.prototype.mediaKeys,HTMLMediaElement.prototype.mediaKeys=null,HTMLMediaElement.prototype.setMediaKeys=eh,window.MediaKeys=fh,window.MediaKeySystemAccess=gh))});function vh(){var a=MediaSource.prototype.addSourceBuffer;MediaSource.prototype.addSourceBuffer=function(){var b=a.apply(this,arguments);b.abort=function(){};return b}}
- function wh(){var a=MediaSource.prototype.endOfStream;MediaSource.prototype.endOfStream=function(){for(var b,d=0,e=0;e<this.sourceBuffers.length;++e)b=this.sourceBuffers[e],b=b.buffered.end(b.buffered.length-1),d=Math.max(d,b);if(!isNaN(this.duration)&&d<this.duration)for(this.Zb=!0,e=0;e<this.sourceBuffers.length;++e)b=this.sourceBuffers[e],b.Tb=!1;return a.apply(this,arguments)};var b=MediaSource.prototype.addSourceBuffer;MediaSource.prototype.addSourceBuffer=function(){var a=b.apply(this,arguments);
- a.N=this;a.addEventListener("updateend",xh,!1);this.a||(this.addEventListener("sourceclose",yh,!1),this.a=!0);return a}}function xh(a){var b=a.target,c=b.N;if(c.Zb){a.preventDefault();a.stopPropagation();a.stopImmediatePropagation();b.Tb=!0;for(a=0;a<c.sourceBuffers.length;++a)if(0==c.sourceBuffers[a].Tb)return;c.Zb=!1}}function yh(a){a=a.target;for(var b=0;b<a.sourceBuffers.length;++b)a.sourceBuffers[b].removeEventListener("updateend",xh,!1);a.removeEventListener("sourceclose",yh,!1)}
- Qg(function(){if(window.MediaSource){var a=navigator.vendor,b=navigator.appVersion;!a||!b||0>a.indexOf("Apple")||(0<=b.indexOf("Version/8")?window.MediaSource=null:0<=b.indexOf("Version/9")?vh():0<=b.indexOf("Version/10")&&(vh(),wh()))}});function Z(a){this.c=[];this.b=[];this.Aa=zh;if(a)try{a(this.fa.bind(this),this.a.bind(this))}catch(b){this.a(b)}}var zh=0;function Ah(a){var b=new Z;b.fa(void 0);return b.then(function(){return a})}function Bh(a){var b=new Z;b.a(a);return b}function Ch(a){function b(a,b,c){a.Aa==zh&&(e[b]=c,d++,d==e.length&&a.fa(e))}var c=new Z;if(!a.length)return c.fa([]),c;for(var d=0,e=Array(a.length),f=c.a.bind(c),g=0;g<a.length;++g)a[g]&&a[g].then?a[g].then(b.bind(null,c,g),f):b(c,g,a[g]);return c}
- function Dh(a){for(var b=new Z,c=b.fa.bind(b),d=b.a.bind(b),e=0;e<a.length;++e)a[e]&&a[e].then?a[e].then(c,d):c(a[e]);return b}Z.prototype.then=function(a,b){var c=new Z;switch(this.Aa){case 1:Eh(this,c,a);break;case 2:Eh(this,c,b);break;case zh:this.c.push({L:c,pb:a}),this.b.push({L:c,pb:b})}return c};Z.prototype["catch"]=function(a){return this.then(void 0,a)};
- Z.prototype.fa=function(a){if(this.Aa==zh){this.jb=a;this.Aa=1;for(a=0;a<this.c.length;++a)Eh(this,this.c[a].L,this.c[a].pb);this.c=[];this.b=[]}};Z.prototype.a=function(a){if(this.Aa==zh){this.jb=a;this.Aa=2;for(a=0;a<this.b.length;++a)Eh(this,this.b[a].L,this.b[a].pb);this.c=[];this.b=[]}};
- function Eh(a,b,c){Fh.push(function(){if(c&&"function"==typeof c){try{var a=c(this.jb)}catch(f){b.a(f);return}try{var e=a&&a.then}catch(f){b.a(f);return}a instanceof Z?a==b?b.a(new TypeError("Chaining cycle detected")):a.then(b.fa.bind(b),b.a.bind(b)):e?Gh(a,e,b):b.fa(a)}else 1==this.Aa?b.fa(this.jb):b.a(this.jb)}.bind(a));null==Hh&&(Hh=Ih(Jh))}
- function Gh(a,b,c){try{var d=!1;b.call(a,function(a){if(!d){d=!0;try{var b=a&&a.then}catch(g){c.a(g);return}b?Gh(a,b,c):c.fa(a)}},c.a.bind(c))}catch(e){c.a(e)}}function Jh(){for(;Fh.length;){null!=Hh&&(Kh(Hh),Hh=null);var a=Fh;Fh=[];for(var b=0;b<a.length;++b)a[b]()}}function Ih(){return 0}function Kh(){}var Hh=null,Fh=[];
- Qg(function(a){window.setImmediate?(Ih=function(a){return window.setImmediate(a)},Kh=function(a){return window.clearImmediate(a)}):(Ih=function(a){return window.setTimeout(a,0)},Kh=function(a){return window.clearTimeout(a)});if(!window.Promise||a)window.Promise=Z,window.Promise.resolve=Ah,window.Promise.reject=Bh,window.Promise.all=Ch,window.Promise.race=Dh,window.Promise.prototype.then=Z.prototype.then,window.Promise.prototype["catch"]=Z.prototype["catch"]});Qg(function(){if(window.HTMLMediaElement){var a=HTMLMediaElement.prototype.play;HTMLMediaElement.prototype.play=function(){var b=a.apply(this,arguments);b&&b["catch"](function(){});return b}}});function Lh(){return{droppedVideoFrames:this.webkitDroppedFrameCount,totalVideoFrames:this.webkitDecodedFrameCount,corruptedVideoFrames:0,creationTime:NaN,totalFrameDelay:0}}Qg(function(){if(window.HTMLVideoElement){var a=HTMLVideoElement.prototype;!a.getVideoPlaybackQuality&&"webkitDroppedFrameCount"in a&&(a.getVideoPlaybackQuality=Lh)}});function Mh(a,b,c){return new window.TextTrackCue(a,b,c)}function Nh(a,b,c){return new window.TextTrackCue(a+"-"+b+"-"+c,a,b,c)}Qg(function(){if(!window.VTTCue&&window.TextTrackCue){var a=TextTrackCue.length;if(3==a)window.VTTCue=Mh;else if(6==a)window.VTTCue=Nh;else{try{var b=!!Mh(1,2,"")}catch(c){b=!1}b&&(window.VTTCue=Mh)}}});}.call(g,this));
- if (typeof(module)!="undefined"&&module.exports)module.exports=g.shaka;
- else if (typeof(define)!="undefined" && define.amd)define(function(){return g.shaka});
- else this.shaka=g.shaka;
- })();
- },{}],6:[function(_dereq_,module,exports){
- // stats.js - http://github.com/mrdoob/stats.js
- var Stats=function(){var l=Date.now(),m=l,g=0,n=Infinity,o=0,h=0,p=Infinity,q=0,r=0,s=0,f=document.createElement("div");f.id="stats";f.addEventListener("mousedown",function(b){b.preventDefault();t(++s%2)},!1);f.style.cssText="width:80px;opacity:0.9;cursor:pointer";var a=document.createElement("div");a.id="fps";a.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#002";f.appendChild(a);var i=document.createElement("div");i.id="fpsText";i.style.cssText="color:#0ff;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";
- i.innerHTML="FPS";a.appendChild(i);var c=document.createElement("div");c.id="fpsGraph";c.style.cssText="position:relative;width:74px;height:30px;background-color:#0ff";for(a.appendChild(c);74>c.children.length;){var j=document.createElement("span");j.style.cssText="width:1px;height:30px;float:left;background-color:#113";c.appendChild(j)}var d=document.createElement("div");d.id="ms";d.style.cssText="padding:0 0 3px 3px;text-align:left;background-color:#020;display:none";f.appendChild(d);var k=document.createElement("div");
- k.id="msText";k.style.cssText="color:#0f0;font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px";k.innerHTML="MS";d.appendChild(k);var e=document.createElement("div");e.id="msGraph";e.style.cssText="position:relative;width:74px;height:30px;background-color:#0f0";for(d.appendChild(e);74>e.children.length;)j=document.createElement("span"),j.style.cssText="width:1px;height:30px;float:left;background-color:#131",e.appendChild(j);var t=function(b){s=b;switch(s){case 0:a.style.display=
- "block";d.style.display="none";break;case 1:a.style.display="none",d.style.display="block"}};return{REVISION:12,domElement:f,setMode:t,begin:function(){l=Date.now()},end:function(){var b=Date.now();g=b-l;n=Math.min(n,g);o=Math.max(o,g);k.textContent=g+" MS ("+n+"-"+o+")";var a=Math.min(30,30-30*(g/200));e.appendChild(e.firstChild).style.height=a+"px";r++;b>m+1E3&&(h=Math.round(1E3*r/(b-m)),p=Math.min(p,h),q=Math.max(q,h),i.textContent=h+" FPS ("+p+"-"+q+")",a=Math.min(30,30-30*(h/100)),c.appendChild(c.firstChild).style.height=
- a+"px",m=b,r=0);return b},update:function(){l=this.end()}}};"object"===typeof module&&(module.exports=Stats);
- },{}],7:[function(_dereq_,module,exports){
- (function (global){
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.WebVRManager = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof _dereq_=="function"&&_dereq_;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Emitter = _dereq_('./emitter.js');
- var Modes = _dereq_('./modes.js');
- var Util = _dereq_('./util.js');
- /**
- * Everything having to do with the WebVR button.
- * Emits a 'click' event when it's clicked.
- */
- function ButtonManager(opt_root) {
- var root = opt_root || document.body;
- this.loadIcons_();
- // Make the fullscreen button.
- var fsButton = this.createButton();
- fsButton.src = this.ICONS.fullscreen;
- fsButton.title = 'Fullscreen mode';
- var s = fsButton.style;
- s.bottom = '40px';
- s.right = 0;
- fsButton.addEventListener('click', this.createClickHandler_('fs'));
- root.appendChild(fsButton);
- this.fsButton = fsButton;
- // Make the VR button.
- var vrButton = this.createButton();
- vrButton.src = this.ICONS.cardboard;
- vrButton.title = 'Virtual reality mode';
- var s = vrButton.style;
- s.bottom = '40px';
- s.right = '48px';
- vrButton.addEventListener('click', this.createClickHandler_('vr'));
- root.appendChild(vrButton);
- this.vrButton = vrButton;
- this.isVisible = true;
- }
- ButtonManager.prototype = new Emitter();
- ButtonManager.prototype.createButton = function() {
- var button = document.createElement('img');
- button.className = 'webvr-button';
- var s = button.style;
- s.position = 'absolute';
- s.width = '24px'
- s.height = '24px';
- s.backgroundSize = 'cover';
- s.backgroundColor = 'transparent';
- s.border = 0;
- s.userSelect = 'none';
- s.webkitUserSelect = 'none';
- s.MozUserSelect = 'none';
- s.cursor = 'pointer';
- s.padding = '12px';
- s.zIndex = 1;
- s.display = 'none';
- s.boxSizing = 'content-box';
- // Prevent button from being selected and dragged.
- button.draggable = false;
- button.addEventListener('dragstart', function(e) {
- e.preventDefault();
- });
- // Style it on hover.
- button.addEventListener('mouseenter', function(e) {
- s.filter = s.webkitFilter = 'drop-shadow(0 0 5px rgba(255,255,255,1))';
- });
- button.addEventListener('mouseleave', function(e) {
- s.filter = s.webkitFilter = '';
- });
- return button;
- };
- ButtonManager.prototype.setMode = function(mode, isVRCompatible) {
- isVRCompatible = isVRCompatible || WebVRConfig.FORCE_ENABLE_VR;
- if (!this.isVisible) {
- return;
- }
- switch (mode) {
- case Modes.NORMAL:
- this.fsButton.style.display = 'none';
- this.fsButton.src = this.ICONS.fullscreen;
- this.vrButton.style.display = (isVRCompatible ? 'block' : 'none');
- break;
- case Modes.MAGIC_WINDOW:
- this.fsButton.style.display = 'block';
- this.fsButton.src = this.ICONS.exitFullscreen;
- this.vrButton.style.display = 'none';
- break;
- case Modes.VR:
- this.fsButton.style.display = 'none';
- this.vrButton.style.display = 'none';
- break;
- }
- // Hack for Safari Mac/iOS to force relayout (svg-specific issue)
- // http://goo.gl/hjgR6r
- var oldValue = this.fsButton.style.display;
- this.fsButton.style.display = 'inline-block';
- this.fsButton.offsetHeight;
- this.fsButton.style.display = oldValue;
- };
- ButtonManager.prototype.setVisibility = function(isVisible) {
- this.isVisible = isVisible;
- this.fsButton.style.display = isVisible ? 'block' : 'none';
- this.vrButton.style.display = isVisible ? 'block' : 'none';
- };
- ButtonManager.prototype.createClickHandler_ = function(eventName) {
- return function(e) {
- e.stopPropagation();
- e.preventDefault();
- this.emit(eventName);
- }.bind(this);
- };
- ButtonManager.prototype.loadIcons_ = function() {
- // Preload some hard-coded SVG.
- this.ICONS = {};
- this.ICONS.cardboard = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMjAuNzQgNkgzLjIxQzIuNTUgNiAyIDYuNTcgMiA3LjI4djEwLjQ0YzAgLjcuNTUgMS4yOCAxLjIzIDEuMjhoNC43OWMuNTIgMCAuOTYtLjMzIDEuMTQtLjc5bDEuNC0zLjQ4Yy4yMy0uNTkuNzktMS4wMSAxLjQ0LTEuMDFzMS4yMS40MiAxLjQ1IDEuMDFsMS4zOSAzLjQ4Yy4xOS40Ni42My43OSAxLjExLjc5aDQuNzljLjcxIDAgMS4yNi0uNTcgMS4yNi0xLjI4VjcuMjhjMC0uNy0uNTUtMS4yOC0xLjI2LTEuMjh6TTcuNSAxNC42MmMtMS4xNyAwLTIuMTMtLjk1LTIuMTMtMi4xMiAwLTEuMTcuOTYtMi4xMyAyLjEzLTIuMTMgMS4xOCAwIDIuMTIuOTYgMi4xMiAyLjEzcy0uOTUgMi4xMi0yLjEyIDIuMTJ6bTkgMGMtMS4xNyAwLTIuMTMtLjk1LTIuMTMtMi4xMiAwLTEuMTcuOTYtMi4xMyAyLjEzLTIuMTNzMi4xMi45NiAyLjEyIDIuMTMtLjk1IDIuMTItMi4xMiAyLjEyeiIvPgogICAgPHBhdGggZmlsbD0ibm9uZSIgZD0iTTAgMGgyNHYyNEgwVjB6Ii8+Cjwvc3ZnPgo=');
- this.ICONS.fullscreen = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNyAxNEg1djVoNXYtMkg3di0zem0tMi00aDJWN2gzVjVINXY1em0xMiA3aC0zdjJoNXYtNWgtMnYzek0xNCA1djJoM3YzaDJWNWgtNXoiLz4KPC9zdmc+Cg==');
- this.ICONS.exitFullscreen = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNNSAxNmgzdjNoMnYtNUg1djJ6bTMtOEg1djJoNVY1SDh2M3ptNiAxMWgydi0zaDN2LTJoLTV2NXptMi0xMVY1aC0ydjVoNVY4aC0zeiIvPgo8L3N2Zz4K');
- this.ICONS.settings = Util.base64('image/svg+xml', 'PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI0ZGRkZGRiI+CiAgICA8cGF0aCBkPSJNMCAwaDI0djI0SDB6IiBmaWxsPSJub25lIi8+CiAgICA8cGF0aCBkPSJNMTkuNDMgMTIuOThjLjA0LS4zMi4wNy0uNjQuMDctLjk4cy0uMDMtLjY2LS4wNy0uOThsMi4xMS0xLjY1Yy4xOS0uMTUuMjQtLjQyLjEyLS42NGwtMi0zLjQ2Yy0uMTItLjIyLS4zOS0uMy0uNjEtLjIybC0yLjQ5IDFjLS41Mi0uNC0xLjA4LS43My0xLjY5LS45OGwtLjM4LTIuNjVDMTQuNDYgMi4xOCAxNC4yNSAyIDE0IDJoLTRjLS4yNSAwLS40Ni4xOC0uNDkuNDJsLS4zOCAyLjY1Yy0uNjEuMjUtMS4xNy41OS0xLjY5Ljk4bC0yLjQ5LTFjLS4yMy0uMDktLjQ5IDAtLjYxLjIybC0yIDMuNDZjLS4xMy4yMi0uMDcuNDkuMTIuNjRsMi4xMSAxLjY1Yy0uMDQuMzItLjA3LjY1LS4wNy45OHMuMDMuNjYuMDcuOThsLTIuMTEgMS42NWMtLjE5LjE1LS4yNC40Mi0uMTIuNjRsMiAzLjQ2Yy4xMi4yMi4zOS4zLjYxLjIybDIuNDktMWMuNTIuNCAxLjA4LjczIDEuNjkuOThsLjM4IDIuNjVjLjAzLjI0LjI0LjQyLjQ5LjQyaDRjLjI1IDAgLjQ2LS4xOC40OS0uNDJsLjM4LTIuNjVjLjYxLS4yNSAxLjE3LS41OSAxLjY5LS45OGwyLjQ5IDFjLjIzLjA5LjQ5IDAgLjYxLS4yMmwyLTMuNDZjLjEyLS4yMi4wNy0uNDktLjEyLS42NGwtMi4xMS0xLjY1ek0xMiAxNS41Yy0xLjkzIDAtMy41LTEuNTctMy41LTMuNXMxLjU3LTMuNSAzLjUtMy41IDMuNSAxLjU3IDMuNSAzLjUtMS41NyAzLjUtMy41IDMuNXoiLz4KPC9zdmc+Cg==');
- };
- module.exports = ButtonManager;
- },{"./emitter.js":2,"./modes.js":3,"./util.js":4}],2:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- function Emitter() {
- this.callbacks = {};
- }
- Emitter.prototype.emit = function(eventName) {
- var callbacks = this.callbacks[eventName];
- if (!callbacks) {
- //console.log('No valid callback specified.');
- return;
- }
- var args = [].slice.call(arguments);
- // Eliminate the first param (the callback).
- args.shift();
- for (var i = 0; i < callbacks.length; i++) {
- callbacks[i].apply(this, args);
- }
- };
- Emitter.prototype.on = function(eventName, callback) {
- if (eventName in this.callbacks) {
- this.callbacks[eventName].push(callback);
- } else {
- this.callbacks[eventName] = [callback];
- }
- };
- module.exports = Emitter;
- },{}],3:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Modes = {
- UNKNOWN: 0,
- // Not fullscreen, just tracking.
- NORMAL: 1,
- // Magic window immersive mode.
- MAGIC_WINDOW: 2,
- // Full screen split screen VR mode.
- VR: 3,
- };
- module.exports = Modes;
- },{}],4:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = {};
- Util.base64 = function(mimeType, base64) {
- return 'data:' + mimeType + ';base64,' + base64;
- };
- Util.isMobile = function() {
- var check = false;
- (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
- return check;
- };
- Util.isFirefox = function() {
- return /firefox/i.test(navigator.userAgent);
- };
- Util.isIOS = function() {
- return /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
- };
- Util.isIFrame = function() {
- try {
- return window.self !== window.top;
- } catch (e) {
- return true;
- }
- };
- Util.appendQueryParameter = function(url, key, value) {
- // Determine delimiter based on if the URL already GET parameters in it.
- var delimiter = (url.indexOf('?') < 0 ? '?' : '&');
- url += delimiter + key + '=' + value;
- return url;
- };
- // From http://goo.gl/4WX3tg
- Util.getQueryParameter = function(name) {
- var name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
- var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
- results = regex.exec(location.search);
- return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
- };
- Util.isLandscapeMode = function() {
- return (window.orientation == 90 || window.orientation == -90);
- };
- Util.getScreenWidth = function() {
- return Math.max(window.screen.width, window.screen.height) *
- window.devicePixelRatio;
- };
- Util.getScreenHeight = function() {
- return Math.min(window.screen.width, window.screen.height) *
- window.devicePixelRatio;
- };
- module.exports = Util;
- },{}],5:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var ButtonManager = _dereq_('./button-manager.js');
- var Emitter = _dereq_('./emitter.js');
- var Modes = _dereq_('./modes.js');
- var Util = _dereq_('./util.js');
- /**
- * Helper for getting in and out of VR mode.
- */
- function WebVRManager(renderer, effect, params) {
- this.params = params || {};
- this.mode = Modes.UNKNOWN;
- // Set option to hide the button.
- this.hideButton = this.params.hideButton || false;
- // Whether or not the FOV should be distorted or un-distorted. By default, it
- // should be distorted, but in the case of vertex shader based distortion,
- // ensure that we use undistorted parameters.
- this.predistorted = !!this.params.predistorted;
- // Save the THREE.js renderer and effect for later.
- this.renderer = renderer;
- this.effect = effect;
- var polyfillWrapper = document.querySelector('.webvr-polyfill-fullscreen-wrapper');
- this.button = new ButtonManager(polyfillWrapper);
- this.isFullscreenDisabled = !!Util.getQueryParameter('no_fullscreen');
- this.startMode = Modes.NORMAL;
- var startModeParam = parseInt(Util.getQueryParameter('start_mode'));
- if (!isNaN(startModeParam)) {
- this.startMode = startModeParam;
- }
- if (this.hideButton) {
- this.button.setVisibility(false);
- }
- // Check if the browser is compatible with WebVR.
- this.getDeviceByType_(VRDisplay).then(function(hmd) {
- this.hmd = hmd;
- // Only enable VR mode if there's a VR device attached or we are running the
- // polyfill on mobile.
- if (!this.isVRCompatibleOverride) {
- this.isVRCompatible = !hmd.isPolyfilled || Util.isMobile();
- }
- switch (this.startMode) {
- case Modes.MAGIC_WINDOW:
- this.setMode_(Modes.MAGIC_WINDOW);
- break;
- case Modes.VR:
- this.enterVRMode_();
- this.setMode_(Modes.VR);
- break;
- default:
- this.setMode_(Modes.NORMAL);
- }
- this.emit('initialized');
- }.bind(this));
- // Hook up button listeners.
- this.button.on('fs', this.onFSClick_.bind(this));
- this.button.on('vr', this.onVRClick_.bind(this));
- // Bind to fullscreen events.
- document.addEventListener('webkitfullscreenchange',
- this.onFullscreenChange_.bind(this));
- document.addEventListener('mozfullscreenchange',
- this.onFullscreenChange_.bind(this));
- document.addEventListener('msfullscreenchange',
- this.onFullscreenChange_.bind(this));
- // Bind to VR* specific events.
- window.addEventListener('vrdisplaypresentchange',
- this.onVRDisplayPresentChange_.bind(this));
- window.addEventListener('vrdisplaydeviceparamschange',
- this.onVRDisplayDeviceParamsChange_.bind(this));
- }
- WebVRManager.prototype = new Emitter();
- // Expose these values externally.
- WebVRManager.Modes = Modes;
- WebVRManager.prototype.render = function(scene, camera, timestamp) {
- // Scene may be an array of two scenes, one for each eye.
- if (scene instanceof Array) {
- this.effect.render(scene[0], camera);
- } else {
- this.effect.render(scene, camera);
- }
- };
- WebVRManager.prototype.setVRCompatibleOverride = function(isVRCompatible) {
- this.isVRCompatible = isVRCompatible;
- this.isVRCompatibleOverride = true;
- // Don't actually change modes, just update the buttons.
- this.button.setMode(this.mode, this.isVRCompatible);
- };
- WebVRManager.prototype.setFullscreenCallback = function(callback) {
- this.fullscreenCallback = callback;
- };
- WebVRManager.prototype.setVRCallback = function(callback) {
- this.vrCallback = callback;
- };
- WebVRManager.prototype.setExitFullscreenCallback = function(callback) {
- this.exitFullscreenCallback = callback;
- }
- /**
- * Promise returns true if there is at least one HMD device available.
- */
- WebVRManager.prototype.getDeviceByType_ = function(type) {
- return new Promise(function(resolve, reject) {
- navigator.getVRDisplays().then(function(displays) {
- // Promise succeeds, but check if there are any displays actually.
- for (var i = 0; i < displays.length; i++) {
- if (displays[i] instanceof type) {
- resolve(displays[i]);
- break;
- }
- }
- resolve(null);
- }, function() {
- // No displays are found.
- resolve(null);
- });
- });
- };
- /**
- * Helper for entering VR mode.
- */
- WebVRManager.prototype.enterVRMode_ = function() {
- this.hmd.requestPresent([{
- source: this.renderer.domElement,
- predistorted: this.predistorted
- }]);
- };
- WebVRManager.prototype.setMode_ = function(mode) {
- var oldMode = this.mode;
- if (mode == this.mode) {
- console.warn('Not changing modes, already in %s', mode);
- return;
- }
- // console.log('Mode change: %s => %s', this.mode, mode);
- this.mode = mode;
- this.button.setMode(mode, this.isVRCompatible);
- // Emit an event indicating the mode changed.
- this.emit('modechange', mode, oldMode);
- };
- /**
- * Main button was clicked.
- */
- WebVRManager.prototype.onFSClick_ = function() {
- switch (this.mode) {
- case Modes.NORMAL:
- // TODO: Remove this hack if/when iOS gets real fullscreen mode.
- // If this is an iframe on iOS, break out and open in no_fullscreen mode.
- if (Util.isIOS() && Util.isIFrame()) {
- if (this.fullscreenCallback) {
- this.fullscreenCallback();
- } else {
- var url = window.location.href;
- url = Util.appendQueryParameter(url, 'no_fullscreen', 'true');
- url = Util.appendQueryParameter(url, 'start_mode', Modes.MAGIC_WINDOW);
- top.location.href = url;
- return;
- }
- }
- this.setMode_(Modes.MAGIC_WINDOW);
- this.requestFullscreen_();
- break;
- case Modes.MAGIC_WINDOW:
- if (this.isFullscreenDisabled) {
- window.history.back();
- return;
- }
- if (this.exitFullscreenCallback) {
- this.exitFullscreenCallback();
- }
- this.setMode_(Modes.NORMAL);
- this.exitFullscreen_();
- break;
- }
- };
- /**
- * The VR button was clicked.
- */
- WebVRManager.prototype.onVRClick_ = function() {
- // TODO: Remove this hack when iOS has fullscreen mode.
- // If this is an iframe on iOS, break out and open in no_fullscreen mode.
- if (this.mode == Modes.NORMAL && Util.isIOS() && Util.isIFrame()) {
- if (this.vrCallback) {
- this.vrCallback();
- } else {
- var url = window.location.href;
- url = Util.appendQueryParameter(url, 'no_fullscreen', 'true');
- url = Util.appendQueryParameter(url, 'start_mode', Modes.VR);
- top.location.href = url;
- return;
- }
- }
- this.enterVRMode_();
- };
- WebVRManager.prototype.requestFullscreen_ = function() {
- var canvas = document.body;
- //var canvas = this.renderer.domElement;
- if (canvas.requestFullscreen) {
- canvas.requestFullscreen();
- } else if (canvas.mozRequestFullScreen) {
- canvas.mozRequestFullScreen();
- } else if (canvas.webkitRequestFullscreen) {
- canvas.webkitRequestFullscreen();
- } else if (canvas.msRequestFullscreen) {
- canvas.msRequestFullscreen();
- }
- };
- WebVRManager.prototype.exitFullscreen_ = function() {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- }
- };
- WebVRManager.prototype.onVRDisplayPresentChange_ = function(e) {
- console.log('onVRDisplayPresentChange_', e);
- if (this.hmd.isPresenting) {
- this.setMode_(Modes.VR);
- } else {
- this.setMode_(Modes.NORMAL);
- }
- };
- WebVRManager.prototype.onVRDisplayDeviceParamsChange_ = function(e) {
- console.log('onVRDisplayDeviceParamsChange_', e);
- };
- WebVRManager.prototype.onFullscreenChange_ = function(e) {
- // If we leave full-screen, go back to normal mode.
- if (document.webkitFullscreenElement === null ||
- document.mozFullScreenElement === null) {
- this.setMode_(Modes.NORMAL);
- }
- };
- module.exports = WebVRManager;
- },{"./button-manager.js":1,"./emitter.js":2,"./modes.js":3,"./util.js":4}]},{},[5])(5)
- });
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{}],8:[function(_dereq_,module,exports){
- module.exports={
- "_args": [
- [
- "webvr-polyfill@^0.9.38",
- "/Users/lincolnfrog/daydream/vrview"
- ]
- ],
- "_from": "webvr-polyfill@>=0.9.38 <0.10.0",
- "_id": "webvr-polyfill@0.9.40",
- "_inCache": true,
- "_installable": true,
- "_location": "/webvr-polyfill",
- "_nodeVersion": "8.6.0",
- "_npmOperationalInternal": {
- "host": "s3://npm-registry-packages",
- "tmp": "tmp/webvr-polyfill-0.9.40.tgz_1507657755590_0.00047161197289824486"
- },
- "_npmUser": {
- "email": "jsantell@gmail.com",
- "name": "jsantell"
- },
- "_npmVersion": "5.3.0",
- "_phantomChildren": {},
- "_requested": {
- "name": "webvr-polyfill",
- "raw": "webvr-polyfill@^0.9.38",
- "rawSpec": "^0.9.38",
- "scope": null,
- "spec": ">=0.9.38 <0.10.0",
- "type": "range"
- },
- "_requiredBy": [
- "/",
- "/webvr-boilerplate"
- ],
- "_resolved": "https://registry.npmjs.org/webvr-polyfill/-/webvr-polyfill-0.9.40.tgz",
- "_shasum": "2cfa0ec0e0cc6ba7238c73a09cba4952fff59a63",
- "_shrinkwrap": null,
- "_spec": "webvr-polyfill@^0.9.38",
- "_where": "/Users/lincolnfrog/daydream/vrview",
- "authors": [
- "Boris Smus <boris@smus.com>",
- "Brandon Jones <tojiro@gmail.com>",
- "Jordan Santell <jordan@jsantell.com>"
- ],
- "bugs": {
- "url": "https://github.com/googlevr/webvr-polyfill/issues"
- },
- "dependencies": {},
- "description": "Use WebVR today, on mobile or desktop, without requiring a special browser build.",
- "devDependencies": {
- "chai": "^3.5.0",
- "jsdom": "^9.12.0",
- "mocha": "^3.2.0",
- "semver": "^5.3.0",
- "webpack": "^2.6.1",
- "webpack-dev-server": "2.7.1"
- },
- "directories": {},
- "dist": {
- "integrity": "sha512-m7jhJHjFcUYPyPSNeGmly7a2h/cP7bARz0OZMoUn5SueVXEKeZ4P7bzbAUDBDvvqCsa5gHgM3PFIhYe13bqaWw==",
- "shasum": "2cfa0ec0e0cc6ba7238c73a09cba4952fff59a63",
- "tarball": "https://registry.npmjs.org/webvr-polyfill/-/webvr-polyfill-0.9.40.tgz"
- },
- "gitHead": "45828ffdb8c3e0f9bb90296d6039d3cc7909ba8e",
- "homepage": "https://github.com/googlevr/webvr-polyfill",
- "keywords": [
- "vr",
- "webvr"
- ],
- "license": "Apache-2.0",
- "main": "src/node-entry",
- "maintainers": [
- {
- "email": "jsantell@gmail.com",
- "name": "jsantell"
- },
- {
- "email": "tojiro@gmail.com",
- "name": "toji"
- },
- {
- "email": "boris@smus.com",
- "name": "smus"
- }
- ],
- "name": "webvr-polyfill",
- "optionalDependencies": {},
- "readme": "ERROR: No README data found!",
- "repository": {
- "type": "git",
- "url": "git+https://github.com/googlevr/webvr-polyfill.git"
- },
- "scripts": {
- "build": "webpack",
- "start": "npm run watch",
- "test": "mocha",
- "watch": "webpack-dev-server"
- },
- "version": "0.9.40"
- }
- },{}],9:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('./util.js');
- var WakeLock = _dereq_('./wakelock.js');
- // Start at a higher number to reduce chance of conflict.
- var nextDisplayId = 1000;
- var hasShowDeprecationWarning = false;
- var defaultLeftBounds = [0, 0, 0.5, 1];
- var defaultRightBounds = [0.5, 0, 0.5, 1];
- /**
- * The base class for all VR frame data.
- */
- function VRFrameData() {
- this.leftProjectionMatrix = new Float32Array(16);
- this.leftViewMatrix = new Float32Array(16);
- this.rightProjectionMatrix = new Float32Array(16);
- this.rightViewMatrix = new Float32Array(16);
- this.pose = null;
- };
- /**
- * The base class for all VR displays.
- */
- function VRDisplay() {
- this.isPolyfilled = true;
- this.displayId = nextDisplayId++;
- this.displayName = 'webvr-polyfill displayName';
- this.depthNear = 0.01;
- this.depthFar = 10000.0;
- this.isConnected = true;
- this.isPresenting = false;
- this.capabilities = {
- hasPosition: false,
- hasOrientation: false,
- hasExternalDisplay: false,
- canPresent: false,
- maxLayers: 1
- };
- this.stageParameters = null;
- // "Private" members.
- this.waitingForPresent_ = false;
- this.layer_ = null;
- this.fullscreenElement_ = null;
- this.fullscreenWrapper_ = null;
- this.fullscreenElementCachedStyle_ = null;
- this.fullscreenEventTarget_ = null;
- this.fullscreenChangeHandler_ = null;
- this.fullscreenErrorHandler_ = null;
- this.wakelock_ = new WakeLock();
- }
- VRDisplay.prototype.getFrameData = function(frameData) {
- // TODO: Technically this should retain it's value for the duration of a frame
- // but I doubt that's practical to do in javascript.
- return Util.frameDataFromPose(frameData, this.getPose(), this);
- };
- VRDisplay.prototype.getPose = function() {
- // TODO: Technically this should retain it's value for the duration of a frame
- // but I doubt that's practical to do in javascript.
- return this.getImmediatePose();
- };
- VRDisplay.prototype.requestAnimationFrame = function(callback) {
- return window.requestAnimationFrame(callback);
- };
- VRDisplay.prototype.cancelAnimationFrame = function(id) {
- return window.cancelAnimationFrame(id);
- };
- VRDisplay.prototype.wrapForFullscreen = function(element) {
- // Don't wrap in iOS.
- if (Util.isIOS()) {
- return element;
- }
- if (!this.fullscreenWrapper_) {
- this.fullscreenWrapper_ = document.createElement('div');
- var cssProperties = [
- 'height: ' + Math.min(screen.height, screen.width) + 'px !important',
- 'top: 0 !important',
- 'left: 0 !important',
- 'right: 0 !important',
- 'border: 0',
- 'margin: 0',
- 'padding: 0',
- 'z-index: 999999 !important',
- 'position: fixed',
- ];
- this.fullscreenWrapper_.setAttribute('style', cssProperties.join('; ') + ';');
- this.fullscreenWrapper_.classList.add('webvr-polyfill-fullscreen-wrapper');
- }
- if (this.fullscreenElement_ == element) {
- return this.fullscreenWrapper_;
- }
- // Remove any previously applied wrappers
- this.removeFullscreenWrapper();
- this.fullscreenElement_ = element;
- var parent = this.fullscreenElement_.parentElement;
- parent.insertBefore(this.fullscreenWrapper_, this.fullscreenElement_);
- parent.removeChild(this.fullscreenElement_);
- this.fullscreenWrapper_.insertBefore(this.fullscreenElement_, this.fullscreenWrapper_.firstChild);
- this.fullscreenElementCachedStyle_ = this.fullscreenElement_.getAttribute('style');
- var self = this;
- function applyFullscreenElementStyle() {
- if (!self.fullscreenElement_) {
- return;
- }
- var cssProperties = [
- 'position: absolute',
- 'top: 0',
- 'left: 0',
- 'width: ' + Math.max(screen.width, screen.height) + 'px',
- 'height: ' + Math.min(screen.height, screen.width) + 'px',
- 'border: 0',
- 'margin: 0',
- 'padding: 0',
- ];
- self.fullscreenElement_.setAttribute('style', cssProperties.join('; ') + ';');
- }
- applyFullscreenElementStyle();
- return this.fullscreenWrapper_;
- };
- VRDisplay.prototype.removeFullscreenWrapper = function() {
- if (!this.fullscreenElement_) {
- return;
- }
- var element = this.fullscreenElement_;
- if (this.fullscreenElementCachedStyle_) {
- element.setAttribute('style', this.fullscreenElementCachedStyle_);
- } else {
- element.removeAttribute('style');
- }
- this.fullscreenElement_ = null;
- this.fullscreenElementCachedStyle_ = null;
- var parent = this.fullscreenWrapper_.parentElement;
- this.fullscreenWrapper_.removeChild(element);
- parent.insertBefore(element, this.fullscreenWrapper_);
- parent.removeChild(this.fullscreenWrapper_);
- return element;
- };
- VRDisplay.prototype.requestPresent = function(layers) {
- var wasPresenting = this.isPresenting;
- var self = this;
- if (!(layers instanceof Array)) {
- if (!hasShowDeprecationWarning) {
- console.warn("Using a deprecated form of requestPresent. Should pass in an array of VRLayers.");
- hasShowDeprecationWarning = true;
- }
- layers = [layers];
- }
- return new Promise(function(resolve, reject) {
- if (!self.capabilities.canPresent) {
- reject(new Error('VRDisplay is not capable of presenting.'));
- return;
- }
- if (layers.length == 0 || layers.length > self.capabilities.maxLayers) {
- reject(new Error('Invalid number of layers.'));
- return;
- }
- var incomingLayer = layers[0];
- if (!incomingLayer.source) {
- /*
- todo: figure out the correct behavior if the source is not provided.
- see https://github.com/w3c/webvr/issues/58
- */
- resolve();
- return;
- }
- var leftBounds = incomingLayer.leftBounds || defaultLeftBounds;
- var rightBounds = incomingLayer.rightBounds || defaultRightBounds;
- if (wasPresenting) {
- // Already presenting, just changing configuration
- var layer = self.layer_;
- if (layer.source !== incomingLayer.source) {
- layer.source = incomingLayer.source;
- }
- for (var i = 0; i < 4; i++) {
- layer.leftBounds[i] = leftBounds[i];
- layer.rightBounds[i] = rightBounds[i];
- }
- resolve();
- return;
- }
- // Was not already presenting.
- self.layer_ = {
- predistorted: incomingLayer.predistorted,
- source: incomingLayer.source,
- leftBounds: leftBounds.slice(0),
- rightBounds: rightBounds.slice(0)
- };
- self.waitingForPresent_ = false;
- if (self.layer_ && self.layer_.source) {
- var fullscreenElement = self.wrapForFullscreen(self.layer_.source);
- var onFullscreenChange = function() {
- var actualFullscreenElement = Util.getFullscreenElement();
- self.isPresenting = (fullscreenElement === actualFullscreenElement);
- if (self.isPresenting) {
- if (screen.orientation && screen.orientation.lock) {
- screen.orientation.lock('landscape-primary').catch(function(error){
- console.error('screen.orientation.lock() failed due to', error.message)
- });
- }
- self.waitingForPresent_ = false;
- self.beginPresent_();
- resolve();
- } else {
- if (screen.orientation && screen.orientation.unlock) {
- screen.orientation.unlock();
- }
- self.removeFullscreenWrapper();
- self.wakelock_.release();
- self.endPresent_();
- self.removeFullscreenListeners_();
- }
- self.fireVRDisplayPresentChange_();
- }
- var onFullscreenError = function() {
- if (!self.waitingForPresent_) {
- return;
- }
- self.removeFullscreenWrapper();
- self.removeFullscreenListeners_();
- self.wakelock_.release();
- self.waitingForPresent_ = false;
- self.isPresenting = false;
- reject(new Error('Unable to present.'));
- }
- self.addFullscreenListeners_(fullscreenElement,
- onFullscreenChange, onFullscreenError);
- if (Util.requestFullscreen(fullscreenElement)) {
- self.wakelock_.request();
- self.waitingForPresent_ = true;
- } else if (Util.isIOS() || Util.isWebViewAndroid()) {
- // *sigh* Just fake it.
- self.wakelock_.request();
- self.isPresenting = true;
- self.beginPresent_();
- self.fireVRDisplayPresentChange_();
- resolve();
- }
- }
- if (!self.waitingForPresent_ && !Util.isIOS()) {
- Util.exitFullscreen();
- reject(new Error('Unable to present.'));
- }
- });
- };
- VRDisplay.prototype.exitPresent = function() {
- var wasPresenting = this.isPresenting;
- var self = this;
- this.isPresenting = false;
- this.layer_ = null;
- this.wakelock_.release();
- return new Promise(function(resolve, reject) {
- if (wasPresenting) {
- if (!Util.exitFullscreen() && Util.isIOS()) {
- self.endPresent_();
- self.fireVRDisplayPresentChange_();
- }
- if (Util.isWebViewAndroid()) {
- self.removeFullscreenWrapper();
- self.removeFullscreenListeners_();
- self.endPresent_();
- self.fireVRDisplayPresentChange_();
- }
- resolve();
- } else {
- reject(new Error('Was not presenting to VRDisplay.'));
- }
- });
- };
- VRDisplay.prototype.getLayers = function() {
- if (this.layer_) {
- return [this.layer_];
- }
- return [];
- };
- VRDisplay.prototype.fireVRDisplayPresentChange_ = function() {
- // Important: unfortunately we cannot have full spec compliance here.
- // CustomEvent custom fields all go under e.detail (so the VRDisplay ends up
- // being e.detail.display, instead of e.display as per WebVR spec).
- var event = new CustomEvent('vrdisplaypresentchange', {detail: {display: this}});
- window.dispatchEvent(event);
- };
- VRDisplay.prototype.fireVRDisplayConnect_ = function() {
- // Important: unfortunately we cannot have full spec compliance here.
- // CustomEvent custom fields all go under e.detail (so the VRDisplay ends up
- // being e.detail.display, instead of e.display as per WebVR spec).
- var event = new CustomEvent('vrdisplayconnect', {detail: {display: this}});
- window.dispatchEvent(event);
- };
- VRDisplay.prototype.addFullscreenListeners_ = function(element, changeHandler, errorHandler) {
- this.removeFullscreenListeners_();
- this.fullscreenEventTarget_ = element;
- this.fullscreenChangeHandler_ = changeHandler;
- this.fullscreenErrorHandler_ = errorHandler;
- if (changeHandler) {
- if (document.fullscreenEnabled) {
- element.addEventListener('fullscreenchange', changeHandler, false);
- } else if (document.webkitFullscreenEnabled) {
- element.addEventListener('webkitfullscreenchange', changeHandler, false);
- } else if (document.mozFullScreenEnabled) {
- document.addEventListener('mozfullscreenchange', changeHandler, false);
- } else if (document.msFullscreenEnabled) {
- element.addEventListener('msfullscreenchange', changeHandler, false);
- }
- }
- if (errorHandler) {
- if (document.fullscreenEnabled) {
- element.addEventListener('fullscreenerror', errorHandler, false);
- } else if (document.webkitFullscreenEnabled) {
- element.addEventListener('webkitfullscreenerror', errorHandler, false);
- } else if (document.mozFullScreenEnabled) {
- document.addEventListener('mozfullscreenerror', errorHandler, false);
- } else if (document.msFullscreenEnabled) {
- element.addEventListener('msfullscreenerror', errorHandler, false);
- }
- }
- };
- VRDisplay.prototype.removeFullscreenListeners_ = function() {
- if (!this.fullscreenEventTarget_)
- return;
- var element = this.fullscreenEventTarget_;
- if (this.fullscreenChangeHandler_) {
- var changeHandler = this.fullscreenChangeHandler_;
- element.removeEventListener('fullscreenchange', changeHandler, false);
- element.removeEventListener('webkitfullscreenchange', changeHandler, false);
- document.removeEventListener('mozfullscreenchange', changeHandler, false);
- element.removeEventListener('msfullscreenchange', changeHandler, false);
- }
- if (this.fullscreenErrorHandler_) {
- var errorHandler = this.fullscreenErrorHandler_;
- element.removeEventListener('fullscreenerror', errorHandler, false);
- element.removeEventListener('webkitfullscreenerror', errorHandler, false);
- document.removeEventListener('mozfullscreenerror', errorHandler, false);
- element.removeEventListener('msfullscreenerror', errorHandler, false);
- }
- this.fullscreenEventTarget_ = null;
- this.fullscreenChangeHandler_ = null;
- this.fullscreenErrorHandler_ = null;
- };
- VRDisplay.prototype.beginPresent_ = function() {
- // Override to add custom behavior when presentation begins.
- };
- VRDisplay.prototype.endPresent_ = function() {
- // Override to add custom behavior when presentation ends.
- };
- VRDisplay.prototype.submitFrame = function(pose) {
- // Override to add custom behavior for frame submission.
- };
- VRDisplay.prototype.getEyeParameters = function(whichEye) {
- // Override to return accurate eye parameters if canPresent is true.
- return null;
- };
- /*
- * Deprecated classes
- */
- /**
- * The base class for all VR devices. (Deprecated)
- */
- function VRDevice() {
- this.isPolyfilled = true;
- this.hardwareUnitId = 'webvr-polyfill hardwareUnitId';
- this.deviceId = 'webvr-polyfill deviceId';
- this.deviceName = 'webvr-polyfill deviceName';
- }
- /**
- * The base class for all VR HMD devices. (Deprecated)
- */
- function HMDVRDevice() {
- }
- HMDVRDevice.prototype = new VRDevice();
- /**
- * The base class for all VR position sensor devices. (Deprecated)
- */
- function PositionSensorVRDevice() {
- }
- PositionSensorVRDevice.prototype = new VRDevice();
- module.exports.VRFrameData = VRFrameData;
- module.exports.VRDisplay = VRDisplay;
- module.exports.VRDevice = VRDevice;
- module.exports.HMDVRDevice = HMDVRDevice;
- module.exports.PositionSensorVRDevice = PositionSensorVRDevice;
- },{"./util.js":29,"./wakelock.js":31}],10:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var CardboardUI = _dereq_('./cardboard-ui.js');
- var Util = _dereq_('./util.js');
- var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js');
- var distortionVS = [
- 'attribute vec2 position;',
- 'attribute vec3 texCoord;',
- 'varying vec2 vTexCoord;',
- 'uniform vec4 viewportOffsetScale[2];',
- 'void main() {',
- ' vec4 viewport = viewportOffsetScale[int(texCoord.z)];',
- ' vTexCoord = (texCoord.xy * viewport.zw) + viewport.xy;',
- ' gl_Position = vec4( position, 1.0, 1.0 );',
- '}',
- ].join('\n');
- var distortionFS = [
- 'precision mediump float;',
- 'uniform sampler2D diffuse;',
- 'varying vec2 vTexCoord;',
- 'void main() {',
- ' gl_FragColor = texture2D(diffuse, vTexCoord);',
- '}',
- ].join('\n');
- /**
- * A mesh-based distorter.
- */
- function CardboardDistorter(gl) {
- this.gl = gl;
- this.ctxAttribs = gl.getContextAttributes();
- this.meshWidth = 20;
- this.meshHeight = 20;
- this.bufferScale = window.WebVRConfig.BUFFER_SCALE;
- this.bufferWidth = gl.drawingBufferWidth;
- this.bufferHeight = gl.drawingBufferHeight;
- // Patching support
- this.realBindFramebuffer = gl.bindFramebuffer;
- this.realEnable = gl.enable;
- this.realDisable = gl.disable;
- this.realColorMask = gl.colorMask;
- this.realClearColor = gl.clearColor;
- this.realViewport = gl.viewport;
- if (!Util.isIOS()) {
- this.realCanvasWidth = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'width');
- this.realCanvasHeight = Object.getOwnPropertyDescriptor(gl.canvas.__proto__, 'height');
- }
- this.isPatched = false;
- // State tracking
- this.lastBoundFramebuffer = null;
- this.cullFace = false;
- this.depthTest = false;
- this.blend = false;
- this.scissorTest = false;
- this.stencilTest = false;
- this.viewport = [0, 0, 0, 0];
- this.colorMask = [true, true, true, true];
- this.clearColor = [0, 0, 0, 0];
- this.attribs = {
- position: 0,
- texCoord: 1
- };
- this.program = Util.linkProgram(gl, distortionVS, distortionFS, this.attribs);
- this.uniforms = Util.getProgramUniforms(gl, this.program);
- this.viewportOffsetScale = new Float32Array(8);
- this.setTextureBounds();
- this.vertexBuffer = gl.createBuffer();
- this.indexBuffer = gl.createBuffer();
- this.indexCount = 0;
- this.renderTarget = gl.createTexture();
- this.framebuffer = gl.createFramebuffer();
- this.depthStencilBuffer = null;
- this.depthBuffer = null;
- this.stencilBuffer = null;
- if (this.ctxAttribs.depth && this.ctxAttribs.stencil) {
- this.depthStencilBuffer = gl.createRenderbuffer();
- } else if (this.ctxAttribs.depth) {
- this.depthBuffer = gl.createRenderbuffer();
- } else if (this.ctxAttribs.stencil) {
- this.stencilBuffer = gl.createRenderbuffer();
- }
- this.patch();
- this.onResize();
- if (!window.WebVRConfig.CARDBOARD_UI_DISABLED) {
- this.cardboardUI = new CardboardUI(gl);
- }
- };
- /**
- * Tears down all the resources created by the distorter and removes any
- * patches.
- */
- CardboardDistorter.prototype.destroy = function() {
- var gl = this.gl;
- this.unpatch();
- gl.deleteProgram(this.program);
- gl.deleteBuffer(this.vertexBuffer);
- gl.deleteBuffer(this.indexBuffer);
- gl.deleteTexture(this.renderTarget);
- gl.deleteFramebuffer(this.framebuffer);
- if (this.depthStencilBuffer) {
- gl.deleteRenderbuffer(this.depthStencilBuffer);
- }
- if (this.depthBuffer) {
- gl.deleteRenderbuffer(this.depthBuffer);
- }
- if (this.stencilBuffer) {
- gl.deleteRenderbuffer(this.stencilBuffer);
- }
- if (this.cardboardUI) {
- this.cardboardUI.destroy();
- }
- };
- /**
- * Resizes the backbuffer to match the canvas width and height.
- */
- CardboardDistorter.prototype.onResize = function() {
- var gl = this.gl;
- var self = this;
- var glState = [
- gl.RENDERBUFFER_BINDING,
- gl.TEXTURE_BINDING_2D, gl.TEXTURE0
- ];
- WGLUPreserveGLState(gl, glState, function(gl) {
- // Bind real backbuffer and clear it once. We don't need to clear it again
- // after that because we're overwriting the same area every frame.
- self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null);
- // Put things in a good state
- if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); }
- self.realColorMask.call(gl, true, true, true, true);
- self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
- self.realClearColor.call(gl, 0, 0, 0, 1);
- gl.clear(gl.COLOR_BUFFER_BIT);
- // Now bind and resize the fake backbuffer
- self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.framebuffer);
- gl.bindTexture(gl.TEXTURE_2D, self.renderTarget);
- gl.texImage2D(gl.TEXTURE_2D, 0, self.ctxAttribs.alpha ? gl.RGBA : gl.RGB,
- self.bufferWidth, self.bufferHeight, 0,
- self.ctxAttribs.alpha ? gl.RGBA : gl.RGB, gl.UNSIGNED_BYTE, null);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, self.renderTarget, 0);
- if (self.ctxAttribs.depth && self.ctxAttribs.stencil) {
- gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthStencilBuffer);
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,
- self.bufferWidth, self.bufferHeight);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT,
- gl.RENDERBUFFER, self.depthStencilBuffer);
- } else if (self.ctxAttribs.depth) {
- gl.bindRenderbuffer(gl.RENDERBUFFER, self.depthBuffer);
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,
- self.bufferWidth, self.bufferHeight);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT,
- gl.RENDERBUFFER, self.depthBuffer);
- } else if (self.ctxAttribs.stencil) {
- gl.bindRenderbuffer(gl.RENDERBUFFER, self.stencilBuffer);
- gl.renderbufferStorage(gl.RENDERBUFFER, gl.STENCIL_INDEX8,
- self.bufferWidth, self.bufferHeight);
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.STENCIL_ATTACHMENT,
- gl.RENDERBUFFER, self.stencilBuffer);
- }
- if (!gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE) {
- console.error('Framebuffer incomplete!');
- }
- self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer);
- if (self.scissorTest) { self.realEnable.call(gl, gl.SCISSOR_TEST); }
- self.realColorMask.apply(gl, self.colorMask);
- self.realViewport.apply(gl, self.viewport);
- self.realClearColor.apply(gl, self.clearColor);
- });
- if (this.cardboardUI) {
- this.cardboardUI.onResize();
- }
- };
- CardboardDistorter.prototype.patch = function() {
- if (this.isPatched) {
- return;
- }
- var self = this;
- var canvas = this.gl.canvas;
- var gl = this.gl;
- if (!Util.isIOS()) {
- canvas.width = Util.getScreenWidth() * this.bufferScale;
- canvas.height = Util.getScreenHeight() * this.bufferScale;
- Object.defineProperty(canvas, 'width', {
- configurable: true,
- enumerable: true,
- get: function() {
- return self.bufferWidth;
- },
- set: function(value) {
- self.bufferWidth = value;
- self.realCanvasWidth.set.call(canvas, value);
- self.onResize();
- }
- });
- Object.defineProperty(canvas, 'height', {
- configurable: true,
- enumerable: true,
- get: function() {
- return self.bufferHeight;
- },
- set: function(value) {
- self.bufferHeight = value;
- self.realCanvasHeight.set.call(canvas, value);
- self.onResize();
- }
- });
- }
- this.lastBoundFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
- if (this.lastBoundFramebuffer == null) {
- this.lastBoundFramebuffer = this.framebuffer;
- this.gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);
- }
- this.gl.bindFramebuffer = function(target, framebuffer) {
- self.lastBoundFramebuffer = framebuffer ? framebuffer : self.framebuffer;
- // Silently make calls to bind the default framebuffer bind ours instead.
- self.realBindFramebuffer.call(gl, target, self.lastBoundFramebuffer);
- };
- this.cullFace = gl.getParameter(gl.CULL_FACE);
- this.depthTest = gl.getParameter(gl.DEPTH_TEST);
- this.blend = gl.getParameter(gl.BLEND);
- this.scissorTest = gl.getParameter(gl.SCISSOR_TEST);
- this.stencilTest = gl.getParameter(gl.STENCIL_TEST);
- gl.enable = function(pname) {
- switch (pname) {
- case gl.CULL_FACE: self.cullFace = true; break;
- case gl.DEPTH_TEST: self.depthTest = true; break;
- case gl.BLEND: self.blend = true; break;
- case gl.SCISSOR_TEST: self.scissorTest = true; break;
- case gl.STENCIL_TEST: self.stencilTest = true; break;
- }
- self.realEnable.call(gl, pname);
- };
- gl.disable = function(pname) {
- switch (pname) {
- case gl.CULL_FACE: self.cullFace = false; break;
- case gl.DEPTH_TEST: self.depthTest = false; break;
- case gl.BLEND: self.blend = false; break;
- case gl.SCISSOR_TEST: self.scissorTest = false; break;
- case gl.STENCIL_TEST: self.stencilTest = false; break;
- }
- self.realDisable.call(gl, pname);
- };
- this.colorMask = gl.getParameter(gl.COLOR_WRITEMASK);
- gl.colorMask = function(r, g, b, a) {
- self.colorMask[0] = r;
- self.colorMask[1] = g;
- self.colorMask[2] = b;
- self.colorMask[3] = a;
- self.realColorMask.call(gl, r, g, b, a);
- };
- this.clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
- gl.clearColor = function(r, g, b, a) {
- self.clearColor[0] = r;
- self.clearColor[1] = g;
- self.clearColor[2] = b;
- self.clearColor[3] = a;
- self.realClearColor.call(gl, r, g, b, a);
- };
- this.viewport = gl.getParameter(gl.VIEWPORT);
- gl.viewport = function(x, y, w, h) {
- self.viewport[0] = x;
- self.viewport[1] = y;
- self.viewport[2] = w;
- self.viewport[3] = h;
- self.realViewport.call(gl, x, y, w, h);
- };
- this.isPatched = true;
- Util.safariCssSizeWorkaround(canvas);
- };
- CardboardDistorter.prototype.unpatch = function() {
- if (!this.isPatched) {
- return;
- }
- var gl = this.gl;
- var canvas = this.gl.canvas;
- if (!Util.isIOS()) {
- Object.defineProperty(canvas, 'width', this.realCanvasWidth);
- Object.defineProperty(canvas, 'height', this.realCanvasHeight);
- }
- canvas.width = this.bufferWidth;
- canvas.height = this.bufferHeight;
- gl.bindFramebuffer = this.realBindFramebuffer;
- gl.enable = this.realEnable;
- gl.disable = this.realDisable;
- gl.colorMask = this.realColorMask;
- gl.clearColor = this.realClearColor;
- gl.viewport = this.realViewport;
- // Check to see if our fake backbuffer is bound and bind the real backbuffer
- // if that's the case.
- if (this.lastBoundFramebuffer == this.framebuffer) {
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- }
- this.isPatched = false;
- setTimeout(function() {
- Util.safariCssSizeWorkaround(canvas);
- }, 1);
- };
- CardboardDistorter.prototype.setTextureBounds = function(leftBounds, rightBounds) {
- if (!leftBounds) {
- leftBounds = [0, 0, 0.5, 1];
- }
- if (!rightBounds) {
- rightBounds = [0.5, 0, 0.5, 1];
- }
- // Left eye
- this.viewportOffsetScale[0] = leftBounds[0]; // X
- this.viewportOffsetScale[1] = leftBounds[1]; // Y
- this.viewportOffsetScale[2] = leftBounds[2]; // Width
- this.viewportOffsetScale[3] = leftBounds[3]; // Height
- // Right eye
- this.viewportOffsetScale[4] = rightBounds[0]; // X
- this.viewportOffsetScale[5] = rightBounds[1]; // Y
- this.viewportOffsetScale[6] = rightBounds[2]; // Width
- this.viewportOffsetScale[7] = rightBounds[3]; // Height
- };
- /**
- * Performs distortion pass on the injected backbuffer, rendering it to the real
- * backbuffer.
- */
- CardboardDistorter.prototype.submitFrame = function() {
- var gl = this.gl;
- var self = this;
- var glState = [];
- if (!window.WebVRConfig.DIRTY_SUBMIT_FRAME_BINDINGS) {
- glState.push(
- gl.CURRENT_PROGRAM,
- gl.ARRAY_BUFFER_BINDING,
- gl.ELEMENT_ARRAY_BUFFER_BINDING,
- gl.TEXTURE_BINDING_2D, gl.TEXTURE0
- );
- }
- WGLUPreserveGLState(gl, glState, function(gl) {
- // Bind the real default framebuffer
- self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, null);
- // Make sure the GL state is in a good place
- if (self.cullFace) { self.realDisable.call(gl, gl.CULL_FACE); }
- if (self.depthTest) { self.realDisable.call(gl, gl.DEPTH_TEST); }
- if (self.blend) { self.realDisable.call(gl, gl.BLEND); }
- if (self.scissorTest) { self.realDisable.call(gl, gl.SCISSOR_TEST); }
- if (self.stencilTest) { self.realDisable.call(gl, gl.STENCIL_TEST); }
- self.realColorMask.call(gl, true, true, true, true);
- self.realViewport.call(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
- // If the backbuffer has an alpha channel clear every frame so the page
- // doesn't show through.
- if (self.ctxAttribs.alpha || Util.isIOS()) {
- self.realClearColor.call(gl, 0, 0, 0, 1);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
- // Bind distortion program and mesh
- gl.useProgram(self.program);
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer);
- gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
- gl.enableVertexAttribArray(self.attribs.position);
- gl.enableVertexAttribArray(self.attribs.texCoord);
- gl.vertexAttribPointer(self.attribs.position, 2, gl.FLOAT, false, 20, 0);
- gl.vertexAttribPointer(self.attribs.texCoord, 3, gl.FLOAT, false, 20, 8);
- gl.activeTexture(gl.TEXTURE0);
- gl.uniform1i(self.uniforms.diffuse, 0);
- gl.bindTexture(gl.TEXTURE_2D, self.renderTarget);
- gl.uniform4fv(self.uniforms.viewportOffsetScale, self.viewportOffsetScale);
- // Draws both eyes
- gl.drawElements(gl.TRIANGLES, self.indexCount, gl.UNSIGNED_SHORT, 0);
- if (self.cardboardUI) {
- self.cardboardUI.renderNoState();
- }
- // Bind the fake default framebuffer again
- self.realBindFramebuffer.call(self.gl, gl.FRAMEBUFFER, self.framebuffer);
- // If preserveDrawingBuffer == false clear the framebuffer
- if (!self.ctxAttribs.preserveDrawingBuffer) {
- self.realClearColor.call(gl, 0, 0, 0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
- if (!window.WebVRConfig.DIRTY_SUBMIT_FRAME_BINDINGS) {
- self.realBindFramebuffer.call(gl, gl.FRAMEBUFFER, self.lastBoundFramebuffer);
- }
- // Restore state
- if (self.cullFace) { self.realEnable.call(gl, gl.CULL_FACE); }
- if (self.depthTest) { self.realEnable.call(gl, gl.DEPTH_TEST); }
- if (self.blend) { self.realEnable.call(gl, gl.BLEND); }
- if (self.scissorTest) { self.realEnable.call(gl, gl.SCISSOR_TEST); }
- if (self.stencilTest) { self.realEnable.call(gl, gl.STENCIL_TEST); }
- self.realColorMask.apply(gl, self.colorMask);
- self.realViewport.apply(gl, self.viewport);
- if (self.ctxAttribs.alpha || !self.ctxAttribs.preserveDrawingBuffer) {
- self.realClearColor.apply(gl, self.clearColor);
- }
- });
- // Workaround for the fact that Safari doesn't allow us to patch the canvas
- // width and height correctly. After each submit frame check to see what the
- // real backbuffer size has been set to and resize the fake backbuffer size
- // to match.
- if (Util.isIOS()) {
- var canvas = gl.canvas;
- if (canvas.width != self.bufferWidth || canvas.height != self.bufferHeight) {
- self.bufferWidth = canvas.width;
- self.bufferHeight = canvas.height;
- self.onResize();
- }
- }
- };
- /**
- * Call when the deviceInfo has changed. At this point we need
- * to re-calculate the distortion mesh.
- */
- CardboardDistorter.prototype.updateDeviceInfo = function(deviceInfo) {
- var gl = this.gl;
- var self = this;
- var glState = [gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING];
- WGLUPreserveGLState(gl, glState, function(gl) {
- var vertices = self.computeMeshVertices_(self.meshWidth, self.meshHeight, deviceInfo);
- gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
- // Indices don't change based on device parameters, so only compute once.
- if (!self.indexCount) {
- var indices = self.computeMeshIndices_(self.meshWidth, self.meshHeight);
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, self.indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
- self.indexCount = indices.length;
- }
- });
- };
- /**
- * Build the distortion mesh vertices.
- * Based on code from the Unity cardboard plugin.
- */
- CardboardDistorter.prototype.computeMeshVertices_ = function(width, height, deviceInfo) {
- var vertices = new Float32Array(2 * width * height * 5);
- var lensFrustum = deviceInfo.getLeftEyeVisibleTanAngles();
- var noLensFrustum = deviceInfo.getLeftEyeNoLensTanAngles();
- var viewport = deviceInfo.getLeftEyeVisibleScreenRect(noLensFrustum);
- var vidx = 0;
- var iidx = 0;
- for (var e = 0; e < 2; e++) {
- for (var j = 0; j < height; j++) {
- for (var i = 0; i < width; i++, vidx++) {
- var u = i / (width - 1);
- var v = j / (height - 1);
- // Grid points regularly spaced in StreoScreen, and barrel distorted in
- // the mesh.
- var s = u;
- var t = v;
- var x = Util.lerp(lensFrustum[0], lensFrustum[2], u);
- var y = Util.lerp(lensFrustum[3], lensFrustum[1], v);
- var d = Math.sqrt(x * x + y * y);
- var r = deviceInfo.distortion.distortInverse(d);
- var p = x * r / d;
- var q = y * r / d;
- u = (p - noLensFrustum[0]) / (noLensFrustum[2] - noLensFrustum[0]);
- v = (q - noLensFrustum[3]) / (noLensFrustum[1] - noLensFrustum[3]);
- // Convert u,v to mesh screen coordinates.
- var aspect = deviceInfo.device.widthMeters / deviceInfo.device.heightMeters;
- // FIXME: The original Unity plugin multiplied U by the aspect ratio
- // and didn't multiply either value by 2, but that seems to get it
- // really close to correct looking for me. I hate this kind of "Don't
- // know why it works" code though, and wold love a more logical
- // explanation of what needs to happen here.
- u = (viewport.x + u * viewport.width - 0.5) * 2.0; //* aspect;
- v = (viewport.y + v * viewport.height - 0.5) * 2.0;
- vertices[(vidx * 5) + 0] = u; // position.x
- vertices[(vidx * 5) + 1] = v; // position.y
- vertices[(vidx * 5) + 2] = s; // texCoord.x
- vertices[(vidx * 5) + 3] = t; // texCoord.y
- vertices[(vidx * 5) + 4] = e; // texCoord.z (viewport index)
- }
- }
- var w = lensFrustum[2] - lensFrustum[0];
- lensFrustum[0] = -(w + lensFrustum[0]);
- lensFrustum[2] = w - lensFrustum[2];
- w = noLensFrustum[2] - noLensFrustum[0];
- noLensFrustum[0] = -(w + noLensFrustum[0]);
- noLensFrustum[2] = w - noLensFrustum[2];
- viewport.x = 1 - (viewport.x + viewport.width);
- }
- return vertices;
- }
- /**
- * Build the distortion mesh indices.
- * Based on code from the Unity cardboard plugin.
- */
- CardboardDistorter.prototype.computeMeshIndices_ = function(width, height) {
- var indices = new Uint16Array(2 * (width - 1) * (height - 1) * 6);
- var halfwidth = width / 2;
- var halfheight = height / 2;
- var vidx = 0;
- var iidx = 0;
- for (var e = 0; e < 2; e++) {
- for (var j = 0; j < height; j++) {
- for (var i = 0; i < width; i++, vidx++) {
- if (i == 0 || j == 0)
- continue;
- // Build a quad. Lower right and upper left quadrants have quads with
- // the triangle diagonal flipped to get the vignette to interpolate
- // correctly.
- if ((i <= halfwidth) == (j <= halfheight)) {
- // Quad diagonal lower left to upper right.
- indices[iidx++] = vidx;
- indices[iidx++] = vidx - width - 1;
- indices[iidx++] = vidx - width;
- indices[iidx++] = vidx - width - 1;
- indices[iidx++] = vidx;
- indices[iidx++] = vidx - 1;
- } else {
- // Quad diagonal upper left to lower right.
- indices[iidx++] = vidx - 1;
- indices[iidx++] = vidx - width;
- indices[iidx++] = vidx;
- indices[iidx++] = vidx - width;
- indices[iidx++] = vidx - 1;
- indices[iidx++] = vidx - width - 1;
- }
- }
- }
- }
- return indices;
- };
- CardboardDistorter.prototype.getOwnPropertyDescriptor_ = function(proto, attrName) {
- var descriptor = Object.getOwnPropertyDescriptor(proto, attrName);
- // In some cases (ahem... Safari), the descriptor returns undefined get and
- // set fields. In this case, we need to create a synthetic property
- // descriptor. This works around some of the issues in
- // https://github.com/borismus/webvr-polyfill/issues/46
- if (descriptor.get === undefined || descriptor.set === undefined) {
- descriptor.configurable = true;
- descriptor.enumerable = true;
- descriptor.get = function() {
- return this.getAttribute(attrName);
- };
- descriptor.set = function(val) {
- this.setAttribute(attrName, val);
- };
- }
- return descriptor;
- };
- module.exports = CardboardDistorter;
- },{"./cardboard-ui.js":11,"./deps/wglu-preserve-state.js":13,"./util.js":29}],11:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('./util.js');
- var WGLUPreserveGLState = _dereq_('./deps/wglu-preserve-state.js');
- var uiVS = [
- 'attribute vec2 position;',
- 'uniform mat4 projectionMat;',
- 'void main() {',
- ' gl_Position = projectionMat * vec4( position, -1.0, 1.0 );',
- '}',
- ].join('\n');
- var uiFS = [
- 'precision mediump float;',
- 'uniform vec4 color;',
- 'void main() {',
- ' gl_FragColor = color;',
- '}',
- ].join('\n');
- var DEG2RAD = Math.PI/180.0;
- // The gear has 6 identical sections, each spanning 60 degrees.
- var kAnglePerGearSection = 60;
- // Half-angle of the span of the outer rim.
- var kOuterRimEndAngle = 12;
- // Angle between the middle of the outer rim and the start of the inner rim.
- var kInnerRimBeginAngle = 20;
- // Distance from center to outer rim, normalized so that the entire model
- // fits in a [-1, 1] x [-1, 1] square.
- var kOuterRadius = 1;
- // Distance from center to depressed rim, in model units.
- var kMiddleRadius = 0.75;
- // Radius of the inner hollow circle, in model units.
- var kInnerRadius = 0.3125;
- // Center line thickness in DP.
- var kCenterLineThicknessDp = 4;
- // Button width in DP.
- var kButtonWidthDp = 28;
- // Factor to scale the touch area that responds to the touch.
- var kTouchSlopFactor = 1.5;
- var Angles = [
- 0, kOuterRimEndAngle, kInnerRimBeginAngle,
- kAnglePerGearSection - kInnerRimBeginAngle,
- kAnglePerGearSection - kOuterRimEndAngle
- ];
- /**
- * Renders the alignment line and "options" gear. It is assumed that the canvas
- * this is rendered into covers the entire screen (or close to it.)
- */
- function CardboardUI(gl) {
- this.gl = gl;
- this.attribs = {
- position: 0
- };
- this.program = Util.linkProgram(gl, uiVS, uiFS, this.attribs);
- this.uniforms = Util.getProgramUniforms(gl, this.program);
- this.vertexBuffer = gl.createBuffer();
- this.gearOffset = 0;
- this.gearVertexCount = 0;
- this.arrowOffset = 0;
- this.arrowVertexCount = 0;
- this.projMat = new Float32Array(16);
- this.listener = null;
- this.onResize();
- };
- /**
- * Tears down all the resources created by the UI renderer.
- */
- CardboardUI.prototype.destroy = function() {
- var gl = this.gl;
- if (this.listener) {
- gl.canvas.removeEventListener('click', this.listener, false);
- }
- gl.deleteProgram(this.program);
- gl.deleteBuffer(this.vertexBuffer);
- };
- /**
- * Adds a listener to clicks on the gear and back icons
- */
- CardboardUI.prototype.listen = function(optionsCallback, backCallback) {
- var canvas = this.gl.canvas;
- this.listener = function(event) {
- var midline = canvas.clientWidth / 2;
- var buttonSize = kButtonWidthDp * kTouchSlopFactor;
- // Check to see if the user clicked on (or around) the gear icon
- if (event.clientX > midline - buttonSize &&
- event.clientX < midline + buttonSize &&
- event.clientY > canvas.clientHeight - buttonSize) {
- optionsCallback(event);
- }
- // Check to see if the user clicked on (or around) the back icon
- else if (event.clientX < buttonSize && event.clientY < buttonSize) {
- backCallback(event);
- }
- };
- canvas.addEventListener('click', this.listener, false);
- };
- /**
- * Builds the UI mesh.
- */
- CardboardUI.prototype.onResize = function() {
- var gl = this.gl;
- var self = this;
- var glState = [
- gl.ARRAY_BUFFER_BINDING
- ];
- WGLUPreserveGLState(gl, glState, function(gl) {
- var vertices = [];
- var midline = gl.drawingBufferWidth / 2;
- // The gl buffer size will likely be smaller than the physical pixel count.
- // So we need to scale the dps down based on the actual buffer size vs physical pixel count.
- // This will properly size the ui elements no matter what the gl buffer resolution is
- var physicalPixels = Math.max(screen.width, screen.height) * window.devicePixelRatio;
- var scalingRatio = gl.drawingBufferWidth / physicalPixels;
- var dps = scalingRatio * window.devicePixelRatio;
- var lineWidth = kCenterLineThicknessDp * dps / 2;
- var buttonSize = kButtonWidthDp * kTouchSlopFactor * dps;
- var buttonScale = kButtonWidthDp * dps / 2;
- var buttonBorder = ((kButtonWidthDp * kTouchSlopFactor) - kButtonWidthDp) * dps;
- // Build centerline
- vertices.push(midline - lineWidth, buttonSize);
- vertices.push(midline - lineWidth, gl.drawingBufferHeight);
- vertices.push(midline + lineWidth, buttonSize);
- vertices.push(midline + lineWidth, gl.drawingBufferHeight);
- // Build gear
- self.gearOffset = (vertices.length / 2);
- function addGearSegment(theta, r) {
- var angle = (90 - theta) * DEG2RAD;
- var x = Math.cos(angle);
- var y = Math.sin(angle);
- vertices.push(kInnerRadius * x * buttonScale + midline, kInnerRadius * y * buttonScale + buttonScale);
- vertices.push(r * x * buttonScale + midline, r * y * buttonScale + buttonScale);
- }
- for (var i = 0; i <= 6; i++) {
- var segmentTheta = i * kAnglePerGearSection;
- addGearSegment(segmentTheta, kOuterRadius);
- addGearSegment(segmentTheta + kOuterRimEndAngle, kOuterRadius);
- addGearSegment(segmentTheta + kInnerRimBeginAngle, kMiddleRadius);
- addGearSegment(segmentTheta + (kAnglePerGearSection - kInnerRimBeginAngle), kMiddleRadius);
- addGearSegment(segmentTheta + (kAnglePerGearSection - kOuterRimEndAngle), kOuterRadius);
- }
- self.gearVertexCount = (vertices.length / 2) - self.gearOffset;
- // Build back arrow
- self.arrowOffset = (vertices.length / 2);
- function addArrowVertex(x, y) {
- vertices.push(buttonBorder + x, gl.drawingBufferHeight - buttonBorder - y);
- }
- var angledLineWidth = lineWidth / Math.sin(45 * DEG2RAD);
- addArrowVertex(0, buttonScale);
- addArrowVertex(buttonScale, 0);
- addArrowVertex(buttonScale + angledLineWidth, angledLineWidth);
- addArrowVertex(angledLineWidth, buttonScale + angledLineWidth);
- addArrowVertex(angledLineWidth, buttonScale - angledLineWidth);
- addArrowVertex(0, buttonScale);
- addArrowVertex(buttonScale, buttonScale * 2);
- addArrowVertex(buttonScale + angledLineWidth, (buttonScale * 2) - angledLineWidth);
- addArrowVertex(angledLineWidth, buttonScale - angledLineWidth);
- addArrowVertex(0, buttonScale);
- addArrowVertex(angledLineWidth, buttonScale - lineWidth);
- addArrowVertex(kButtonWidthDp * dps, buttonScale - lineWidth);
- addArrowVertex(angledLineWidth, buttonScale + lineWidth);
- addArrowVertex(kButtonWidthDp * dps, buttonScale + lineWidth);
- self.arrowVertexCount = (vertices.length / 2) - self.arrowOffset;
- // Buffer data
- gl.bindBuffer(gl.ARRAY_BUFFER, self.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
- });
- };
- /**
- * Performs distortion pass on the injected backbuffer, rendering it to the real
- * backbuffer.
- */
- CardboardUI.prototype.render = function() {
- var gl = this.gl;
- var self = this;
- var glState = [
- gl.CULL_FACE,
- gl.DEPTH_TEST,
- gl.BLEND,
- gl.SCISSOR_TEST,
- gl.STENCIL_TEST,
- gl.COLOR_WRITEMASK,
- gl.VIEWPORT,
- gl.CURRENT_PROGRAM,
- gl.ARRAY_BUFFER_BINDING
- ];
- WGLUPreserveGLState(gl, glState, function(gl) {
- // Make sure the GL state is in a good place
- gl.disable(gl.CULL_FACE);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.BLEND);
- gl.disable(gl.SCISSOR_TEST);
- gl.disable(gl.STENCIL_TEST);
- gl.colorMask(true, true, true, true);
- gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
- self.renderNoState();
- });
- };
- CardboardUI.prototype.renderNoState = function() {
- var gl = this.gl;
- // Bind distortion program and mesh
- gl.useProgram(this.program);
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.enableVertexAttribArray(this.attribs.position);
- gl.vertexAttribPointer(this.attribs.position, 2, gl.FLOAT, false, 8, 0);
- gl.uniform4f(this.uniforms.color, 1.0, 1.0, 1.0, 1.0);
- Util.orthoMatrix(this.projMat, 0, gl.drawingBufferWidth, 0, gl.drawingBufferHeight, 0.1, 1024.0);
- gl.uniformMatrix4fv(this.uniforms.projectionMat, false, this.projMat);
- // Draws UI element
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
- gl.drawArrays(gl.TRIANGLE_STRIP, this.gearOffset, this.gearVertexCount);
- gl.drawArrays(gl.TRIANGLE_STRIP, this.arrowOffset, this.arrowVertexCount);
- };
- module.exports = CardboardUI;
- },{"./deps/wglu-preserve-state.js":13,"./util.js":29}],12:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var CardboardDistorter = _dereq_('./cardboard-distorter.js');
- var CardboardUI = _dereq_('./cardboard-ui.js');
- var DeviceInfo = _dereq_('./device-info.js');
- var Dpdb = _dereq_('./dpdb/dpdb.js');
- var FusionPoseSensor = _dereq_('./sensor-fusion/fusion-pose-sensor.js');
- var RotateInstructions = _dereq_('./rotate-instructions.js');
- var ViewerSelector = _dereq_('./viewer-selector.js');
- var VRDisplay = _dereq_('./base.js').VRDisplay;
- var Util = _dereq_('./util.js');
- var Eye = {
- LEFT: 'left',
- RIGHT: 'right'
- };
- /**
- * VRDisplay based on mobile device parameters and DeviceMotion APIs.
- */
- function CardboardVRDisplay() {
- this.displayName = 'Cardboard VRDisplay (webvr-polyfill)';
- this.capabilities.hasOrientation = true;
- this.capabilities.canPresent = true;
- // "Private" members.
- this.bufferScale_ = window.WebVRConfig.BUFFER_SCALE;
- this.poseSensor_ = new FusionPoseSensor();
- this.distorter_ = null;
- this.cardboardUI_ = null;
- this.dpdb_ = new Dpdb(true, this.onDeviceParamsUpdated_.bind(this));
- this.deviceInfo_ = new DeviceInfo(this.dpdb_.getDeviceParams());
- this.viewerSelector_ = new ViewerSelector();
- this.viewerSelector_.onChange(this.onViewerChanged_.bind(this));
- // Set the correct initial viewer.
- this.deviceInfo_.setViewer(this.viewerSelector_.getCurrentViewer());
- if (!window.WebVRConfig.ROTATE_INSTRUCTIONS_DISABLED) {
- this.rotateInstructions_ = new RotateInstructions();
- }
- if (Util.isIOS()) {
- // Listen for resize events to workaround this awful Safari bug.
- window.addEventListener('resize', this.onResize_.bind(this));
- }
- }
- CardboardVRDisplay.prototype = new VRDisplay();
- CardboardVRDisplay.prototype.getImmediatePose = function() {
- return {
- position: this.poseSensor_.getPosition(),
- orientation: this.poseSensor_.getOrientation(),
- linearVelocity: null,
- linearAcceleration: null,
- angularVelocity: null,
- angularAcceleration: null
- };
- };
- CardboardVRDisplay.prototype.resetPose = function() {
- this.poseSensor_.resetPose();
- };
- CardboardVRDisplay.prototype.getEyeParameters = function(whichEye) {
- var offset = [this.deviceInfo_.viewer.interLensDistance * 0.5, 0.0, 0.0];
- var fieldOfView;
- // TODO: FoV can be a little expensive to compute. Cache when device params change.
- if (whichEye == Eye.LEFT) {
- offset[0] *= -1.0;
- fieldOfView = this.deviceInfo_.getFieldOfViewLeftEye();
- } else if (whichEye == Eye.RIGHT) {
- fieldOfView = this.deviceInfo_.getFieldOfViewRightEye();
- } else {
- console.error('Invalid eye provided: %s', whichEye);
- return null;
- }
- return {
- fieldOfView: fieldOfView,
- offset: offset,
- // TODO: Should be able to provide better values than these.
- renderWidth: this.deviceInfo_.device.width * 0.5 * this.bufferScale_,
- renderHeight: this.deviceInfo_.device.height * this.bufferScale_,
- };
- };
- CardboardVRDisplay.prototype.onDeviceParamsUpdated_ = function(newParams) {
- if (Util.isDebug()) {
- console.log('DPDB reported that device params were updated.');
- }
- this.deviceInfo_.updateDeviceParams(newParams);
- if (this.distorter_) {
- this.distorter_.updateDeviceInfo(this.deviceInfo_);
- }
- };
- CardboardVRDisplay.prototype.updateBounds_ = function () {
- if (this.layer_ && this.distorter_ && (this.layer_.leftBounds || this.layer_.rightBounds)) {
- this.distorter_.setTextureBounds(this.layer_.leftBounds, this.layer_.rightBounds);
- }
- };
- CardboardVRDisplay.prototype.beginPresent_ = function() {
- var gl = this.layer_.source.getContext('webgl');
- if (!gl)
- gl = this.layer_.source.getContext('experimental-webgl');
- if (!gl)
- gl = this.layer_.source.getContext('webgl2');
- if (!gl)
- return; // Can't do distortion without a WebGL context.
- // Provides a way to opt out of distortion
- if (this.layer_.predistorted) {
- if (!window.WebVRConfig.CARDBOARD_UI_DISABLED) {
- gl.canvas.width = Util.getScreenWidth() * this.bufferScale_;
- gl.canvas.height = Util.getScreenHeight() * this.bufferScale_;
- this.cardboardUI_ = new CardboardUI(gl);
- }
- } else {
- // Create a new distorter for the target context
- this.distorter_ = new CardboardDistorter(gl);
- this.distorter_.updateDeviceInfo(this.deviceInfo_);
- this.cardboardUI_ = this.distorter_.cardboardUI;
- }
- if (this.cardboardUI_) {
- this.cardboardUI_.listen(function(e) {
- // Options clicked.
- this.viewerSelector_.show(this.layer_.source.parentElement);
- e.stopPropagation();
- e.preventDefault();
- }.bind(this), function(e) {
- // Back clicked.
- this.exitPresent();
- e.stopPropagation();
- e.preventDefault();
- }.bind(this));
- }
- if (this.rotateInstructions_) {
- if (Util.isLandscapeMode() && Util.isMobile()) {
- // In landscape mode, temporarily show the "put into Cardboard"
- // interstitial. Otherwise, do the default thing.
- this.rotateInstructions_.showTemporarily(3000, this.layer_.source.parentElement);
- } else {
- this.rotateInstructions_.update();
- }
- }
- // Listen for orientation change events in order to show interstitial.
- this.orientationHandler = this.onOrientationChange_.bind(this);
- window.addEventListener('orientationchange', this.orientationHandler);
- // Listen for present display change events in order to update distorter dimensions
- this.vrdisplaypresentchangeHandler = this.updateBounds_.bind(this);
- window.addEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler);
- // Fire this event initially, to give geometry-distortion clients the chance
- // to do something custom.
- this.fireVRDisplayDeviceParamsChange_();
- };
- CardboardVRDisplay.prototype.endPresent_ = function() {
- if (this.distorter_) {
- this.distorter_.destroy();
- this.distorter_ = null;
- }
- if (this.cardboardUI_) {
- this.cardboardUI_.destroy();
- this.cardboardUI_ = null;
- }
- if (this.rotateInstructions_) {
- this.rotateInstructions_.hide();
- }
- this.viewerSelector_.hide();
- window.removeEventListener('orientationchange', this.orientationHandler);
- window.removeEventListener('vrdisplaypresentchange', this.vrdisplaypresentchangeHandler);
- };
- CardboardVRDisplay.prototype.submitFrame = function(pose) {
- if (this.distorter_) {
- this.updateBounds_();
- this.distorter_.submitFrame();
- } else if (this.cardboardUI_ && this.layer_) {
- // Hack for predistorted: true.
- var canvas = this.layer_.source.getContext('webgl').canvas;
- if (canvas.width != this.lastWidth || canvas.height != this.lastHeight) {
- this.cardboardUI_.onResize();
- }
- this.lastWidth = canvas.width;
- this.lastHeight = canvas.height;
- // Render the Cardboard UI.
- this.cardboardUI_.render();
- }
- };
- CardboardVRDisplay.prototype.onOrientationChange_ = function(e) {
- // Hide the viewer selector.
- this.viewerSelector_.hide();
- // Update the rotate instructions.
- if (this.rotateInstructions_) {
- this.rotateInstructions_.update();
- }
- this.onResize_();
- };
- CardboardVRDisplay.prototype.onResize_ = function(e) {
- if (this.layer_) {
- var gl = this.layer_.source.getContext('webgl');
- // Size the CSS canvas.
- // Added padding on right and bottom because iPhone 5 will not
- // hide the URL bar unless content is bigger than the screen.
- // This will not be visible as long as the container element (e.g. body)
- // is set to 'overflow: hidden'.
- // Additionally, 'box-sizing: content-box' ensures renderWidth = width + padding.
- // This is required when 'box-sizing: border-box' is used elsewhere in the page.
- var cssProperties = [
- 'position: absolute',
- 'top: 0',
- 'left: 0',
- // Use vw/vh to handle implicitly devicePixelRatio; issue #282
- 'width: 100vw',
- 'height: 100vh',
- 'border: 0',
- 'margin: 0',
- // Set no padding in the case where you don't have control over
- // the content injection, like in Unity WebGL; issue #282
- 'padding: 0px',
- 'box-sizing: content-box',
- ];
- gl.canvas.setAttribute('style', cssProperties.join('; ') + ';');
- Util.safariCssSizeWorkaround(gl.canvas);
- }
- };
- CardboardVRDisplay.prototype.onViewerChanged_ = function(viewer) {
- this.deviceInfo_.setViewer(viewer);
- if (this.distorter_) {
- // Update the distortion appropriately.
- this.distorter_.updateDeviceInfo(this.deviceInfo_);
- }
- // Fire a new event containing viewer and device parameters for clients that
- // want to implement their own geometry-based distortion.
- this.fireVRDisplayDeviceParamsChange_();
- };
- CardboardVRDisplay.prototype.fireVRDisplayDeviceParamsChange_ = function() {
- var event = new CustomEvent('vrdisplaydeviceparamschange', {
- detail: {
- vrdisplay: this,
- deviceInfo: this.deviceInfo_,
- }
- });
- window.dispatchEvent(event);
- };
- module.exports = CardboardVRDisplay;
- },{"./base.js":9,"./cardboard-distorter.js":10,"./cardboard-ui.js":11,"./device-info.js":14,"./dpdb/dpdb.js":18,"./rotate-instructions.js":23,"./sensor-fusion/fusion-pose-sensor.js":25,"./util.js":29,"./viewer-selector.js":30}],13:[function(_dereq_,module,exports){
- /**
- * Copyright (c) 2016, Brandon Jones.
- * https://github.com/toji/webgl-utils/blob/master/src/wglu-preserve-state.js
- * LICENSE: https://github.com/toji/webgl-utils/blob/master/LICENSE.md
- */
- function WGLUPreserveGLState(gl, bindings, callback) {
- if (!bindings) {
- callback(gl);
- return;
- }
- var boundValues = [];
- var activeTexture = null;
- for (var i = 0; i < bindings.length; ++i) {
- var binding = bindings[i];
- switch (binding) {
- case gl.TEXTURE_BINDING_2D:
- case gl.TEXTURE_BINDING_CUBE_MAP:
- var textureUnit = bindings[++i];
- if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31) {
- console.error("TEXTURE_BINDING_2D or TEXTURE_BINDING_CUBE_MAP must be followed by a valid texture unit");
- boundValues.push(null, null);
- break;
- }
- if (!activeTexture) {
- activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
- }
- gl.activeTexture(textureUnit);
- boundValues.push(gl.getParameter(binding), null);
- break;
- case gl.ACTIVE_TEXTURE:
- activeTexture = gl.getParameter(gl.ACTIVE_TEXTURE);
- boundValues.push(null);
- break;
- default:
- boundValues.push(gl.getParameter(binding));
- break;
- }
- }
- callback(gl);
- for (var i = 0; i < bindings.length; ++i) {
- var binding = bindings[i];
- var boundValue = boundValues[i];
- switch (binding) {
- case gl.ACTIVE_TEXTURE:
- break; // Ignore this binding, since we special-case it to happen last.
- case gl.ARRAY_BUFFER_BINDING:
- gl.bindBuffer(gl.ARRAY_BUFFER, boundValue);
- break;
- case gl.COLOR_CLEAR_VALUE:
- gl.clearColor(boundValue[0], boundValue[1], boundValue[2], boundValue[3]);
- break;
- case gl.COLOR_WRITEMASK:
- gl.colorMask(boundValue[0], boundValue[1], boundValue[2], boundValue[3]);
- break;
- case gl.CURRENT_PROGRAM:
- gl.useProgram(boundValue);
- break;
- case gl.ELEMENT_ARRAY_BUFFER_BINDING:
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, boundValue);
- break;
- case gl.FRAMEBUFFER_BINDING:
- gl.bindFramebuffer(gl.FRAMEBUFFER, boundValue);
- break;
- case gl.RENDERBUFFER_BINDING:
- gl.bindRenderbuffer(gl.RENDERBUFFER, boundValue);
- break;
- case gl.TEXTURE_BINDING_2D:
- var textureUnit = bindings[++i];
- if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31)
- break;
- gl.activeTexture(textureUnit);
- gl.bindTexture(gl.TEXTURE_2D, boundValue);
- break;
- case gl.TEXTURE_BINDING_CUBE_MAP:
- var textureUnit = bindings[++i];
- if (textureUnit < gl.TEXTURE0 || textureUnit > gl.TEXTURE31)
- break;
- gl.activeTexture(textureUnit);
- gl.bindTexture(gl.TEXTURE_CUBE_MAP, boundValue);
- break;
- case gl.VIEWPORT:
- gl.viewport(boundValue[0], boundValue[1], boundValue[2], boundValue[3]);
- break;
- case gl.BLEND:
- case gl.CULL_FACE:
- case gl.DEPTH_TEST:
- case gl.SCISSOR_TEST:
- case gl.STENCIL_TEST:
- if (boundValue) {
- gl.enable(binding);
- } else {
- gl.disable(binding);
- }
- break;
- default:
- console.log("No GL restore behavior for 0x" + binding.toString(16));
- break;
- }
- if (activeTexture) {
- gl.activeTexture(activeTexture);
- }
- }
- }
- module.exports = WGLUPreserveGLState;
- },{}],14:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Distortion = _dereq_('./distortion/distortion.js');
- var MathUtil = _dereq_('./math-util.js');
- var Util = _dereq_('./util.js');
- function Device(params) {
- this.width = params.width || Util.getScreenWidth();
- this.height = params.height || Util.getScreenHeight();
- this.widthMeters = params.widthMeters;
- this.heightMeters = params.heightMeters;
- this.bevelMeters = params.bevelMeters;
- }
- // Fallback Android device (based on Nexus 5 measurements) for use when
- // we can't recognize an Android device.
- var DEFAULT_ANDROID = new Device({
- widthMeters: 0.110,
- heightMeters: 0.062,
- bevelMeters: 0.004
- });
- // Fallback iOS device (based on iPhone6) for use when
- // we can't recognize an Android device.
- var DEFAULT_IOS = new Device({
- widthMeters: 0.1038,
- heightMeters: 0.0584,
- bevelMeters: 0.004
- });
- var Viewers = {
- CardboardV1: new CardboardViewer({
- id: 'CardboardV1',
- label: 'Cardboard I/O 2014',
- fov: 40,
- interLensDistance: 0.060,
- baselineLensDistance: 0.035,
- screenLensDistance: 0.042,
- distortionCoefficients: [0.441, 0.156],
- inverseCoefficients: [-0.4410035, 0.42756155, -0.4804439, 0.5460139,
- -0.58821183, 0.5733938, -0.48303202, 0.33299083, -0.17573841,
- 0.0651772, -0.01488963, 0.001559834]
- }),
- CardboardV2: new CardboardViewer({
- id: 'CardboardV2',
- label: 'Cardboard I/O 2015',
- fov: 60,
- interLensDistance: 0.064,
- baselineLensDistance: 0.035,
- screenLensDistance: 0.039,
- distortionCoefficients: [0.34, 0.55],
- inverseCoefficients: [-0.33836704, -0.18162185, 0.862655, -1.2462051,
- 1.0560602, -0.58208317, 0.21609078, -0.05444823, 0.009177956,
- -9.904169E-4, 6.183535E-5, -1.6981803E-6]
- })
- };
- var DEFAULT_LEFT_CENTER = {x: 0.5, y: 0.5};
- var DEFAULT_RIGHT_CENTER = {x: 0.5, y: 0.5};
- /**
- * Manages information about the device and the viewer.
- *
- * deviceParams indicates the parameters of the device to use (generally
- * obtained from dpdb.getDeviceParams()). Can be null to mean no device
- * params were found.
- */
- function DeviceInfo(deviceParams) {
- this.viewer = Viewers.CardboardV2;
- this.updateDeviceParams(deviceParams);
- this.distortion = new Distortion(this.viewer.distortionCoefficients);
- }
- DeviceInfo.prototype.updateDeviceParams = function(deviceParams) {
- this.device = this.determineDevice_(deviceParams) || this.device;
- };
- DeviceInfo.prototype.getDevice = function() {
- return this.device;
- };
- DeviceInfo.prototype.setViewer = function(viewer) {
- this.viewer = viewer;
- this.distortion = new Distortion(this.viewer.distortionCoefficients);
- };
- DeviceInfo.prototype.determineDevice_ = function(deviceParams) {
- if (!deviceParams) {
- // No parameters, so use a default.
- if (Util.isIOS()) {
- console.warn('Using fallback iOS device measurements.');
- return DEFAULT_IOS;
- } else {
- console.warn('Using fallback Android device measurements.');
- return DEFAULT_ANDROID;
- }
- }
- // Compute device screen dimensions based on deviceParams.
- var METERS_PER_INCH = 0.0254;
- var metersPerPixelX = METERS_PER_INCH / deviceParams.xdpi;
- var metersPerPixelY = METERS_PER_INCH / deviceParams.ydpi;
- var width = Util.getScreenWidth();
- var height = Util.getScreenHeight();
- return new Device({
- widthMeters: metersPerPixelX * width,
- heightMeters: metersPerPixelY * height,
- bevelMeters: deviceParams.bevelMm * 0.001,
- });
- };
- /**
- * Calculates field of view for the left eye.
- */
- DeviceInfo.prototype.getDistortedFieldOfViewLeftEye = function() {
- var viewer = this.viewer;
- var device = this.device;
- var distortion = this.distortion;
- // Device.height and device.width for device in portrait mode, so transpose.
- var eyeToScreenDistance = viewer.screenLensDistance;
- var outerDist = (device.widthMeters - viewer.interLensDistance) / 2;
- var innerDist = viewer.interLensDistance / 2;
- var bottomDist = viewer.baselineLensDistance - device.bevelMeters;
- var topDist = device.heightMeters - bottomDist;
- var outerAngle = MathUtil.radToDeg * Math.atan(
- distortion.distort(outerDist / eyeToScreenDistance));
- var innerAngle = MathUtil.radToDeg * Math.atan(
- distortion.distort(innerDist / eyeToScreenDistance));
- var bottomAngle = MathUtil.radToDeg * Math.atan(
- distortion.distort(bottomDist / eyeToScreenDistance));
- var topAngle = MathUtil.radToDeg * Math.atan(
- distortion.distort(topDist / eyeToScreenDistance));
- return {
- leftDegrees: Math.min(outerAngle, viewer.fov),
- rightDegrees: Math.min(innerAngle, viewer.fov),
- downDegrees: Math.min(bottomAngle, viewer.fov),
- upDegrees: Math.min(topAngle, viewer.fov)
- };
- };
- /**
- * Calculates the tan-angles from the maximum FOV for the left eye for the
- * current device and screen parameters.
- */
- DeviceInfo.prototype.getLeftEyeVisibleTanAngles = function() {
- var viewer = this.viewer;
- var device = this.device;
- var distortion = this.distortion;
- // Tan-angles from the max FOV.
- var fovLeft = Math.tan(-MathUtil.degToRad * viewer.fov);
- var fovTop = Math.tan(MathUtil.degToRad * viewer.fov);
- var fovRight = Math.tan(MathUtil.degToRad * viewer.fov);
- var fovBottom = Math.tan(-MathUtil.degToRad * viewer.fov);
- // Viewport size.
- var halfWidth = device.widthMeters / 4;
- var halfHeight = device.heightMeters / 2;
- // Viewport center, measured from left lens position.
- var verticalLensOffset = (viewer.baselineLensDistance - device.bevelMeters - halfHeight);
- var centerX = viewer.interLensDistance / 2 - halfWidth;
- var centerY = -verticalLensOffset;
- var centerZ = viewer.screenLensDistance;
- // Tan-angles of the viewport edges, as seen through the lens.
- var screenLeft = distortion.distort((centerX - halfWidth) / centerZ);
- var screenTop = distortion.distort((centerY + halfHeight) / centerZ);
- var screenRight = distortion.distort((centerX + halfWidth) / centerZ);
- var screenBottom = distortion.distort((centerY - halfHeight) / centerZ);
- // Compare the two sets of tan-angles and take the value closer to zero on each side.
- var result = new Float32Array(4);
- result[0] = Math.max(fovLeft, screenLeft);
- result[1] = Math.min(fovTop, screenTop);
- result[2] = Math.min(fovRight, screenRight);
- result[3] = Math.max(fovBottom, screenBottom);
- return result;
- };
- /**
- * Calculates the tan-angles from the maximum FOV for the left eye for the
- * current device and screen parameters, assuming no lenses.
- */
- DeviceInfo.prototype.getLeftEyeNoLensTanAngles = function() {
- var viewer = this.viewer;
- var device = this.device;
- var distortion = this.distortion;
- var result = new Float32Array(4);
- // Tan-angles from the max FOV.
- var fovLeft = distortion.distortInverse(Math.tan(-MathUtil.degToRad * viewer.fov));
- var fovTop = distortion.distortInverse(Math.tan(MathUtil.degToRad * viewer.fov));
- var fovRight = distortion.distortInverse(Math.tan(MathUtil.degToRad * viewer.fov));
- var fovBottom = distortion.distortInverse(Math.tan(-MathUtil.degToRad * viewer.fov));
- // Viewport size.
- var halfWidth = device.widthMeters / 4;
- var halfHeight = device.heightMeters / 2;
- // Viewport center, measured from left lens position.
- var verticalLensOffset = (viewer.baselineLensDistance - device.bevelMeters - halfHeight);
- var centerX = viewer.interLensDistance / 2 - halfWidth;
- var centerY = -verticalLensOffset;
- var centerZ = viewer.screenLensDistance;
- // Tan-angles of the viewport edges, as seen through the lens.
- var screenLeft = (centerX - halfWidth) / centerZ;
- var screenTop = (centerY + halfHeight) / centerZ;
- var screenRight = (centerX + halfWidth) / centerZ;
- var screenBottom = (centerY - halfHeight) / centerZ;
- // Compare the two sets of tan-angles and take the value closer to zero on each side.
- result[0] = Math.max(fovLeft, screenLeft);
- result[1] = Math.min(fovTop, screenTop);
- result[2] = Math.min(fovRight, screenRight);
- result[3] = Math.max(fovBottom, screenBottom);
- return result;
- };
- /**
- * Calculates the screen rectangle visible from the left eye for the
- * current device and screen parameters.
- */
- DeviceInfo.prototype.getLeftEyeVisibleScreenRect = function(undistortedFrustum) {
- var viewer = this.viewer;
- var device = this.device;
- var dist = viewer.screenLensDistance;
- var eyeX = (device.widthMeters - viewer.interLensDistance) / 2;
- var eyeY = viewer.baselineLensDistance - device.bevelMeters;
- var left = (undistortedFrustum[0] * dist + eyeX) / device.widthMeters;
- var top = (undistortedFrustum[1] * dist + eyeY) / device.heightMeters;
- var right = (undistortedFrustum[2] * dist + eyeX) / device.widthMeters;
- var bottom = (undistortedFrustum[3] * dist + eyeY) / device.heightMeters;
- return {
- x: left,
- y: bottom,
- width: right - left,
- height: top - bottom
- };
- };
- DeviceInfo.prototype.getFieldOfViewLeftEye = function(opt_isUndistorted) {
- return opt_isUndistorted ? this.getUndistortedFieldOfViewLeftEye() :
- this.getDistortedFieldOfViewLeftEye();
- };
- DeviceInfo.prototype.getFieldOfViewRightEye = function(opt_isUndistorted) {
- var fov = this.getFieldOfViewLeftEye(opt_isUndistorted);
- return {
- leftDegrees: fov.rightDegrees,
- rightDegrees: fov.leftDegrees,
- upDegrees: fov.upDegrees,
- downDegrees: fov.downDegrees
- };
- };
- /**
- * Calculates undistorted field of view for the left eye.
- */
- DeviceInfo.prototype.getUndistortedFieldOfViewLeftEye = function() {
- var p = this.getUndistortedParams_();
- return {
- leftDegrees: MathUtil.radToDeg * Math.atan(p.outerDist),
- rightDegrees: MathUtil.radToDeg * Math.atan(p.innerDist),
- downDegrees: MathUtil.radToDeg * Math.atan(p.bottomDist),
- upDegrees: MathUtil.radToDeg * Math.atan(p.topDist)
- };
- };
- DeviceInfo.prototype.getUndistortedViewportLeftEye = function() {
- var p = this.getUndistortedParams_();
- var viewer = this.viewer;
- var device = this.device;
- // Distances stored in local variables are in tan-angle units unless otherwise
- // noted.
- var eyeToScreenDistance = viewer.screenLensDistance;
- var screenWidth = device.widthMeters / eyeToScreenDistance;
- var screenHeight = device.heightMeters / eyeToScreenDistance;
- var xPxPerTanAngle = device.width / screenWidth;
- var yPxPerTanAngle = device.height / screenHeight;
- var x = Math.round((p.eyePosX - p.outerDist) * xPxPerTanAngle);
- var y = Math.round((p.eyePosY - p.bottomDist) * yPxPerTanAngle);
- return {
- x: x,
- y: y,
- width: Math.round((p.eyePosX + p.innerDist) * xPxPerTanAngle) - x,
- height: Math.round((p.eyePosY + p.topDist) * yPxPerTanAngle) - y
- };
- };
- DeviceInfo.prototype.getUndistortedParams_ = function() {
- var viewer = this.viewer;
- var device = this.device;
- var distortion = this.distortion;
- // Most of these variables in tan-angle units.
- var eyeToScreenDistance = viewer.screenLensDistance;
- var halfLensDistance = viewer.interLensDistance / 2 / eyeToScreenDistance;
- var screenWidth = device.widthMeters / eyeToScreenDistance;
- var screenHeight = device.heightMeters / eyeToScreenDistance;
- var eyePosX = screenWidth / 2 - halfLensDistance;
- var eyePosY = (viewer.baselineLensDistance - device.bevelMeters) / eyeToScreenDistance;
- var maxFov = viewer.fov;
- var viewerMax = distortion.distortInverse(Math.tan(MathUtil.degToRad * maxFov));
- var outerDist = Math.min(eyePosX, viewerMax);
- var innerDist = Math.min(halfLensDistance, viewerMax);
- var bottomDist = Math.min(eyePosY, viewerMax);
- var topDist = Math.min(screenHeight - eyePosY, viewerMax);
- return {
- outerDist: outerDist,
- innerDist: innerDist,
- topDist: topDist,
- bottomDist: bottomDist,
- eyePosX: eyePosX,
- eyePosY: eyePosY
- };
- };
- function CardboardViewer(params) {
- // A machine readable ID.
- this.id = params.id;
- // A human readable label.
- this.label = params.label;
- // Field of view in degrees (per side).
- this.fov = params.fov;
- // Distance between lens centers in meters.
- this.interLensDistance = params.interLensDistance;
- // Distance between viewer baseline and lens center in meters.
- this.baselineLensDistance = params.baselineLensDistance;
- // Screen-to-lens distance in meters.
- this.screenLensDistance = params.screenLensDistance;
- // Distortion coefficients.
- this.distortionCoefficients = params.distortionCoefficients;
- // Inverse distortion coefficients.
- // TODO: Calculate these from distortionCoefficients in the future.
- this.inverseCoefficients = params.inverseCoefficients;
- }
- // Export viewer information.
- DeviceInfo.Viewers = Viewers;
- module.exports = DeviceInfo;
- },{"./distortion/distortion.js":16,"./math-util.js":20,"./util.js":29}],15:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var VRDisplay = _dereq_('./base.js').VRDisplay;
- var HMDVRDevice = _dereq_('./base.js').HMDVRDevice;
- var PositionSensorVRDevice = _dereq_('./base.js').PositionSensorVRDevice;
- /**
- * Wraps a VRDisplay and exposes it as a HMDVRDevice
- */
- function VRDisplayHMDDevice(display) {
- this.display = display;
- this.hardwareUnitId = display.displayId;
- this.deviceId = 'webvr-polyfill:HMD:' + display.displayId;
- this.deviceName = display.displayName + ' (HMD)';
- }
- VRDisplayHMDDevice.prototype = new HMDVRDevice();
- VRDisplayHMDDevice.prototype.getEyeParameters = function(whichEye) {
- var eyeParameters = this.display.getEyeParameters(whichEye);
- return {
- currentFieldOfView: eyeParameters.fieldOfView,
- maximumFieldOfView: eyeParameters.fieldOfView,
- minimumFieldOfView: eyeParameters.fieldOfView,
- recommendedFieldOfView: eyeParameters.fieldOfView,
- eyeTranslation: { x: eyeParameters.offset[0], y: eyeParameters.offset[1], z: eyeParameters.offset[2] },
- renderRect: {
- x: (whichEye == 'right') ? eyeParameters.renderWidth : 0,
- y: 0,
- width: eyeParameters.renderWidth,
- height: eyeParameters.renderHeight
- }
- };
- };
- VRDisplayHMDDevice.prototype.setFieldOfView =
- function(opt_fovLeft, opt_fovRight, opt_zNear, opt_zFar) {
- // Not supported. getEyeParameters reports that the min, max, and recommended
- // FoV is all the same, so no adjustment can be made.
- };
- // TODO: Need to hook requestFullscreen to see if a wrapped VRDisplay was passed
- // in as an option. If so we should prevent the default fullscreen behavior and
- // call VRDisplay.requestPresent instead.
- /**
- * Wraps a VRDisplay and exposes it as a PositionSensorVRDevice
- */
- function VRDisplayPositionSensorDevice(display) {
- this.display = display;
- this.hardwareUnitId = display.displayId;
- this.deviceId = 'webvr-polyfill:PositionSensor: ' + display.displayId;
- this.deviceName = display.displayName + ' (PositionSensor)';
- }
- VRDisplayPositionSensorDevice.prototype = new PositionSensorVRDevice();
- VRDisplayPositionSensorDevice.prototype.getState = function() {
- var pose = this.display.getPose();
- return {
- position: pose.position ? { x: pose.position[0], y: pose.position[1], z: pose.position[2] } : null,
- orientation: pose.orientation ? { x: pose.orientation[0], y: pose.orientation[1], z: pose.orientation[2], w: pose.orientation[3] } : null,
- linearVelocity: null,
- linearAcceleration: null,
- angularVelocity: null,
- angularAcceleration: null
- };
- };
- VRDisplayPositionSensorDevice.prototype.resetState = function() {
- return this.positionDevice.resetPose();
- };
- module.exports.VRDisplayHMDDevice = VRDisplayHMDDevice;
- module.exports.VRDisplayPositionSensorDevice = VRDisplayPositionSensorDevice;
- },{"./base.js":9}],16:[function(_dereq_,module,exports){
- /**
- * TODO(smus): Implement coefficient inversion.
- */
- function Distortion(coefficients) {
- this.coefficients = coefficients;
- }
- /**
- * Calculates the inverse distortion for a radius.
- * </p><p>
- * Allows to compute the original undistorted radius from a distorted one.
- * See also getApproximateInverseDistortion() for a faster but potentially
- * less accurate method.
- *
- * @param {Number} radius Distorted radius from the lens center in tan-angle units.
- * @return {Number} The undistorted radius in tan-angle units.
- */
- Distortion.prototype.distortInverse = function(radius) {
- // Secant method.
- var r0 = 0;
- var r1 = 1;
- var dr0 = radius - this.distort(r0);
- while (Math.abs(r1 - r0) > 0.0001 /** 0.1mm */) {
- var dr1 = radius - this.distort(r1);
- var r2 = r1 - dr1 * ((r1 - r0) / (dr1 - dr0));
- r0 = r1;
- r1 = r2;
- dr0 = dr1;
- }
- return r1;
- };
- /**
- * Distorts a radius by its distortion factor from the center of the lenses.
- *
- * @param {Number} radius Radius from the lens center in tan-angle units.
- * @return {Number} The distorted radius in tan-angle units.
- */
- Distortion.prototype.distort = function(radius) {
- var r2 = radius * radius;
- var ret = 0;
- for (var i = 0; i < this.coefficients.length; i++) {
- ret = r2 * (ret + this.coefficients[i]);
- }
- return (ret + 1) * radius;
- };
- module.exports = Distortion;
- },{}],17:[function(_dereq_,module,exports){
- module.exports={
- "format": 1,
- "last_updated": "2017-08-27T14:39:31Z",
- "devices": [
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "asus/*/Nexus 7/*"
- },
- {
- "ua": "Nexus 7"
- }
- ],
- "dpi": [
- 320.8,
- 323
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "asus/*/ASUS_Z00AD/*"
- },
- {
- "ua": "ASUS_Z00AD"
- }
- ],
- "dpi": [
- 403,
- 404.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Google/*/Pixel XL/*"
- },
- {
- "ua": "Pixel XL"
- }
- ],
- "dpi": [
- 537.9,
- 533
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Google/*/Pixel/*"
- },
- {
- "ua": "Pixel"
- }
- ],
- "dpi": [
- 432.6,
- 436.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "HTC/*/HTC6435LVW/*"
- },
- {
- "ua": "HTC6435LVW"
- }
- ],
- "dpi": [
- 449.7,
- 443.3
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "HTC/*/HTC One XL/*"
- },
- {
- "ua": "HTC One XL"
- }
- ],
- "dpi": [
- 315.3,
- 314.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "htc/*/Nexus 9/*"
- },
- {
- "ua": "Nexus 9"
- }
- ],
- "dpi": 289,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "HTC/*/HTC One M9/*"
- },
- {
- "ua": "HTC One M9"
- }
- ],
- "dpi": [
- 442.5,
- 443.3
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "HTC/*/HTC One_M8/*"
- },
- {
- "ua": "HTC One_M8"
- }
- ],
- "dpi": [
- 449.7,
- 447.4
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "HTC/*/HTC One/*"
- },
- {
- "ua": "HTC One"
- }
- ],
- "dpi": 472.8,
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Huawei/*/Nexus 6P/*"
- },
- {
- "ua": "Nexus 6P"
- }
- ],
- "dpi": [
- 515.1,
- 518
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LENOVO/*/Lenovo PB2-690Y/*"
- },
- {
- "ua": "Lenovo PB2-690Y"
- }
- ],
- "dpi": [
- 457.2,
- 454.713
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/Nexus 5X/*"
- },
- {
- "ua": "Nexus 5X"
- }
- ],
- "dpi": [
- 422,
- 419.9
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/LGMS345/*"
- },
- {
- "ua": "LGMS345"
- }
- ],
- "dpi": [
- 221.7,
- 219.1
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/LG-D800/*"
- },
- {
- "ua": "LG-D800"
- }
- ],
- "dpi": [
- 422,
- 424.1
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/LG-D850/*"
- },
- {
- "ua": "LG-D850"
- }
- ],
- "dpi": [
- 537.9,
- 541.9
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/VS985 4G/*"
- },
- {
- "ua": "VS985 4G"
- }
- ],
- "dpi": [
- 537.9,
- 535.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/Nexus 5/*"
- },
- {
- "ua": "Nexus 5 B"
- }
- ],
- "dpi": [
- 442.4,
- 444.8
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/Nexus 4/*"
- },
- {
- "ua": "Nexus 4"
- }
- ],
- "dpi": [
- 319.8,
- 318.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/LG-P769/*"
- },
- {
- "ua": "LG-P769"
- }
- ],
- "dpi": [
- 240.6,
- 247.5
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/LGMS323/*"
- },
- {
- "ua": "LGMS323"
- }
- ],
- "dpi": [
- 206.6,
- 204.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "LGE/*/LGLS996/*"
- },
- {
- "ua": "LGLS996"
- }
- ],
- "dpi": [
- 403.4,
- 401.5
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Micromax/*/4560MMX/*"
- },
- {
- "ua": "4560MMX"
- }
- ],
- "dpi": [
- 240,
- 219.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Micromax/*/A250/*"
- },
- {
- "ua": "Micromax A250"
- }
- ],
- "dpi": [
- 480,
- 446.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Micromax/*/Micromax AQ4501/*"
- },
- {
- "ua": "Micromax AQ4501"
- }
- ],
- "dpi": 240,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/DROID RAZR/*"
- },
- {
- "ua": "DROID RAZR"
- }
- ],
- "dpi": [
- 368.1,
- 256.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT830C/*"
- },
- {
- "ua": "XT830C"
- }
- ],
- "dpi": [
- 254,
- 255.9
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1021/*"
- },
- {
- "ua": "XT1021"
- }
- ],
- "dpi": [
- 254,
- 256.7
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1023/*"
- },
- {
- "ua": "XT1023"
- }
- ],
- "dpi": [
- 254,
- 256.7
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1028/*"
- },
- {
- "ua": "XT1028"
- }
- ],
- "dpi": [
- 326.6,
- 327.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1034/*"
- },
- {
- "ua": "XT1034"
- }
- ],
- "dpi": [
- 326.6,
- 328.4
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1053/*"
- },
- {
- "ua": "XT1053"
- }
- ],
- "dpi": [
- 315.3,
- 316.1
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1562/*"
- },
- {
- "ua": "XT1562"
- }
- ],
- "dpi": [
- 403.4,
- 402.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/Nexus 6/*"
- },
- {
- "ua": "Nexus 6 B"
- }
- ],
- "dpi": [
- 494.3,
- 489.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1063/*"
- },
- {
- "ua": "XT1063"
- }
- ],
- "dpi": [
- 295,
- 296.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1064/*"
- },
- {
- "ua": "XT1064"
- }
- ],
- "dpi": [
- 295,
- 295.6
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1092/*"
- },
- {
- "ua": "XT1092"
- }
- ],
- "dpi": [
- 422,
- 424.1
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/XT1095/*"
- },
- {
- "ua": "XT1095"
- }
- ],
- "dpi": [
- 422,
- 423.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "motorola/*/G4/*"
- },
- {
- "ua": "Moto G (4)"
- }
- ],
- "dpi": 401,
- "bw": 4,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "OnePlus/*/A0001/*"
- },
- {
- "ua": "A0001"
- }
- ],
- "dpi": [
- 403.4,
- 401
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "OnePlus/*/ONE E1005/*"
- },
- {
- "ua": "ONE E1005"
- }
- ],
- "dpi": [
- 442.4,
- 441.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "OnePlus/*/ONE A2005/*"
- },
- {
- "ua": "ONE A2005"
- }
- ],
- "dpi": [
- 391.9,
- 405.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "OPPO/*/X909/*"
- },
- {
- "ua": "X909"
- }
- ],
- "dpi": [
- 442.4,
- 444.1
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9082/*"
- },
- {
- "ua": "GT-I9082"
- }
- ],
- "dpi": [
- 184.7,
- 185.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G360P/*"
- },
- {
- "ua": "SM-G360P"
- }
- ],
- "dpi": [
- 196.7,
- 205.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/Nexus S/*"
- },
- {
- "ua": "Nexus S"
- }
- ],
- "dpi": [
- 234.5,
- 229.8
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9300/*"
- },
- {
- "ua": "GT-I9300"
- }
- ],
- "dpi": [
- 304.8,
- 303.9
- ],
- "bw": 5,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-T230NU/*"
- },
- {
- "ua": "SM-T230NU"
- }
- ],
- "dpi": 216,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SGH-T399/*"
- },
- {
- "ua": "SGH-T399"
- }
- ],
- "dpi": [
- 217.7,
- 231.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SGH-M919/*"
- },
- {
- "ua": "SGH-M919"
- }
- ],
- "dpi": [
- 440.8,
- 437.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-N9005/*"
- },
- {
- "ua": "SM-N9005"
- }
- ],
- "dpi": [
- 386.4,
- 387
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SAMSUNG-SM-N900A/*"
- },
- {
- "ua": "SAMSUNG-SM-N900A"
- }
- ],
- "dpi": [
- 386.4,
- 387.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9500/*"
- },
- {
- "ua": "GT-I9500"
- }
- ],
- "dpi": [
- 442.5,
- 443.3
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9505/*"
- },
- {
- "ua": "GT-I9505"
- }
- ],
- "dpi": 439.4,
- "bw": 4,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G900F/*"
- },
- {
- "ua": "SM-G900F"
- }
- ],
- "dpi": [
- 415.6,
- 431.6
- ],
- "bw": 5,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G900M/*"
- },
- {
- "ua": "SM-G900M"
- }
- ],
- "dpi": [
- 415.6,
- 431.6
- ],
- "bw": 5,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G800F/*"
- },
- {
- "ua": "SM-G800F"
- }
- ],
- "dpi": 326.8,
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G906S/*"
- },
- {
- "ua": "SM-G906S"
- }
- ],
- "dpi": [
- 562.7,
- 572.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9300/*"
- },
- {
- "ua": "GT-I9300"
- }
- ],
- "dpi": [
- 306.7,
- 304.8
- ],
- "bw": 5,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-T535/*"
- },
- {
- "ua": "SM-T535"
- }
- ],
- "dpi": [
- 142.6,
- 136.4
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-N920C/*"
- },
- {
- "ua": "SM-N920C"
- }
- ],
- "dpi": [
- 515.1,
- 518.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-N920W8/*"
- },
- {
- "ua": "SM-N920W8"
- }
- ],
- "dpi": [
- 515.1,
- 518.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9300I/*"
- },
- {
- "ua": "GT-I9300I"
- }
- ],
- "dpi": [
- 304.8,
- 305.8
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-I9195/*"
- },
- {
- "ua": "GT-I9195"
- }
- ],
- "dpi": [
- 249.4,
- 256.7
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SPH-L520/*"
- },
- {
- "ua": "SPH-L520"
- }
- ],
- "dpi": [
- 249.4,
- 255.9
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SAMSUNG-SGH-I717/*"
- },
- {
- "ua": "SAMSUNG-SGH-I717"
- }
- ],
- "dpi": 285.8,
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SPH-D710/*"
- },
- {
- "ua": "SPH-D710"
- }
- ],
- "dpi": [
- 217.7,
- 204.2
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/GT-N7100/*"
- },
- {
- "ua": "GT-N7100"
- }
- ],
- "dpi": 265.1,
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SCH-I605/*"
- },
- {
- "ua": "SCH-I605"
- }
- ],
- "dpi": 265.1,
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/Galaxy Nexus/*"
- },
- {
- "ua": "Galaxy Nexus"
- }
- ],
- "dpi": [
- 315.3,
- 314.2
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-N910H/*"
- },
- {
- "ua": "SM-N910H"
- }
- ],
- "dpi": [
- 515.1,
- 518
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-N910C/*"
- },
- {
- "ua": "SM-N910C"
- }
- ],
- "dpi": [
- 515.2,
- 520.2
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G130M/*"
- },
- {
- "ua": "SM-G130M"
- }
- ],
- "dpi": [
- 165.9,
- 164.8
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G928I/*"
- },
- {
- "ua": "SM-G928I"
- }
- ],
- "dpi": [
- 515.1,
- 518.4
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G920F/*"
- },
- {
- "ua": "SM-G920F"
- }
- ],
- "dpi": 580.6,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G920P/*"
- },
- {
- "ua": "SM-G920P"
- }
- ],
- "dpi": [
- 522.5,
- 577
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G925F/*"
- },
- {
- "ua": "SM-G925F"
- }
- ],
- "dpi": 580.6,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G925V/*"
- },
- {
- "ua": "SM-G925V"
- }
- ],
- "dpi": [
- 522.5,
- 576.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G930F/*"
- },
- {
- "ua": "SM-G930F"
- }
- ],
- "dpi": 576.6,
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G935F/*"
- },
- {
- "ua": "SM-G935F"
- }
- ],
- "dpi": 533,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G950F/*"
- },
- {
- "ua": "SM-G950F"
- }
- ],
- "dpi": [
- 562.707,
- 565.293
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "samsung/*/SM-G955U/*"
- },
- {
- "ua": "SM-G955U"
- }
- ],
- "dpi": [
- 522.514,
- 525.762
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Sony/*/C6903/*"
- },
- {
- "ua": "C6903"
- }
- ],
- "dpi": [
- 442.5,
- 443.3
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Sony/*/D6653/*"
- },
- {
- "ua": "D6653"
- }
- ],
- "dpi": [
- 428.6,
- 427.6
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Sony/*/E6653/*"
- },
- {
- "ua": "E6653"
- }
- ],
- "dpi": [
- 428.6,
- 425.7
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Sony/*/E6853/*"
- },
- {
- "ua": "E6853"
- }
- ],
- "dpi": [
- 403.4,
- 401.9
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "Sony/*/SGP321/*"
- },
- {
- "ua": "SGP321"
- }
- ],
- "dpi": [
- 224.7,
- 224.1
- ],
- "bw": 3,
- "ac": 500
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "TCT/*/ALCATEL ONE TOUCH Fierce/*"
- },
- {
- "ua": "ALCATEL ONE TOUCH Fierce"
- }
- ],
- "dpi": [
- 240,
- 247.5
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "THL/*/thl 5000/*"
- },
- {
- "ua": "thl 5000"
- }
- ],
- "dpi": [
- 480,
- 443.3
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "android",
- "rules": [
- {
- "mdmh": "ZTE/*/ZTE Blade L2/*"
- },
- {
- "ua": "ZTE Blade L2"
- }
- ],
- "dpi": 240,
- "bw": 3,
- "ac": 500
- },
- {
- "type": "ios",
- "rules": [
- {
- "res": [
- 640,
- 960
- ]
- }
- ],
- "dpi": [
- 325.1,
- 328.4
- ],
- "bw": 4,
- "ac": 1000
- },
- {
- "type": "ios",
- "rules": [
- {
- "res": [
- 640,
- 1136
- ]
- }
- ],
- "dpi": [
- 317.1,
- 320.2
- ],
- "bw": 3,
- "ac": 1000
- },
- {
- "type": "ios",
- "rules": [
- {
- "res": [
- 750,
- 1334
- ]
- }
- ],
- "dpi": 326.4,
- "bw": 4,
- "ac": 1000
- },
- {
- "type": "ios",
- "rules": [
- {
- "res": [
- 1242,
- 2208
- ]
- }
- ],
- "dpi": [
- 453.6,
- 458.4
- ],
- "bw": 4,
- "ac": 1000
- },
- {
- "type": "ios",
- "rules": [
- {
- "res": [
- 1125,
- 2001
- ]
- }
- ],
- "dpi": [
- 410.9,
- 415.4
- ],
- "bw": 4,
- "ac": 1000
- }
- ]
- }
- },{}],18:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- // Offline cache of the DPDB, to be used until we load the online one (and
- // as a fallback in case we can't load the online one).
- var DPDB_CACHE = _dereq_('./dpdb.json');
- var Util = _dereq_('../util.js');
- // Online DPDB URL.
- var ONLINE_DPDB_URL =
- 'https://dpdb.webvr.rocks/dpdb.json';
- /**
- * Calculates device parameters based on the DPDB (Device Parameter Database).
- * Initially, uses the cached DPDB values.
- *
- * If fetchOnline == true, then this object tries to fetch the online version
- * of the DPDB and updates the device info if a better match is found.
- * Calls the onDeviceParamsUpdated callback when there is an update to the
- * device information.
- */
- function Dpdb(fetchOnline, onDeviceParamsUpdated) {
- // Start with the offline DPDB cache while we are loading the real one.
- this.dpdb = DPDB_CACHE;
- // Calculate device params based on the offline version of the DPDB.
- this.recalculateDeviceParams_();
- // XHR to fetch online DPDB file, if requested.
- if (fetchOnline) {
- // Set the callback.
- this.onDeviceParamsUpdated = onDeviceParamsUpdated;
- var xhr = new XMLHttpRequest();
- var obj = this;
- xhr.open('GET', ONLINE_DPDB_URL, true);
- xhr.addEventListener('load', function() {
- obj.loading = false;
- if (xhr.status >= 200 && xhr.status <= 299) {
- // Success.
- obj.dpdb = JSON.parse(xhr.response);
- obj.recalculateDeviceParams_();
- } else {
- // Error loading the DPDB.
- console.error('Error loading online DPDB!');
- }
- });
- xhr.send();
- }
- }
- // Returns the current device parameters.
- Dpdb.prototype.getDeviceParams = function() {
- return this.deviceParams;
- };
- // Recalculates this device's parameters based on the DPDB.
- Dpdb.prototype.recalculateDeviceParams_ = function() {
- var newDeviceParams = this.calcDeviceParams_();
- if (newDeviceParams) {
- this.deviceParams = newDeviceParams;
- // Invoke callback, if it is set.
- if (this.onDeviceParamsUpdated) {
- this.onDeviceParamsUpdated(this.deviceParams);
- }
- } else {
- console.error('Failed to recalculate device parameters.');
- }
- };
- // Returns a DeviceParams object that represents the best guess as to this
- // device's parameters. Can return null if the device does not match any
- // known devices.
- Dpdb.prototype.calcDeviceParams_ = function() {
- var db = this.dpdb; // shorthand
- if (!db) {
- console.error('DPDB not available.');
- return null;
- }
- if (db.format != 1) {
- console.error('DPDB has unexpected format version.');
- return null;
- }
- if (!db.devices || !db.devices.length) {
- console.error('DPDB does not have a devices section.');
- return null;
- }
- // Get the actual user agent and screen dimensions in pixels.
- var userAgent = navigator.userAgent || navigator.vendor || window.opera;
- var width = Util.getScreenWidth();
- var height = Util.getScreenHeight();
- if (!db.devices) {
- console.error('DPDB has no devices section.');
- return null;
- }
- for (var i = 0; i < db.devices.length; i++) {
- var device = db.devices[i];
- if (!device.rules) {
- console.warn('Device[' + i + '] has no rules section.');
- continue;
- }
- if (device.type != 'ios' && device.type != 'android') {
- console.warn('Device[' + i + '] has invalid type.');
- continue;
- }
- // See if this device is of the appropriate type.
- if (Util.isIOS() != (device.type == 'ios')) continue;
- // See if this device matches any of the rules:
- var matched = false;
- for (var j = 0; j < device.rules.length; j++) {
- var rule = device.rules[j];
- if (this.matchRule_(rule, userAgent, width, height)) {
- matched = true;
- break;
- }
- }
- if (!matched) continue;
- // device.dpi might be an array of [ xdpi, ydpi] or just a scalar.
- var xdpi = device.dpi[0] || device.dpi;
- var ydpi = device.dpi[1] || device.dpi;
- return new DeviceParams({ xdpi: xdpi, ydpi: ydpi, bevelMm: device.bw });
- }
- console.warn('No DPDB device match.');
- return null;
- };
- Dpdb.prototype.matchRule_ = function(rule, ua, screenWidth, screenHeight) {
- // We can only match 'ua' and 'res' rules, not other types like 'mdmh'
- // (which are meant for native platforms).
- if (!rule.ua && !rule.res) return false;
- // If our user agent string doesn't contain the indicated user agent string,
- // the match fails.
- if (rule.ua && ua.indexOf(rule.ua) < 0) return false;
- // If the rule specifies screen dimensions that don't correspond to ours,
- // the match fails.
- if (rule.res) {
- if (!rule.res[0] || !rule.res[1]) return false;
- var resX = rule.res[0];
- var resY = rule.res[1];
- // Compare min and max so as to make the order not matter, i.e., it should
- // be true that 640x480 == 480x640.
- if (Math.min(screenWidth, screenHeight) != Math.min(resX, resY) ||
- (Math.max(screenWidth, screenHeight) != Math.max(resX, resY))) {
- return false;
- }
- }
- return true;
- }
- function DeviceParams(params) {
- this.xdpi = params.xdpi;
- this.ydpi = params.ydpi;
- this.bevelMm = params.bevelMm;
- }
- module.exports = Dpdb;
- },{"../util.js":29,"./dpdb.json":17}],19:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('./util.js');
- var WebVRPolyfill = _dereq_('./webvr-polyfill.js').WebVRPolyfill;
- // Initialize a WebVRConfig just in case.
- window.WebVRConfig = Util.extend({
- // Forces availability of VR mode, even for non-mobile devices.
- FORCE_ENABLE_VR: false,
- // Complementary filter coefficient. 0 for accelerometer, 1 for gyro.
- K_FILTER: 0.98,
- // How far into the future to predict during fast motion (in seconds).
- PREDICTION_TIME_S: 0.040,
- // Flag to enable touch panner. In case you have your own touch controls.
- TOUCH_PANNER_DISABLED: true,
- // Flag to disabled the UI in VR Mode.
- CARDBOARD_UI_DISABLED: false, // Default: false
- // Flag to disable the instructions to rotate your device.
- ROTATE_INSTRUCTIONS_DISABLED: false, // Default: false.
- // Enable yaw panning only, disabling roll and pitch. This can be useful
- // for panoramas with nothing interesting above or below.
- YAW_ONLY: false,
- // To disable keyboard and mouse controls, if you want to use your own
- // implementation.
- MOUSE_KEYBOARD_CONTROLS_DISABLED: false,
- // Prevent the polyfill from initializing immediately. Requires the app
- // to call InitializeWebVRPolyfill() before it can be used.
- DEFER_INITIALIZATION: false,
- // Enable the deprecated version of the API (navigator.getVRDevices).
- ENABLE_DEPRECATED_API: false,
- // Scales the recommended buffer size reported by WebVR, which can improve
- // performance.
- // UPDATE(2016-05-03): Setting this to 0.5 by default since 1.0 does not
- // perform well on many mobile devices.
- BUFFER_SCALE: 0.5,
- // Allow VRDisplay.submitFrame to change gl bindings, which is more
- // efficient if the application code will re-bind its resources on the
- // next frame anyway. This has been seen to cause rendering glitches with
- // THREE.js.
- // Dirty bindings include: gl.FRAMEBUFFER_BINDING, gl.CURRENT_PROGRAM,
- // gl.ARRAY_BUFFER_BINDING, gl.ELEMENT_ARRAY_BUFFER_BINDING,
- // and gl.TEXTURE_BINDING_2D for texture unit 0.
- DIRTY_SUBMIT_FRAME_BINDINGS: false,
- // When set to true, this will cause a polyfilled VRDisplay to always be
- // appended to the list returned by navigator.getVRDisplays(), even if that
- // list includes a native VRDisplay.
- ALWAYS_APPEND_POLYFILL_DISPLAY: false,
- // There are versions of Chrome (M58-M60?) where the native WebVR API exists,
- // and instead of returning 0 VR displays when none are detected,
- // `navigator.getVRDisplays()`'s promise never resolves. This results
- // in the polyfill hanging and not being able to provide fallback
- // displays, so set a timeout in milliseconds to stop waiting for a response
- // and just use polyfilled displays.
- // https://bugs.chromium.org/p/chromium/issues/detail?id=727969
- GET_VR_DISPLAYS_TIMEOUT: 1000,
- }, window.WebVRConfig);
- if (!window.WebVRConfig.DEFER_INITIALIZATION) {
- new WebVRPolyfill();
- } else {
- window.InitializeWebVRPolyfill = function() {
- new WebVRPolyfill();
- }
- }
- window.WebVRPolyfill = WebVRPolyfill;
- },{"./util.js":29,"./webvr-polyfill.js":32}],20:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var MathUtil = window.MathUtil || {};
- MathUtil.degToRad = Math.PI / 180;
- MathUtil.radToDeg = 180 / Math.PI;
- // Some minimal math functionality borrowed from THREE.Math and stripped down
- // for the purposes of this library.
- MathUtil.Vector2 = function ( x, y ) {
- this.x = x || 0;
- this.y = y || 0;
- };
- MathUtil.Vector2.prototype = {
- constructor: MathUtil.Vector2,
- set: function ( x, y ) {
- this.x = x;
- this.y = y;
- return this;
- },
- copy: function ( v ) {
- this.x = v.x;
- this.y = v.y;
- return this;
- },
- subVectors: function ( a, b ) {
- this.x = a.x - b.x;
- this.y = a.y - b.y;
- return this;
- },
- };
- MathUtil.Vector3 = function ( x, y, z ) {
- this.x = x || 0;
- this.y = y || 0;
- this.z = z || 0;
- };
- MathUtil.Vector3.prototype = {
- constructor: MathUtil.Vector3,
- set: function ( x, y, z ) {
- this.x = x;
- this.y = y;
- this.z = z;
- return this;
- },
- copy: function ( v ) {
- this.x = v.x;
- this.y = v.y;
- this.z = v.z;
- return this;
- },
- length: function () {
- return Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z );
- },
- normalize: function () {
- var scalar = this.length();
- if ( scalar !== 0 ) {
- var invScalar = 1 / scalar;
- this.multiplyScalar(invScalar);
- } else {
- this.x = 0;
- this.y = 0;
- this.z = 0;
- }
- return this;
- },
- multiplyScalar: function ( scalar ) {
- this.x *= scalar;
- this.y *= scalar;
- this.z *= scalar;
- },
- applyQuaternion: function ( q ) {
- var x = this.x;
- var y = this.y;
- var z = this.z;
- var qx = q.x;
- var qy = q.y;
- var qz = q.z;
- var qw = q.w;
- // calculate quat * vector
- var ix = qw * x + qy * z - qz * y;
- var iy = qw * y + qz * x - qx * z;
- var iz = qw * z + qx * y - qy * x;
- var iw = - qx * x - qy * y - qz * z;
- // calculate result * inverse quat
- this.x = ix * qw + iw * - qx + iy * - qz - iz * - qy;
- this.y = iy * qw + iw * - qy + iz * - qx - ix * - qz;
- this.z = iz * qw + iw * - qz + ix * - qy - iy * - qx;
- return this;
- },
- dot: function ( v ) {
- return this.x * v.x + this.y * v.y + this.z * v.z;
- },
- crossVectors: function ( a, b ) {
- var ax = a.x, ay = a.y, az = a.z;
- var bx = b.x, by = b.y, bz = b.z;
- this.x = ay * bz - az * by;
- this.y = az * bx - ax * bz;
- this.z = ax * by - ay * bx;
- return this;
- },
- };
- MathUtil.Quaternion = function ( x, y, z, w ) {
- this.x = x || 0;
- this.y = y || 0;
- this.z = z || 0;
- this.w = ( w !== undefined ) ? w : 1;
- };
- MathUtil.Quaternion.prototype = {
- constructor: MathUtil.Quaternion,
- set: function ( x, y, z, w ) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- return this;
- },
- copy: function ( quaternion ) {
- this.x = quaternion.x;
- this.y = quaternion.y;
- this.z = quaternion.z;
- this.w = quaternion.w;
- return this;
- },
- setFromEulerXYZ: function( x, y, z ) {
- var c1 = Math.cos( x / 2 );
- var c2 = Math.cos( y / 2 );
- var c3 = Math.cos( z / 2 );
- var s1 = Math.sin( x / 2 );
- var s2 = Math.sin( y / 2 );
- var s3 = Math.sin( z / 2 );
- this.x = s1 * c2 * c3 + c1 * s2 * s3;
- this.y = c1 * s2 * c3 - s1 * c2 * s3;
- this.z = c1 * c2 * s3 + s1 * s2 * c3;
- this.w = c1 * c2 * c3 - s1 * s2 * s3;
- return this;
- },
- setFromEulerYXZ: function( x, y, z ) {
- var c1 = Math.cos( x / 2 );
- var c2 = Math.cos( y / 2 );
- var c3 = Math.cos( z / 2 );
- var s1 = Math.sin( x / 2 );
- var s2 = Math.sin( y / 2 );
- var s3 = Math.sin( z / 2 );
- this.x = s1 * c2 * c3 + c1 * s2 * s3;
- this.y = c1 * s2 * c3 - s1 * c2 * s3;
- this.z = c1 * c2 * s3 - s1 * s2 * c3;
- this.w = c1 * c2 * c3 + s1 * s2 * s3;
- return this;
- },
- setFromAxisAngle: function ( axis, angle ) {
- // http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/index.htm
- // assumes axis is normalized
- var halfAngle = angle / 2, s = Math.sin( halfAngle );
- this.x = axis.x * s;
- this.y = axis.y * s;
- this.z = axis.z * s;
- this.w = Math.cos( halfAngle );
- return this;
- },
- multiply: function ( q ) {
- return this.multiplyQuaternions( this, q );
- },
- multiplyQuaternions: function ( a, b ) {
- // from http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/code/index.htm
- var qax = a.x, qay = a.y, qaz = a.z, qaw = a.w;
- var qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
- this.x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
- this.y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
- this.z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
- this.w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
- return this;
- },
- inverse: function () {
- this.x *= -1;
- this.y *= -1;
- this.z *= -1;
- this.normalize();
- return this;
- },
- normalize: function () {
- var l = Math.sqrt( this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w );
- if ( l === 0 ) {
- this.x = 0;
- this.y = 0;
- this.z = 0;
- this.w = 1;
- } else {
- l = 1 / l;
- this.x = this.x * l;
- this.y = this.y * l;
- this.z = this.z * l;
- this.w = this.w * l;
- }
- return this;
- },
- slerp: function ( qb, t ) {
- if ( t === 0 ) return this;
- if ( t === 1 ) return this.copy( qb );
- var x = this.x, y = this.y, z = this.z, w = this.w;
- // http://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/slerp/
- var cosHalfTheta = w * qb.w + x * qb.x + y * qb.y + z * qb.z;
- if ( cosHalfTheta < 0 ) {
- this.w = - qb.w;
- this.x = - qb.x;
- this.y = - qb.y;
- this.z = - qb.z;
- cosHalfTheta = - cosHalfTheta;
- } else {
- this.copy( qb );
- }
- if ( cosHalfTheta >= 1.0 ) {
- this.w = w;
- this.x = x;
- this.y = y;
- this.z = z;
- return this;
- }
- var halfTheta = Math.acos( cosHalfTheta );
- var sinHalfTheta = Math.sqrt( 1.0 - cosHalfTheta * cosHalfTheta );
- if ( Math.abs( sinHalfTheta ) < 0.001 ) {
- this.w = 0.5 * ( w + this.w );
- this.x = 0.5 * ( x + this.x );
- this.y = 0.5 * ( y + this.y );
- this.z = 0.5 * ( z + this.z );
- return this;
- }
- var ratioA = Math.sin( ( 1 - t ) * halfTheta ) / sinHalfTheta,
- ratioB = Math.sin( t * halfTheta ) / sinHalfTheta;
- this.w = ( w * ratioA + this.w * ratioB );
- this.x = ( x * ratioA + this.x * ratioB );
- this.y = ( y * ratioA + this.y * ratioB );
- this.z = ( z * ratioA + this.z * ratioB );
- return this;
- },
- setFromUnitVectors: function () {
- // http://lolengine.net/blog/2014/02/24/quaternion-from-two-vectors-final
- // assumes direction vectors vFrom and vTo are normalized
- var v1, r;
- var EPS = 0.000001;
- return function ( vFrom, vTo ) {
- if ( v1 === undefined ) v1 = new MathUtil.Vector3();
- r = vFrom.dot( vTo ) + 1;
- if ( r < EPS ) {
- r = 0;
- if ( Math.abs( vFrom.x ) > Math.abs( vFrom.z ) ) {
- v1.set( - vFrom.y, vFrom.x, 0 );
- } else {
- v1.set( 0, - vFrom.z, vFrom.y );
- }
- } else {
- v1.crossVectors( vFrom, vTo );
- }
- this.x = v1.x;
- this.y = v1.y;
- this.z = v1.z;
- this.w = r;
- this.normalize();
- return this;
- }
- }(),
- };
- module.exports = MathUtil;
- },{}],21:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var VRDisplay = _dereq_('./base.js').VRDisplay;
- var MathUtil = _dereq_('./math-util.js');
- var Util = _dereq_('./util.js');
- // How much to rotate per key stroke.
- var KEY_SPEED = 0.15;
- var KEY_ANIMATION_DURATION = 80;
- // How much to rotate for mouse events.
- var MOUSE_SPEED_X = 0.5;
- var MOUSE_SPEED_Y = 0.3;
- /**
- * VRDisplay based on mouse and keyboard input. Designed for desktops/laptops
- * where orientation events aren't supported. Cannot present.
- */
- function MouseKeyboardVRDisplay() {
- this.displayName = 'Mouse and Keyboard VRDisplay (webvr-polyfill)';
- this.capabilities.hasOrientation = true;
- // Attach to mouse and keyboard events.
- window.addEventListener('keydown', this.onKeyDown_.bind(this));
- window.addEventListener('mousemove', this.onMouseMove_.bind(this));
- window.addEventListener('mousedown', this.onMouseDown_.bind(this));
- window.addEventListener('mouseup', this.onMouseUp_.bind(this));
- // "Private" members.
- this.phi_ = 0;
- this.theta_ = 0;
- // Variables for keyboard-based rotation animation.
- this.targetAngle_ = null;
- this.angleAnimation_ = null;
- // State variables for calculations.
- this.orientation_ = new MathUtil.Quaternion();
- // Variables for mouse-based rotation.
- this.rotateStart_ = new MathUtil.Vector2();
- this.rotateEnd_ = new MathUtil.Vector2();
- this.rotateDelta_ = new MathUtil.Vector2();
- this.isDragging_ = false;
- this.orientationOut_ = new Float32Array(4);
- }
- MouseKeyboardVRDisplay.prototype = new VRDisplay();
- MouseKeyboardVRDisplay.prototype.getImmediatePose = function() {
- this.orientation_.setFromEulerYXZ(this.phi_, this.theta_, 0);
- this.orientationOut_[0] = this.orientation_.x;
- this.orientationOut_[1] = this.orientation_.y;
- this.orientationOut_[2] = this.orientation_.z;
- this.orientationOut_[3] = this.orientation_.w;
- return {
- position: null,
- orientation: this.orientationOut_,
- linearVelocity: null,
- linearAcceleration: null,
- angularVelocity: null,
- angularAcceleration: null
- };
- };
- MouseKeyboardVRDisplay.prototype.onKeyDown_ = function(e) {
- // Track WASD and arrow keys.
- if (e.keyCode == 38) { // Up key.
- this.animatePhi_(this.phi_ + KEY_SPEED);
- } else if (e.keyCode == 39) { // Right key.
- this.animateTheta_(this.theta_ - KEY_SPEED);
- } else if (e.keyCode == 40) { // Down key.
- this.animatePhi_(this.phi_ - KEY_SPEED);
- } else if (e.keyCode == 37) { // Left key.
- this.animateTheta_(this.theta_ + KEY_SPEED);
- }
- };
- MouseKeyboardVRDisplay.prototype.animateTheta_ = function(targetAngle) {
- this.animateKeyTransitions_('theta_', targetAngle);
- };
- MouseKeyboardVRDisplay.prototype.animatePhi_ = function(targetAngle) {
- // Prevent looking too far up or down.
- targetAngle = Util.clamp(targetAngle, -Math.PI/2, Math.PI/2);
- this.animateKeyTransitions_('phi_', targetAngle);
- };
- /**
- * Start an animation to transition an angle from one value to another.
- */
- MouseKeyboardVRDisplay.prototype.animateKeyTransitions_ = function(angleName, targetAngle) {
- // If an animation is currently running, cancel it.
- if (this.angleAnimation_) {
- cancelAnimationFrame(this.angleAnimation_);
- }
- var startAngle = this[angleName];
- var startTime = new Date();
- // Set up an interval timer to perform the animation.
- this.angleAnimation_ = requestAnimationFrame(function animate() {
- // Once we're finished the animation, we're done.
- var elapsed = new Date() - startTime;
- if (elapsed >= KEY_ANIMATION_DURATION) {
- this[angleName] = targetAngle;
- cancelAnimationFrame(this.angleAnimation_);
- return;
- }
- // loop with requestAnimationFrame
- this.angleAnimation_ = requestAnimationFrame(animate.bind(this))
- // Linearly interpolate the angle some amount.
- var percent = elapsed / KEY_ANIMATION_DURATION;
- this[angleName] = startAngle + (targetAngle - startAngle) * percent;
- }.bind(this));
- };
- MouseKeyboardVRDisplay.prototype.onMouseDown_ = function(e) {
- this.rotateStart_.set(e.clientX, e.clientY);
- this.isDragging_ = true;
- };
- // Very similar to https://gist.github.com/mrflix/8351020
- MouseKeyboardVRDisplay.prototype.onMouseMove_ = function(e) {
- if (!this.isDragging_ && !this.isPointerLocked_()) {
- return;
- }
- // Support pointer lock API.
- if (this.isPointerLocked_()) {
- var movementX = e.movementX || e.mozMovementX || 0;
- var movementY = e.movementY || e.mozMovementY || 0;
- this.rotateEnd_.set(this.rotateStart_.x - movementX, this.rotateStart_.y - movementY);
- } else {
- this.rotateEnd_.set(e.clientX, e.clientY);
- }
- // Calculate how much we moved in mouse space.
- this.rotateDelta_.subVectors(this.rotateEnd_, this.rotateStart_);
- this.rotateStart_.copy(this.rotateEnd_);
- // Keep track of the cumulative euler angles.
- this.phi_ += 2 * Math.PI * this.rotateDelta_.y / screen.height * MOUSE_SPEED_Y;
- this.theta_ += 2 * Math.PI * this.rotateDelta_.x / screen.width * MOUSE_SPEED_X;
- // Prevent looking too far up or down.
- this.phi_ = Util.clamp(this.phi_, -Math.PI/2, Math.PI/2);
- };
- MouseKeyboardVRDisplay.prototype.onMouseUp_ = function(e) {
- this.isDragging_ = false;
- };
- MouseKeyboardVRDisplay.prototype.isPointerLocked_ = function() {
- var el = document.pointerLockElement || document.mozPointerLockElement ||
- document.webkitPointerLockElement;
- return el !== undefined;
- };
- MouseKeyboardVRDisplay.prototype.resetPose = function() {
- this.phi_ = 0;
- this.theta_ = 0;
- };
- module.exports = MouseKeyboardVRDisplay;
- },{"./base.js":9,"./math-util.js":20,"./util.js":29}],22:[function(_dereq_,module,exports){
- (function (global){
- // This is the entry point if requiring/importing via node, or
- // a build tool that uses package.json entry (like browserify, webpack).
- // If running in node with a window mock available, globalize its members
- // if needed. Otherwise, just continue to `./main`
- if (typeof global !== 'undefined' && global.window) {
- global.document = global.window.document;
- global.navigator = global.window.navigator;
- }
- _dereq_('./main');
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{"./main":19}],23:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('./util.js');
- function RotateInstructions() {
- this.loadIcon_();
- var overlay = document.createElement('div');
- var s = overlay.style;
- s.position = 'fixed';
- s.top = 0;
- s.right = 0;
- s.bottom = 0;
- s.left = 0;
- s.backgroundColor = 'gray';
- s.fontFamily = 'sans-serif';
- // Force this to be above the fullscreen canvas, which is at zIndex: 999999.
- s.zIndex = 1000000;
- var img = document.createElement('img');
- img.src = this.icon;
- var s = img.style;
- s.marginLeft = '25%';
- s.marginTop = '25%';
- s.width = '50%';
- overlay.appendChild(img);
- var text = document.createElement('div');
- var s = text.style;
- s.textAlign = 'center';
- s.fontSize = '16px';
- s.lineHeight = '24px';
- s.margin = '24px 25%';
- s.width = '50%';
- text.innerHTML = 'Place your phone into your Cardboard viewer.';
- overlay.appendChild(text);
- var snackbar = document.createElement('div');
- var s = snackbar.style;
- s.backgroundColor = '#CFD8DC';
- s.position = 'fixed';
- s.bottom = 0;
- s.width = '100%';
- s.height = '48px';
- s.padding = '14px 24px';
- s.boxSizing = 'border-box';
- s.color = '#656A6B';
- overlay.appendChild(snackbar);
- var snackbarText = document.createElement('div');
- snackbarText.style.float = 'left';
- snackbarText.innerHTML = 'No Cardboard viewer?';
- var snackbarButton = document.createElement('a');
- snackbarButton.href = 'https://www.google.com/get/cardboard/get-cardboard/';
- snackbarButton.innerHTML = 'get one';
- snackbarButton.target = '_blank';
- var s = snackbarButton.style;
- s.float = 'right';
- s.fontWeight = 600;
- s.textTransform = 'uppercase';
- s.borderLeft = '1px solid gray';
- s.paddingLeft = '24px';
- s.textDecoration = 'none';
- s.color = '#656A6B';
- snackbar.appendChild(snackbarText);
- snackbar.appendChild(snackbarButton);
- this.overlay = overlay;
- this.text = text;
- this.hide();
- }
- RotateInstructions.prototype.show = function(parent) {
- if (!parent && !this.overlay.parentElement) {
- document.body.appendChild(this.overlay);
- } else if (parent) {
- if (this.overlay.parentElement && this.overlay.parentElement != parent)
- this.overlay.parentElement.removeChild(this.overlay);
- parent.appendChild(this.overlay);
- }
- this.overlay.style.display = 'block';
- var img = this.overlay.querySelector('img');
- var s = img.style;
- if (Util.isLandscapeMode()) {
- s.width = '20%';
- s.marginLeft = '40%';
- s.marginTop = '3%';
- } else {
- s.width = '50%';
- s.marginLeft = '25%';
- s.marginTop = '25%';
- }
- };
- RotateInstructions.prototype.hide = function() {
- this.overlay.style.display = 'none';
- };
- RotateInstructions.prototype.showTemporarily = function(ms, parent) {
- this.show(parent);
- this.timer = setTimeout(this.hide.bind(this), ms);
- };
- RotateInstructions.prototype.disableShowTemporarily = function() {
- clearTimeout(this.timer);
- };
- RotateInstructions.prototype.update = function() {
- this.disableShowTemporarily();
- // In portrait VR mode, tell the user to rotate to landscape. Otherwise, hide
- // the instructions.
- if (!Util.isLandscapeMode() && Util.isMobile()) {
- this.show();
- } else {
- this.hide();
- }
- };
- RotateInstructions.prototype.loadIcon_ = function() {
- // Encoded asset_src/rotate-instructions.svg
- this.icon = Util.base64('image/svg+xml', 'PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+Cjxzdmcgd2lkdGg9IjE5OHB4IiBoZWlnaHQ9IjI0MHB4IiB2aWV3Qm94PSIwIDAgMTk4IDI0MCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4bWxuczpza2V0Y2g9Imh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaC9ucyI+CiAgICA8IS0tIEdlbmVyYXRvcjogU2tldGNoIDMuMy4zICgxMjA4MSkgLSBodHRwOi8vd3d3LmJvaGVtaWFuY29kaW5nLmNvbS9za2V0Y2ggLS0+CiAgICA8dGl0bGU+dHJhbnNpdGlvbjwvdGl0bGU+CiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4KICAgIDxkZWZzPjwvZGVmcz4KICAgIDxnIGlkPSJQYWdlLTEiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHNrZXRjaDp0eXBlPSJNU1BhZ2UiPgogICAgICAgIDxnIGlkPSJ0cmFuc2l0aW9uIiBza2V0Y2g6dHlwZT0iTVNBcnRib2FyZEdyb3VwIj4KICAgICAgICAgICAgPGcgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTQtKy1JbXBvcnRlZC1MYXllcnMtQ29weS0rLUltcG9ydGVkLUxheWVycy1Db3B5LTItQ29weSIgc2tldGNoOnR5cGU9Ik1TTGF5ZXJHcm91cCI+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHktNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsIDEwNy4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjYyNSwyLjUyNyBDMTQ5LjYyNSwyLjUyNyAxNTUuODA1LDYuMDk2IDE1Ni4zNjIsNi40MTggTDE1Ni4zNjIsNy4zMDQgQzE1Ni4zNjIsNy40ODEgMTU2LjM3NSw3LjY2NCAxNTYuNCw3Ljg1MyBDMTU2LjQxLDcuOTM0IDE1Ni40Miw4LjAxNSAxNTYuNDI3LDguMDk1IEMxNTYuNTY3LDkuNTEgMTU3LjQwMSwxMS4wOTMgMTU4LjUzMiwxMi4wOTQgTDE2NC4yNTIsMTcuMTU2IEwxNjQuMzMzLDE3LjA2NiBDMTY0LjMzMywxNy4wNjYgMTY4LjcxNSwxNC41MzYgMTY5LjU2OCwxNC4wNDIgQzE3MS4wMjUsMTQuODgzIDE5NS41MzgsMjkuMDM1IDE5NS41MzgsMjkuMDM1IEwxOTUuNTM4LDgzLjAzNiBDMTk1LjUzOCw4My44MDcgMTk1LjE1Miw4NC4yNTMgMTk0LjU5LDg0LjI1MyBDMTk0LjM1Nyw4NC4yNTMgMTk0LjA5NSw4NC4xNzcgMTkzLjgxOCw4NC4wMTcgTDE2OS44NTEsNzAuMTc5IEwxNjkuODM3LDcwLjIwMyBMMTQyLjUxNSw4NS45NzggTDE0MS42NjUsODQuNjU1IEMxMzYuOTM0LDgzLjEyNiAxMzEuOTE3LDgxLjkxNSAxMjYuNzE0LDgxLjA0NSBDMTI2LjcwOSw4MS4wNiAxMjYuNzA3LDgxLjA2OSAxMjYuNzA3LDgxLjA2OSBMMTIxLjY0LDk4LjAzIEwxMTMuNzQ5LDEwMi41ODYgTDExMy43MTIsMTAyLjUyMyBMMTEzLjcxMiwxMzAuMTEzIEMxMTMuNzEyLDEzMC44ODUgMTEzLjMyNiwxMzEuMzMgMTEyLjc2NCwxMzEuMzMgQzExMi41MzIsMTMxLjMzIDExMi4yNjksMTMxLjI1NCAxMTEuOTkyLDEzMS4wOTQgTDY5LjUxOSwxMDYuNTcyIEM2OC41NjksMTA2LjAyMyA2Ny43OTksMTA0LjY5NSA2Ny43OTksMTAzLjYwNSBMNjcuNzk5LDEwMi41NyBMNjcuNzc4LDEwMi42MTcgQzY3LjI3LDEwMi4zOTMgNjYuNjQ4LDEwMi4yNDkgNjUuOTYyLDEwMi4yMTggQzY1Ljg3NSwxMDIuMjE0IDY1Ljc4OCwxMDIuMjEyIDY1LjcwMSwxMDIuMjEyIEM2NS42MDYsMTAyLjIxMiA2NS41MTEsMTAyLjIxNSA2NS40MTYsMTAyLjIxOSBDNjUuMTk1LDEwMi4yMjkgNjQuOTc0LDEwMi4yMzUgNjQuNzU0LDEwMi4yMzUgQzY0LjMzMSwxMDIuMjM1IDYzLjkxMSwxMDIuMjE2IDYzLjQ5OCwxMDIuMTc4IEM2MS44NDMsMTAyLjAyNSA2MC4yOTgsMTAxLjU3OCA1OS4wOTQsMTAwLjg4MiBMMTIuNTE4LDczLjk5MiBMMTIuNTIzLDc0LjAwNCBMMi4yNDUsNTUuMjU0IEMxLjI0NCw1My40MjcgMi4wMDQsNTEuMDM4IDMuOTQzLDQ5LjkxOCBMNTkuOTU0LDE3LjU3MyBDNjAuNjI2LDE3LjE4NSA2MS4zNSwxNy4wMDEgNjIuMDUzLDE3LjAwMSBDNjMuMzc5LDE3LjAwMSA2NC42MjUsMTcuNjYgNjUuMjgsMTguODU0IEw2NS4yODUsMTguODUxIEw2NS41MTIsMTkuMjY0IEw2NS41MDYsMTkuMjY4IEM2NS45MDksMjAuMDAzIDY2LjQwNSwyMC42OCA2Ni45ODMsMjEuMjg2IEw2Ny4yNiwyMS41NTYgQzY5LjE3NCwyMy40MDYgNzEuNzI4LDI0LjM1NyA3NC4zNzMsMjQuMzU3IEM3Ni4zMjIsMjQuMzU3IDc4LjMyMSwyMy44NCA4MC4xNDgsMjIuNzg1IEM4MC4xNjEsMjIuNzg1IDg3LjQ2NywxOC41NjYgODcuNDY3LDE4LjU2NiBDODguMTM5LDE4LjE3OCA4OC44NjMsMTcuOTk0IDg5LjU2NiwxNy45OTQgQzkwLjg5MiwxNy45OTQgOTIuMTM4LDE4LjY1MiA5Mi43OTIsMTkuODQ3IEw5Ni4wNDIsMjUuNzc1IEw5Ni4wNjQsMjUuNzU3IEwxMDIuODQ5LDI5LjY3NCBMMTAyLjc0NCwyOS40OTIgTDE0OS42MjUsMi41MjcgTTE0OS42MjUsMC44OTIgQzE0OS4zNDMsMC44OTIgMTQ5LjA2MiwwLjk2NSAxNDguODEsMS4xMSBMMTAyLjY0MSwyNy42NjYgTDk3LjIzMSwyNC41NDIgTDk0LjIyNiwxOS4wNjEgQzkzLjMxMywxNy4zOTQgOTEuNTI3LDE2LjM1OSA4OS41NjYsMTYuMzU4IEM4OC41NTUsMTYuMzU4IDg3LjU0NiwxNi42MzIgODYuNjQ5LDE3LjE1IEM4My44NzgsMTguNzUgNzkuNjg3LDIxLjE2OSA3OS4zNzQsMjEuMzQ1IEM3OS4zNTksMjEuMzUzIDc5LjM0NSwyMS4zNjEgNzkuMzMsMjEuMzY5IEM3Ny43OTgsMjIuMjU0IDc2LjA4NCwyMi43MjIgNzQuMzczLDIyLjcyMiBDNzIuMDgxLDIyLjcyMiA2OS45NTksMjEuODkgNjguMzk3LDIwLjM4IEw2OC4xNDUsMjAuMTM1IEM2Ny43MDYsMTkuNjcyIDY3LjMyMywxOS4xNTYgNjcuMDA2LDE4LjYwMSBDNjYuOTg4LDE4LjU1OSA2Ni45NjgsMTguNTE5IDY2Ljk0NiwxOC40NzkgTDY2LjcxOSwxOC4wNjUgQzY2LjY5LDE4LjAxMiA2Ni42NTgsMTcuOTYgNjYuNjI0LDE3LjkxMSBDNjUuNjg2LDE2LjMzNyA2My45NTEsMTUuMzY2IDYyLjA1MywxNS4zNjYgQzYxLjA0MiwxNS4zNjYgNjAuMDMzLDE1LjY0IDU5LjEzNiwxNi4xNTggTDMuMTI1LDQ4LjUwMiBDMC40MjYsNTAuMDYxIC0wLjYxMyw1My40NDIgMC44MTEsNTYuMDQgTDExLjA4OSw3NC43OSBDMTEuMjY2LDc1LjExMyAxMS41MzcsNzUuMzUzIDExLjg1LDc1LjQ5NCBMNTguMjc2LDEwMi4yOTggQzU5LjY3OSwxMDMuMTA4IDYxLjQzMywxMDMuNjMgNjMuMzQ4LDEwMy44MDYgQzYzLjgxMiwxMDMuODQ4IDY0LjI4NSwxMDMuODcgNjQuNzU0LDEwMy44NyBDNjUsMTAzLjg3IDY1LjI0OSwxMDMuODY0IDY1LjQ5NCwxMDMuODUyIEM2NS41NjMsMTAzLjg0OSA2NS42MzIsMTAzLjg0NyA2NS43MDEsMTAzLjg0NyBDNjUuNzY0LDEwMy44NDcgNjUuODI4LDEwMy44NDkgNjUuODksMTAzLjg1MiBDNjUuOTg2LDEwMy44NTYgNjYuMDgsMTAzLjg2MyA2Ni4xNzMsMTAzLjg3NCBDNjYuMjgyLDEwNS40NjcgNjcuMzMyLDEwNy4xOTcgNjguNzAyLDEwNy45ODggTDExMS4xNzQsMTMyLjUxIEMxMTEuNjk4LDEzMi44MTIgMTEyLjIzMiwxMzIuOTY1IDExMi43NjQsMTMyLjk2NSBDMTE0LjI2MSwxMzIuOTY1IDExNS4zNDcsMTMxLjc2NSAxMTUuMzQ3LDEzMC4xMTMgTDExNS4zNDcsMTAzLjU1MSBMMTIyLjQ1OCw5OS40NDYgQzEyMi44MTksOTkuMjM3IDEyMy4wODcsOTguODk4IDEyMy4yMDcsOTguNDk4IEwxMjcuODY1LDgyLjkwNSBDMTMyLjI3OSw4My43MDIgMTM2LjU1Nyw4NC43NTMgMTQwLjYwNyw4Ni4wMzMgTDE0MS4xNCw4Ni44NjIgQzE0MS40NTEsODcuMzQ2IDE0MS45NzcsODcuNjEzIDE0Mi41MTYsODcuNjEzIEMxNDIuNzk0LDg3LjYxMyAxNDMuMDc2LDg3LjU0MiAxNDMuMzMzLDg3LjM5MyBMMTY5Ljg2NSw3Mi4wNzYgTDE5Myw4NS40MzMgQzE5My41MjMsODUuNzM1IDE5NC4wNTgsODUuODg4IDE5NC41OSw4NS44ODggQzE5Ni4wODcsODUuODg4IDE5Ny4xNzMsODQuNjg5IDE5Ny4xNzMsODMuMDM2IEwxOTcuMTczLDI5LjAzNSBDMTk3LjE3MywyOC40NTEgMTk2Ljg2MSwyNy45MTEgMTk2LjM1NSwyNy42MTkgQzE5Ni4zNTUsMjcuNjE5IDE3MS44NDMsMTMuNDY3IDE3MC4zODUsMTIuNjI2IEMxNzAuMTMyLDEyLjQ4IDE2OS44NSwxMi40MDcgMTY5LjU2OCwxMi40MDcgQzE2OS4yODUsMTIuNDA3IDE2OS4wMDIsMTIuNDgxIDE2OC43NDksMTIuNjI3IEMxNjguMTQzLDEyLjk3OCAxNjUuNzU2LDE0LjM1NyAxNjQuNDI0LDE1LjEyNSBMMTU5LjYxNSwxMC44NyBDMTU4Ljc5NiwxMC4xNDUgMTU4LjE1NCw4LjkzNyAxNTguMDU0LDcuOTM0IEMxNTguMDQ1LDcuODM3IDE1OC4wMzQsNy43MzkgMTU4LjAyMSw3LjY0IEMxNTguMDA1LDcuNTIzIDE1Ny45OTgsNy40MSAxNTcuOTk4LDcuMzA0IEwxNTcuOTk4LDYuNDE4IEMxNTcuOTk4LDUuODM0IDE1Ny42ODYsNS4yOTUgMTU3LjE4MSw1LjAwMiBDMTU2LjYyNCw0LjY4IDE1MC40NDIsMS4xMTEgMTUwLjQ0MiwxLjExMSBDMTUwLjE4OSwwLjk2NSAxNDkuOTA3LDAuODkyIDE0OS42MjUsMC44OTIiIGlkPSJGaWxsLTEiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTYuMDI3LDI1LjYzNiBMMTQyLjYwMyw1Mi41MjcgQzE0My44MDcsNTMuMjIyIDE0NC41ODIsNTQuMTE0IDE0NC44NDUsNTUuMDY4IEwxNDQuODM1LDU1LjA3NSBMNjMuNDYxLDEwMi4wNTcgTDYzLjQ2LDEwMi4wNTcgQzYxLjgwNiwxMDEuOTA1IDYwLjI2MSwxMDEuNDU3IDU5LjA1NywxMDAuNzYyIEwxMi40ODEsNzMuODcxIEw5Ni4wMjcsMjUuNjM2IiBpZD0iRmlsbC0yIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYzLjQ2MSwxMDIuMTc0IEM2My40NTMsMTAyLjE3NCA2My40NDYsMTAyLjE3NCA2My40MzksMTAyLjE3MiBDNjEuNzQ2LDEwMi4wMTYgNjAuMjExLDEwMS41NjMgNTguOTk4LDEwMC44NjMgTDEyLjQyMiw3My45NzMgQzEyLjM4Niw3My45NTIgMTIuMzY0LDczLjkxNCAxMi4zNjQsNzMuODcxIEMxMi4zNjQsNzMuODMgMTIuMzg2LDczLjc5MSAxMi40MjIsNzMuNzcgTDk1Ljk2OCwyNS41MzUgQzk2LjAwNCwyNS41MTQgOTYuMDQ5LDI1LjUxNCA5Ni4wODUsMjUuNTM1IEwxNDIuNjYxLDUyLjQyNiBDMTQzLjg4OCw1My4xMzQgMTQ0LjY4Miw1NC4wMzggMTQ0Ljk1Nyw1NS4wMzcgQzE0NC45Nyw1NS4wODMgMTQ0Ljk1Myw1NS4xMzMgMTQ0LjkxNSw1NS4xNjEgQzE0NC45MTEsNTUuMTY1IDE0NC44OTgsNTUuMTc0IDE0NC44OTQsNTUuMTc3IEw2My41MTksMTAyLjE1OCBDNjMuNTAxLDEwMi4xNjkgNjMuNDgxLDEwMi4xNzQgNjMuNDYxLDEwMi4xNzQgTDYzLjQ2MSwxMDIuMTc0IFogTTEyLjcxNCw3My44NzEgTDU5LjExNSwxMDAuNjYxIEM2MC4yOTMsMTAxLjM0MSA2MS43ODYsMTAxLjc4MiA2My40MzUsMTAxLjkzNyBMMTQ0LjcwNyw1NS4wMTUgQzE0NC40MjgsNTQuMTA4IDE0My42ODIsNTMuMjg1IDE0Mi41NDQsNTIuNjI4IEw5Ni4wMjcsMjUuNzcxIEwxMi43MTQsNzMuODcxIEwxMi43MTQsNzMuODcxIFoiIGlkPSJGaWxsLTMiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ4LjMyNyw1OC40NzEgQzE0OC4xNDUsNTguNDggMTQ3Ljk2Miw1OC40OCAxNDcuNzgxLDU4LjQ3MiBDMTQ1Ljg4Nyw1OC4zODkgMTQ0LjQ3OSw1Ny40MzQgMTQ0LjYzNiw1Ni4zNCBDMTQ0LjY4OSw1NS45NjcgMTQ0LjY2NCw1NS41OTcgMTQ0LjU2NCw1NS4yMzUgTDYzLjQ2MSwxMDIuMDU3IEM2NC4wODksMTAyLjExNSA2NC43MzMsMTAyLjEzIDY1LjM3OSwxMDIuMDk5IEM2NS41NjEsMTAyLjA5IDY1Ljc0MywxMDIuMDkgNjUuOTI1LDEwMi4wOTggQzY3LjgxOSwxMDIuMTgxIDY5LjIyNywxMDMuMTM2IDY5LjA3LDEwNC4yMyBMMTQ4LjMyNyw1OC40NzEiIGlkPSJGaWxsLTQiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNjkuMDcsMTA0LjM0NyBDNjkuMDQ4LDEwNC4zNDcgNjkuMDI1LDEwNC4zNCA2OS4wMDUsMTA0LjMyNyBDNjguOTY4LDEwNC4zMDEgNjguOTQ4LDEwNC4yNTcgNjguOTU1LDEwNC4yMTMgQzY5LDEwMy44OTYgNjguODk4LDEwMy41NzYgNjguNjU4LDEwMy4yODggQzY4LjE1MywxMDIuNjc4IDY3LjEwMywxMDIuMjY2IDY1LjkyLDEwMi4yMTQgQzY1Ljc0MiwxMDIuMjA2IDY1LjU2MywxMDIuMjA3IDY1LjM4NSwxMDIuMjE1IEM2NC43NDIsMTAyLjI0NiA2NC4wODcsMTAyLjIzMiA2My40NSwxMDIuMTc0IEM2My4zOTksMTAyLjE2OSA2My4zNTgsMTAyLjEzMiA2My4zNDcsMTAyLjA4MiBDNjMuMzM2LDEwMi4wMzMgNjMuMzU4LDEwMS45ODEgNjMuNDAyLDEwMS45NTYgTDE0NC41MDYsNTUuMTM0IEMxNDQuNTM3LDU1LjExNiAxNDQuNTc1LDU1LjExMyAxNDQuNjA5LDU1LjEyNyBDMTQ0LjY0Miw1NS4xNDEgMTQ0LjY2OCw1NS4xNyAxNDQuNjc3LDU1LjIwNCBDMTQ0Ljc4MSw1NS41ODUgMTQ0LjgwNiw1NS45NzIgMTQ0Ljc1MSw1Ni4zNTcgQzE0NC43MDYsNTYuNjczIDE0NC44MDgsNTYuOTk0IDE0NS4wNDcsNTcuMjgyIEMxNDUuNTUzLDU3Ljg5MiAxNDYuNjAyLDU4LjMwMyAxNDcuNzg2LDU4LjM1NSBDMTQ3Ljk2NCw1OC4zNjMgMTQ4LjE0Myw1OC4zNjMgMTQ4LjMyMSw1OC4zNTQgQzE0OC4zNzcsNTguMzUyIDE0OC40MjQsNTguMzg3IDE0OC40MzksNTguNDM4IEMxNDguNDU0LDU4LjQ5IDE0OC40MzIsNTguNTQ1IDE0OC4zODUsNTguNTcyIEw2OS4xMjksMTA0LjMzMSBDNjkuMTExLDEwNC4zNDIgNjkuMDksMTA0LjM0NyA2OS4wNywxMDQuMzQ3IEw2OS4wNywxMDQuMzQ3IFogTTY1LjY2NSwxMDEuOTc1IEM2NS43NTQsMTAxLjk3NSA2NS44NDIsMTAxLjk3NyA2NS45MywxMDEuOTgxIEM2Ny4xOTYsMTAyLjAzNyA2OC4yODMsMTAyLjQ2OSA2OC44MzgsMTAzLjEzOSBDNjkuMDY1LDEwMy40MTMgNjkuMTg4LDEwMy43MTQgNjkuMTk4LDEwNC4wMjEgTDE0Ny44ODMsNTguNTkyIEMxNDcuODQ3LDU4LjU5MiAxNDcuODExLDU4LjU5MSAxNDcuNzc2LDU4LjU4OSBDMTQ2LjUwOSw1OC41MzMgMTQ1LjQyMiw1OC4xIDE0NC44NjcsNTcuNDMxIEMxNDQuNTg1LDU3LjA5MSAxNDQuNDY1LDU2LjcwNyAxNDQuNTIsNTYuMzI0IEMxNDQuNTYzLDU2LjAyMSAxNDQuNTUyLDU1LjcxNiAxNDQuNDg4LDU1LjQxNCBMNjMuODQ2LDEwMS45NyBDNjQuMzUzLDEwMi4wMDIgNjQuODY3LDEwMi4wMDYgNjUuMzc0LDEwMS45ODIgQzY1LjQ3MSwxMDEuOTc3IDY1LjU2OCwxMDEuOTc1IDY1LjY2NSwxMDEuOTc1IEw2NS42NjUsMTAxLjk3NSBaIiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTIuMjA4LDU1LjEzNCBDMS4yMDcsNTMuMzA3IDEuOTY3LDUwLjkxNyAzLjkwNiw0OS43OTcgTDU5LjkxNywxNy40NTMgQzYxLjg1NiwxNi4zMzMgNjQuMjQxLDE2LjkwNyA2NS4yNDMsMTguNzM0IEw2NS40NzUsMTkuMTQ0IEM2NS44NzIsMTkuODgyIDY2LjM2OCwyMC41NiA2Ni45NDUsMjEuMTY1IEw2Ny4yMjMsMjEuNDM1IEM3MC41NDgsMjQuNjQ5IDc1LjgwNiwyNS4xNTEgODAuMTExLDIyLjY2NSBMODcuNDMsMTguNDQ1IEM4OS4zNywxNy4zMjYgOTEuNzU0LDE3Ljg5OSA5Mi43NTUsMTkuNzI3IEw5Ni4wMDUsMjUuNjU1IEwxMi40ODYsNzMuODg0IEwyLjIwOCw1NS4xMzQgWiIgaWQ9IkZpbGwtNiIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMi40ODYsNzQuMDAxIEMxMi40NzYsNzQuMDAxIDEyLjQ2NSw3My45OTkgMTIuNDU1LDczLjk5NiBDMTIuNDI0LDczLjk4OCAxMi4zOTksNzMuOTY3IDEyLjM4NCw3My45NCBMMi4xMDYsNTUuMTkgQzEuMDc1LDUzLjMxIDEuODU3LDUwLjg0NSAzLjg0OCw0OS42OTYgTDU5Ljg1OCwxNy4zNTIgQzYwLjUyNSwxNi45NjcgNjEuMjcxLDE2Ljc2NCA2Mi4wMTYsMTYuNzY0IEM2My40MzEsMTYuNzY0IDY0LjY2NiwxNy40NjYgNjUuMzI3LDE4LjY0NiBDNjUuMzM3LDE4LjY1NCA2NS4zNDUsMTguNjYzIDY1LjM1MSwxOC42NzQgTDY1LjU3OCwxOS4wODggQzY1LjU4NCwxOS4xIDY1LjU4OSwxOS4xMTIgNjUuNTkxLDE5LjEyNiBDNjUuOTg1LDE5LjgzOCA2Ni40NjksMjAuNDk3IDY3LjAzLDIxLjA4NSBMNjcuMzA1LDIxLjM1MSBDNjkuMTUxLDIzLjEzNyA3MS42NDksMjQuMTIgNzQuMzM2LDI0LjEyIEM3Ni4zMTMsMjQuMTIgNzguMjksMjMuNTgyIDgwLjA1MywyMi41NjMgQzgwLjA2NCwyMi41NTcgODAuMDc2LDIyLjU1MyA4MC4wODgsMjIuNTUgTDg3LjM3MiwxOC4zNDQgQzg4LjAzOCwxNy45NTkgODguNzg0LDE3Ljc1NiA4OS41MjksMTcuNzU2IEM5MC45NTYsMTcuNzU2IDkyLjIwMSwxOC40NzIgOTIuODU4LDE5LjY3IEw5Ni4xMDcsMjUuNTk5IEM5Ni4xMzgsMjUuNjU0IDk2LjExOCwyNS43MjQgOTYuMDYzLDI1Ljc1NiBMMTIuNTQ1LDczLjk4NSBDMTIuNTI2LDczLjk5NiAxMi41MDYsNzQuMDAxIDEyLjQ4Niw3NC4wMDEgTDEyLjQ4Niw3NC4wMDEgWiBNNjIuMDE2LDE2Ljk5NyBDNjEuMzEyLDE2Ljk5NyA2MC42MDYsMTcuMTkgNTkuOTc1LDE3LjU1NCBMMy45NjUsNDkuODk5IEMyLjA4Myw1MC45ODUgMS4zNDEsNTMuMzA4IDIuMzEsNTUuMDc4IEwxMi41MzEsNzMuNzIzIEw5NS44NDgsMjUuNjExIEw5Mi42NTMsMTkuNzgyIEM5Mi4wMzgsMTguNjYgOTAuODcsMTcuOTkgODkuNTI5LDE3Ljk5IEM4OC44MjUsMTcuOTkgODguMTE5LDE4LjE4MiA4Ny40ODksMTguNTQ3IEw4MC4xNzIsMjIuNzcyIEM4MC4xNjEsMjIuNzc4IDgwLjE0OSwyMi43ODIgODAuMTM3LDIyLjc4NSBDNzguMzQ2LDIzLjgxMSA3Ni4zNDEsMjQuMzU0IDc0LjMzNiwyNC4zNTQgQzcxLjU4OCwyNC4zNTQgNjkuMDMzLDIzLjM0NyA2Ny4xNDIsMjEuNTE5IEw2Ni44NjQsMjEuMjQ5IEM2Ni4yNzcsMjAuNjM0IDY1Ljc3NCwxOS45NDcgNjUuMzY3LDE5LjIwMyBDNjUuMzYsMTkuMTkyIDY1LjM1NiwxOS4xNzkgNjUuMzU0LDE5LjE2NiBMNjUuMTYzLDE4LjgxOSBDNjUuMTU0LDE4LjgxMSA2NS4xNDYsMTguODAxIDY1LjE0LDE4Ljc5IEM2NC41MjUsMTcuNjY3IDYzLjM1NywxNi45OTcgNjIuMDE2LDE2Ljk5NyBMNjIuMDE2LDE2Ljk5NyBaIiBpZD0iRmlsbC03IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTQyLjQzNCw0OC44MDggTDQyLjQzNCw0OC44MDggQzM5LjkyNCw0OC44MDcgMzcuNzM3LDQ3LjU1IDM2LjU4Miw0NS40NDMgQzM0Ljc3MSw0Mi4xMzkgMzYuMTQ0LDM3LjgwOSAzOS42NDEsMzUuNzg5IEw1MS45MzIsMjguNjkxIEM1My4xMDMsMjguMDE1IDU0LjQxMywyNy42NTggNTUuNzIxLDI3LjY1OCBDNTguMjMxLDI3LjY1OCA2MC40MTgsMjguOTE2IDYxLjU3MywzMS4wMjMgQzYzLjM4NCwzNC4zMjcgNjIuMDEyLDM4LjY1NyA1OC41MTQsNDAuNjc3IEw0Ni4yMjMsNDcuNzc1IEM0NS4wNTMsNDguNDUgNDMuNzQyLDQ4LjgwOCA0Mi40MzQsNDguODA4IEw0Mi40MzQsNDguODA4IFogTTU1LjcyMSwyOC4xMjUgQzU0LjQ5NSwyOC4xMjUgNTMuMjY1LDI4LjQ2MSA1Mi4xNjYsMjkuMDk2IEwzOS44NzUsMzYuMTk0IEMzNi41OTYsMzguMDg3IDM1LjMwMiw0Mi4xMzYgMzYuOTkyLDQ1LjIxOCBDMzguMDYzLDQ3LjE3MyA0MC4wOTgsNDguMzQgNDIuNDM0LDQ4LjM0IEM0My42NjEsNDguMzQgNDQuODksNDguMDA1IDQ1Ljk5LDQ3LjM3IEw1OC4yODEsNDAuMjcyIEM2MS41NiwzOC4zNzkgNjIuODUzLDM0LjMzIDYxLjE2NCwzMS4yNDggQzYwLjA5MiwyOS4yOTMgNTguMDU4LDI4LjEyNSA1NS43MjEsMjguMTI1IEw1NS43MjEsMjguMTI1IFoiIGlkPSJGaWxsLTgiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTQ5LjU4OCwyLjQwNyBDMTQ5LjU4OCwyLjQwNyAxNTUuNzY4LDUuOTc1IDE1Ni4zMjUsNi4yOTcgTDE1Ni4zMjUsNy4xODQgQzE1Ni4zMjUsNy4zNiAxNTYuMzM4LDcuNTQ0IDE1Ni4zNjIsNy43MzMgQzE1Ni4zNzMsNy44MTQgMTU2LjM4Miw3Ljg5NCAxNTYuMzksNy45NzUgQzE1Ni41Myw5LjM5IDE1Ny4zNjMsMTAuOTczIDE1OC40OTUsMTEuOTc0IEwxNjUuODkxLDE4LjUxOSBDMTY2LjA2OCwxOC42NzUgMTY2LjI0OSwxOC44MTQgMTY2LjQzMiwxOC45MzQgQzE2OC4wMTEsMTkuOTc0IDE2OS4zODIsMTkuNCAxNjkuNDk0LDE3LjY1MiBDMTY5LjU0MywxNi44NjggMTY5LjU1MSwxNi4wNTcgMTY5LjUxNywxNS4yMjMgTDE2OS41MTQsMTUuMDYzIEwxNjkuNTE0LDEzLjkxMiBDMTcwLjc4LDE0LjY0MiAxOTUuNTAxLDI4LjkxNSAxOTUuNTAxLDI4LjkxNSBMMTk1LjUwMSw4Mi45MTUgQzE5NS41MDEsODQuMDA1IDE5NC43MzEsODQuNDQ1IDE5My43ODEsODMuODk3IEwxNTEuMzA4LDU5LjM3NCBDMTUwLjM1OCw1OC44MjYgMTQ5LjU4OCw1Ny40OTcgMTQ5LjU4OCw1Ni40MDggTDE0OS41ODgsMjIuMzc1IiBpZD0iRmlsbC05IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE5NC41NTMsODQuMjUgQzE5NC4yOTYsODQuMjUgMTk0LjAxMyw4NC4xNjUgMTkzLjcyMiw4My45OTcgTDE1MS4yNSw1OS40NzYgQzE1MC4yNjksNTguOTA5IDE0OS40NzEsNTcuNTMzIDE0OS40NzEsNTYuNDA4IEwxNDkuNDcxLDIyLjM3NSBMMTQ5LjcwNSwyMi4zNzUgTDE0OS43MDUsNTYuNDA4IEMxNDkuNzA1LDU3LjQ1OSAxNTAuNDUsNTguNzQ0IDE1MS4zNjYsNTkuMjc0IEwxOTMuODM5LDgzLjc5NSBDMTk0LjI2Myw4NC4wNCAxOTQuNjU1LDg0LjA4MyAxOTQuOTQyLDgzLjkxNyBDMTk1LjIyNyw4My43NTMgMTk1LjM4NCw4My4zOTcgMTk1LjM4NCw4Mi45MTUgTDE5NS4zODQsMjguOTgyIEMxOTQuMTAyLDI4LjI0MiAxNzIuMTA0LDE1LjU0MiAxNjkuNjMxLDE0LjExNCBMMTY5LjYzNCwxNS4yMiBDMTY5LjY2OCwxNi4wNTIgMTY5LjY2LDE2Ljg3NCAxNjkuNjEsMTcuNjU5IEMxNjkuNTU2LDE4LjUwMyAxNjkuMjE0LDE5LjEyMyAxNjguNjQ3LDE5LjQwNSBDMTY4LjAyOCwxOS43MTQgMTY3LjE5NywxOS41NzggMTY2LjM2NywxOS4wMzIgQzE2Ni4xODEsMTguOTA5IDE2NS45OTUsMTguNzY2IDE2NS44MTQsMTguNjA2IEwxNTguNDE3LDEyLjA2MiBDMTU3LjI1OSwxMS4wMzYgMTU2LjQxOCw5LjQzNyAxNTYuMjc0LDcuOTg2IEMxNTYuMjY2LDcuOTA3IDE1Ni4yNTcsNy44MjcgMTU2LjI0Nyw3Ljc0OCBDMTU2LjIyMSw3LjU1NSAxNTYuMjA5LDcuMzY1IDE1Ni4yMDksNy4xODQgTDE1Ni4yMDksNi4zNjQgQzE1NS4zNzUsNS44ODMgMTQ5LjUyOSwyLjUwOCAxNDkuNTI5LDIuNTA4IEwxNDkuNjQ2LDIuMzA2IEMxNDkuNjQ2LDIuMzA2IDE1NS44MjcsNS44NzQgMTU2LjM4NCw2LjE5NiBMMTU2LjQ0Miw2LjIzIEwxNTYuNDQyLDcuMTg0IEMxNTYuNDQyLDcuMzU1IDE1Ni40NTQsNy41MzUgMTU2LjQ3OCw3LjcxNyBDMTU2LjQ4OSw3LjggMTU2LjQ5OSw3Ljg4MiAxNTYuNTA3LDcuOTYzIEMxNTYuNjQ1LDkuMzU4IDE1Ny40NTUsMTAuODk4IDE1OC41NzIsMTEuODg2IEwxNjUuOTY5LDE4LjQzMSBDMTY2LjE0MiwxOC41ODQgMTY2LjMxOSwxOC43MiAxNjYuNDk2LDE4LjgzNyBDMTY3LjI1NCwxOS4zMzYgMTY4LDE5LjQ2NyAxNjguNTQzLDE5LjE5NiBDMTY5LjAzMywxOC45NTMgMTY5LjMyOSwxOC40MDEgMTY5LjM3NywxNy42NDUgQzE2OS40MjcsMTYuODY3IDE2OS40MzQsMTYuMDU0IDE2OS40MDEsMTUuMjI4IEwxNjkuMzk3LDE1LjA2NSBMMTY5LjM5NywxMy43MSBMMTY5LjU3MiwxMy44MSBDMTcwLjgzOSwxNC41NDEgMTk1LjU1OSwyOC44MTQgMTk1LjU1OSwyOC44MTQgTDE5NS42MTgsMjguODQ3IEwxOTUuNjE4LDgyLjkxNSBDMTk1LjYxOCw4My40ODQgMTk1LjQyLDgzLjkxMSAxOTUuMDU5LDg0LjExOSBDMTk0LjkwOCw4NC4yMDYgMTk0LjczNyw4NC4yNSAxOTQuNTUzLDg0LjI1IiBpZD0iRmlsbC0xMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDUuNjg1LDU2LjE2MSBMMTY5LjgsNzAuMDgzIEwxNDMuODIyLDg1LjA4MSBMMTQyLjM2LDg0Ljc3NCBDMTM1LjgyNiw4Mi42MDQgMTI4LjczMiw4MS4wNDYgMTIxLjM0MSw4MC4xNTggQzExNi45NzYsNzkuNjM0IDExMi42NzgsODEuMjU0IDExMS43NDMsODMuNzc4IEMxMTEuNTA2LDg0LjQxNCAxMTEuNTAzLDg1LjA3MSAxMTEuNzMyLDg1LjcwNiBDMTEzLjI3LDg5Ljk3MyAxMTUuOTY4LDk0LjA2OSAxMTkuNzI3LDk3Ljg0MSBMMTIwLjI1OSw5OC42ODYgQzEyMC4yNiw5OC42ODUgOTQuMjgyLDExMy42ODMgOTQuMjgyLDExMy42ODMgTDcwLjE2Nyw5OS43NjEgTDE0NS42ODUsNTYuMTYxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik05NC4yODIsMTEzLjgxOCBMOTQuMjIzLDExMy43ODUgTDY5LjkzMyw5OS43NjEgTDcwLjEwOCw5OS42NiBMMTQ1LjY4NSw1Ni4wMjYgTDE0NS43NDMsNTYuMDU5IEwxNzAuMDMzLDcwLjA4MyBMMTQzLjg0Miw4NS4yMDUgTDE0My43OTcsODUuMTk1IEMxNDMuNzcyLDg1LjE5IDE0Mi4zMzYsODQuODg4IDE0Mi4zMzYsODQuODg4IEMxMzUuNzg3LDgyLjcxNCAxMjguNzIzLDgxLjE2MyAxMjEuMzI3LDgwLjI3NCBDMTIwLjc4OCw4MC4yMDkgMTIwLjIzNiw4MC4xNzcgMTE5LjY4OSw4MC4xNzcgQzExNS45MzEsODAuMTc3IDExMi42MzUsODEuNzA4IDExMS44NTIsODMuODE5IEMxMTEuNjI0LDg0LjQzMiAxMTEuNjIxLDg1LjA1MyAxMTEuODQyLDg1LjY2NyBDMTEzLjM3Nyw4OS45MjUgMTE2LjA1OCw5My45OTMgMTE5LjgxLDk3Ljc1OCBMMTE5LjgyNiw5Ny43NzkgTDEyMC4zNTIsOTguNjE0IEMxMjAuMzU0LDk4LjYxNyAxMjAuMzU2LDk4LjYyIDEyMC4zNTgsOTguNjI0IEwxMjAuNDIyLDk4LjcyNiBMMTIwLjMxNyw5OC43ODcgQzEyMC4yNjQsOTguODE4IDk0LjU5OSwxMTMuNjM1IDk0LjM0LDExMy43ODUgTDk0LjI4MiwxMTMuODE4IEw5NC4yODIsMTEzLjgxOCBaIE03MC40MDEsOTkuNzYxIEw5NC4yODIsMTEzLjU0OSBMMTE5LjA4NCw5OS4yMjkgQzExOS42Myw5OC45MTQgMTE5LjkzLDk4Ljc0IDEyMC4xMDEsOTguNjU0IEwxMTkuNjM1LDk3LjkxNCBDMTE1Ljg2NCw5NC4xMjcgMTEzLjE2OCw5MC4wMzMgMTExLjYyMiw4NS43NDYgQzExMS4zODIsODUuMDc5IDExMS4zODYsODQuNDA0IDExMS42MzMsODMuNzM4IEMxMTIuNDQ4LDgxLjUzOSAxMTUuODM2LDc5Ljk0MyAxMTkuNjg5LDc5Ljk0MyBDMTIwLjI0Niw3OS45NDMgMTIwLjgwNiw3OS45NzYgMTIxLjM1NSw4MC4wNDIgQzEyOC43NjcsODAuOTMzIDEzNS44NDYsODIuNDg3IDE0Mi4zOTYsODQuNjYzIEMxNDMuMjMyLDg0LjgzOCAxNDMuNjExLDg0LjkxNyAxNDMuNzg2LDg0Ljk2NyBMMTY5LjU2Niw3MC4wODMgTDE0NS42ODUsNTYuMjk1IEw3MC40MDEsOTkuNzYxIEw3MC40MDEsOTkuNzYxIFoiIGlkPSJGaWxsLTEyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2Ny4yMywxOC45NzkgTDE2Ny4yMyw2OS44NSBMMTM5LjkwOSw4NS42MjMgTDEzMy40NDgsNzEuNDU2IEMxMzIuNTM4LDY5LjQ2IDEzMC4wMiw2OS43MTggMTI3LjgyNCw3Mi4wMyBDMTI2Ljc2OSw3My4xNCAxMjUuOTMxLDc0LjU4NSAxMjUuNDk0LDc2LjA0OCBMMTE5LjAzNCw5Ny42NzYgTDkxLjcxMiwxMTMuNDUgTDkxLjcxMiw2Mi41NzkgTDE2Ny4yMywxOC45NzkiIGlkPSJGaWxsLTEzIiBmaWxsPSIjRkZGRkZGIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTkxLjcxMiwxMTMuNTY3IEM5MS42OTIsMTEzLjU2NyA5MS42NzIsMTEzLjU2MSA5MS42NTMsMTEzLjU1MSBDOTEuNjE4LDExMy41MyA5MS41OTUsMTEzLjQ5MiA5MS41OTUsMTEzLjQ1IEw5MS41OTUsNjIuNTc5IEM5MS41OTUsNjIuNTM3IDkxLjYxOCw2Mi40OTkgOTEuNjUzLDYyLjQ3OCBMMTY3LjE3MiwxOC44NzggQzE2Ny4yMDgsMTguODU3IDE2Ny4yNTIsMTguODU3IDE2Ny4yODgsMTguODc4IEMxNjcuMzI0LDE4Ljg5OSAxNjcuMzQ3LDE4LjkzNyAxNjcuMzQ3LDE4Ljk3OSBMMTY3LjM0Nyw2OS44NSBDMTY3LjM0Nyw2OS44OTEgMTY3LjMyNCw2OS45MyAxNjcuMjg4LDY5Ljk1IEwxMzkuOTY3LDg1LjcyNSBDMTM5LjkzOSw4NS43NDEgMTM5LjkwNSw4NS43NDUgMTM5Ljg3Myw4NS43MzUgQzEzOS44NDIsODUuNzI1IDEzOS44MTYsODUuNzAyIDEzOS44MDIsODUuNjcyIEwxMzMuMzQyLDcxLjUwNCBDMTMyLjk2Nyw3MC42ODIgMTMyLjI4LDcwLjIyOSAxMzEuNDA4LDcwLjIyOSBDMTMwLjMxOSw3MC4yMjkgMTI5LjA0NCw3MC45MTUgMTI3LjkwOCw3Mi4xMSBDMTI2Ljg3NCw3My4yIDEyNi4wMzQsNzQuNjQ3IDEyNS42MDYsNzYuMDgyIEwxMTkuMTQ2LDk3LjcwOSBDMTE5LjEzNyw5Ny43MzggMTE5LjExOCw5Ny43NjIgMTE5LjA5Miw5Ny43NzcgTDkxLjc3LDExMy41NTEgQzkxLjc1MiwxMTMuNTYxIDkxLjczMiwxMTMuNTY3IDkxLjcxMiwxMTMuNTY3IEw5MS43MTIsMTEzLjU2NyBaIE05MS44MjksNjIuNjQ3IEw5MS44MjksMTEzLjI0OCBMMTE4LjkzNSw5Ny41OTggTDEyNS4zODIsNzYuMDE1IEMxMjUuODI3LDc0LjUyNSAxMjYuNjY0LDczLjA4MSAxMjcuNzM5LDcxLjk1IEMxMjguOTE5LDcwLjcwOCAxMzAuMjU2LDY5Ljk5NiAxMzEuNDA4LDY5Ljk5NiBDMTMyLjM3Nyw2OS45OTYgMTMzLjEzOSw3MC40OTcgMTMzLjU1NCw3MS40MDcgTDEzOS45NjEsODUuNDU4IEwxNjcuMTEzLDY5Ljc4MiBMMTY3LjExMywxOS4xODEgTDkxLjgyOSw2Mi42NDcgTDkxLjgyOSw2Mi42NDcgWiIgaWQ9IkZpbGwtMTQiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTY4LjU0MywxOS4yMTMgTDE2OC41NDMsNzAuMDgzIEwxNDEuMjIxLDg1Ljg1NyBMMTM0Ljc2MSw3MS42ODkgQzEzMy44NTEsNjkuNjk0IDEzMS4zMzMsNjkuOTUxIDEyOS4xMzcsNzIuMjYzIEMxMjguMDgyLDczLjM3NCAxMjcuMjQ0LDc0LjgxOSAxMjYuODA3LDc2LjI4MiBMMTIwLjM0Niw5Ny45MDkgTDkzLjAyNSwxMTMuNjgzIEw5My4wMjUsNjIuODEzIEwxNjguNTQzLDE5LjIxMyIgaWQ9IkZpbGwtMTUiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTMuMDI1LDExMy44IEM5My4wMDUsMTEzLjggOTIuOTg0LDExMy43OTUgOTIuOTY2LDExMy43ODUgQzkyLjkzMSwxMTMuNzY0IDkyLjkwOCwxMTMuNzI1IDkyLjkwOCwxMTMuNjg0IEw5Mi45MDgsNjIuODEzIEM5Mi45MDgsNjIuNzcxIDkyLjkzMSw2Mi43MzMgOTIuOTY2LDYyLjcxMiBMMTY4LjQ4NCwxOS4xMTIgQzE2OC41MiwxOS4wOSAxNjguNTY1LDE5LjA5IDE2OC42MDEsMTkuMTEyIEMxNjguNjM3LDE5LjEzMiAxNjguNjYsMTkuMTcxIDE2OC42NiwxOS4yMTIgTDE2OC42Niw3MC4wODMgQzE2OC42Niw3MC4xMjUgMTY4LjYzNyw3MC4xNjQgMTY4LjYwMSw3MC4xODQgTDE0MS4yOCw4NS45NTggQzE0MS4yNTEsODUuOTc1IDE0MS4yMTcsODUuOTc5IDE0MS4xODYsODUuOTY4IEMxNDEuMTU0LDg1Ljk1OCAxNDEuMTI5LDg1LjkzNiAxNDEuMTE1LDg1LjkwNiBMMTM0LjY1NSw3MS43MzggQzEzNC4yOCw3MC45MTUgMTMzLjU5Myw3MC40NjMgMTMyLjcyLDcwLjQ2MyBDMTMxLjYzMiw3MC40NjMgMTMwLjM1Nyw3MS4xNDggMTI5LjIyMSw3Mi4zNDQgQzEyOC4xODYsNzMuNDMzIDEyNy4zNDcsNzQuODgxIDEyNi45MTksNzYuMzE1IEwxMjAuNDU4LDk3Ljk0MyBDMTIwLjQ1LDk3Ljk3MiAxMjAuNDMxLDk3Ljk5NiAxMjAuNDA1LDk4LjAxIEw5My4wODMsMTEzLjc4NSBDOTMuMDY1LDExMy43OTUgOTMuMDQ1LDExMy44IDkzLjAyNSwxMTMuOCBMOTMuMDI1LDExMy44IFogTTkzLjE0Miw2Mi44ODEgTDkzLjE0MiwxMTMuNDgxIEwxMjAuMjQ4LDk3LjgzMiBMMTI2LjY5NSw3Ni4yNDggQzEyNy4xNCw3NC43NTggMTI3Ljk3Nyw3My4zMTUgMTI5LjA1Miw3Mi4xODMgQzEzMC4yMzEsNzAuOTQyIDEzMS41NjgsNzAuMjI5IDEzMi43Miw3MC4yMjkgQzEzMy42ODksNzAuMjI5IDEzNC40NTIsNzAuNzMxIDEzNC44NjcsNzEuNjQxIEwxNDEuMjc0LDg1LjY5MiBMMTY4LjQyNiw3MC4wMTYgTDE2OC40MjYsMTkuNDE1IEw5My4xNDIsNjIuODgxIEw5My4xNDIsNjIuODgxIFoiIGlkPSJGaWxsLTE2IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS44LDcwLjA4MyBMMTQyLjQ3OCw4NS44NTcgTDEzNi4wMTgsNzEuNjg5IEMxMzUuMTA4LDY5LjY5NCAxMzIuNTksNjkuOTUxIDEzMC4zOTMsNzIuMjYzIEMxMjkuMzM5LDczLjM3NCAxMjguNSw3NC44MTkgMTI4LjA2NCw3Ni4yODIgTDEyMS42MDMsOTcuOTA5IEw5NC4yODIsMTEzLjY4MyBMOTQuMjgyLDYyLjgxMyBMMTY5LjgsMTkuMjEzIEwxNjkuOCw3MC4wODMgWiIgaWQ9IkZpbGwtMTciIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNOTQuMjgyLDExMy45MTcgQzk0LjI0MSwxMTMuOTE3IDk0LjIwMSwxMTMuOTA3IDk0LjE2NSwxMTMuODg2IEM5NC4wOTMsMTEzLjg0NSA5NC4wNDgsMTEzLjc2NyA5NC4wNDgsMTEzLjY4NCBMOTQuMDQ4LDYyLjgxMyBDOTQuMDQ4LDYyLjczIDk0LjA5Myw2Mi42NTIgOTQuMTY1LDYyLjYxMSBMMTY5LjY4MywxOS4wMSBDMTY5Ljc1NSwxOC45NjkgMTY5Ljg0NCwxOC45NjkgMTY5LjkxNywxOS4wMSBDMTY5Ljk4OSwxOS4wNTIgMTcwLjAzMywxOS4xMjkgMTcwLjAzMywxOS4yMTIgTDE3MC4wMzMsNzAuMDgzIEMxNzAuMDMzLDcwLjE2NiAxNjkuOTg5LDcwLjI0NCAxNjkuOTE3LDcwLjI4NSBMMTQyLjU5NSw4Ni4wNiBDMTQyLjUzOCw4Ni4wOTIgMTQyLjQ2OSw4Ni4xIDE0Mi40MDcsODYuMDggQzE0Mi4zNDQsODYuMDYgMTQyLjI5Myw4Ni4wMTQgMTQyLjI2Niw4NS45NTQgTDEzNS44MDUsNzEuNzg2IEMxMzUuNDQ1LDcwLjk5NyAxMzQuODEzLDcwLjU4IDEzMy45NzcsNzAuNTggQzEzMi45MjEsNzAuNTggMTMxLjY3Niw3MS4yNTIgMTMwLjU2Miw3Mi40MjQgQzEyOS41NCw3My41MDEgMTI4LjcxMSw3NC45MzEgMTI4LjI4Nyw3Ni4zNDggTDEyMS44MjcsOTcuOTc2IEMxMjEuODEsOTguMDM0IDEyMS43NzEsOTguMDgyIDEyMS43Miw5OC4xMTIgTDk0LjM5OCwxMTMuODg2IEM5NC4zNjIsMTEzLjkwNyA5NC4zMjIsMTEzLjkxNyA5NC4yODIsMTEzLjkxNyBMOTQuMjgyLDExMy45MTcgWiBNOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDExMy4yNzkgTDEyMS40MDYsOTcuNzU0IEwxMjcuODQsNzYuMjE1IEMxMjguMjksNzQuNzA4IDEyOS4xMzcsNzMuMjQ3IDEzMC4yMjQsNzIuMTAzIEMxMzEuNDI1LDcwLjgzOCAxMzIuNzkzLDcwLjExMiAxMzMuOTc3LDcwLjExMiBDMTM0Ljk5NSw3MC4xMTIgMTM1Ljc5NSw3MC42MzggMTM2LjIzLDcxLjU5MiBMMTQyLjU4NCw4NS41MjYgTDE2OS41NjYsNjkuOTQ4IEwxNjkuNTY2LDE5LjYxNyBMOTQuNTE1LDYyLjk0OCBMOTQuNTE1LDYyLjk0OCBaIiBpZD0iRmlsbC0xOCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMDkuODk0LDkyLjk0MyBMMTA5Ljg5NCw5Mi45NDMgQzEwOC4xMiw5Mi45NDMgMTA2LjY1Myw5Mi4yMTggMTA1LjY1LDkwLjgyMyBDMTA1LjU4Myw5MC43MzEgMTA1LjU5Myw5MC42MSAxMDUuNjczLDkwLjUyOSBDMTA1Ljc1Myw5MC40NDggMTA1Ljg4LDkwLjQ0IDEwNS45NzQsOTAuNTA2IEMxMDYuNzU0LDkxLjA1MyAxMDcuNjc5LDkxLjMzMyAxMDguNzI0LDkxLjMzMyBDMTEwLjA0Nyw5MS4zMzMgMTExLjQ3OCw5MC44OTQgMTEyLjk4LDkwLjAyNyBDMTE4LjI5MSw4Ni45NiAxMjIuNjExLDc5LjUwOSAxMjIuNjExLDczLjQxNiBDMTIyLjYxMSw3MS40ODkgMTIyLjE2OSw2OS44NTYgMTIxLjMzMyw2OC42OTIgQzEyMS4yNjYsNjguNiAxMjEuMjc2LDY4LjQ3MyAxMjEuMzU2LDY4LjM5MiBDMTIxLjQzNiw2OC4zMTEgMTIxLjU2Myw2OC4yOTkgMTIxLjY1Niw2OC4zNjUgQzEyMy4zMjcsNjkuNTM3IDEyNC4yNDcsNzEuNzQ2IDEyNC4yNDcsNzQuNTg0IEMxMjQuMjQ3LDgwLjgyNiAxMTkuODIxLDg4LjQ0NyAxMTQuMzgyLDkxLjU4NyBDMTEyLjgwOCw5Mi40OTUgMTExLjI5OCw5Mi45NDMgMTA5Ljg5NCw5Mi45NDMgTDEwOS44OTQsOTIuOTQzIFogTTEwNi45MjUsOTEuNDAxIEMxMDcuNzM4LDkyLjA1MiAxMDguNzQ1LDkyLjI3OCAxMDkuODkzLDkyLjI3OCBMMTA5Ljg5NCw5Mi4yNzggQzExMS4yMTUsOTIuMjc4IDExMi42NDcsOTEuOTUxIDExNC4xNDgsOTEuMDg0IEMxMTkuNDU5LDg4LjAxNyAxMjMuNzgsODAuNjIxIDEyMy43OCw3NC41MjggQzEyMy43OCw3Mi41NDkgMTIzLjMxNyw3MC45MjkgMTIyLjQ1NCw2OS43NjcgQzEyMi44NjUsNzAuODAyIDEyMy4wNzksNzIuMDQyIDEyMy4wNzksNzMuNDAyIEMxMjMuMDc5LDc5LjY0NSAxMTguNjUzLDg3LjI4NSAxMTMuMjE0LDkwLjQyNSBDMTExLjY0LDkxLjMzNCAxMTAuMTMsOTEuNzQyIDEwOC43MjQsOTEuNzQyIEMxMDguMDgzLDkxLjc0MiAxMDcuNDgxLDkxLjU5MyAxMDYuOTI1LDkxLjQwMSBMMTA2LjkyNSw5MS40MDEgWiIgaWQ9IkZpbGwtMTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjA5Nyw5MC4yMyBDMTE4LjQ4MSw4Ny4xMjIgMTIyLjg0NSw3OS41OTQgMTIyLjg0NSw3My40MTYgQzEyMi44NDUsNzEuMzY1IDEyMi4zNjIsNjkuNzI0IDEyMS41MjIsNjguNTU2IEMxMTkuNzM4LDY3LjMwNCAxMTcuMTQ4LDY3LjM2MiAxMTQuMjY1LDY5LjAyNiBDMTA4Ljg4MSw3Mi4xMzQgMTA0LjUxNyw3OS42NjIgMTA0LjUxNyw4NS44NCBDMTA0LjUxNyw4Ny44OTEgMTA1LDg5LjUzMiAxMDUuODQsOTAuNyBDMTA3LjYyNCw5MS45NTIgMTEwLjIxNCw5MS44OTQgMTEzLjA5Nyw5MC4yMyIgaWQ9IkZpbGwtMjAiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTA4LjcyNCw5MS42MTQgTDEwOC43MjQsOTEuNjE0IEMxMDcuNTgyLDkxLjYxNCAxMDYuNTY2LDkxLjQwMSAxMDUuNzA1LDkwLjc5NyBDMTA1LjY4NCw5MC43ODMgMTA1LjY2NSw5MC44MTEgMTA1LjY1LDkwLjc5IEMxMDQuNzU2LDg5LjU0NiAxMDQuMjgzLDg3Ljg0MiAxMDQuMjgzLDg1LjgxNyBDMTA0LjI4Myw3OS41NzUgMTA4LjcwOSw3MS45NTMgMTE0LjE0OCw2OC44MTIgQzExNS43MjIsNjcuOTA0IDExNy4yMzIsNjcuNDQ5IDExOC42MzgsNjcuNDQ5IEMxMTkuNzgsNjcuNDQ5IDEyMC43OTYsNjcuNzU4IDEyMS42NTYsNjguMzYyIEMxMjEuNjc4LDY4LjM3NyAxMjEuNjk3LDY4LjM5NyAxMjEuNzEyLDY4LjQxOCBDMTIyLjYwNiw2OS42NjIgMTIzLjA3OSw3MS4zOSAxMjMuMDc5LDczLjQxNSBDMTIzLjA3OSw3OS42NTggMTE4LjY1Myw4Ny4xOTggMTEzLjIxNCw5MC4zMzggQzExMS42NCw5MS4yNDcgMTEwLjEzLDkxLjYxNCAxMDguNzI0LDkxLjYxNCBMMTA4LjcyNCw5MS42MTQgWiBNMTA2LjAwNiw5MC41MDUgQzEwNi43OCw5MS4wMzcgMTA3LjY5NCw5MS4yODEgMTA4LjcyNCw5MS4yODEgQzExMC4wNDcsOTEuMjgxIDExMS40NzgsOTAuODY4IDExMi45OCw5MC4wMDEgQzExOC4yOTEsODYuOTM1IDEyMi42MTEsNzkuNDk2IDEyMi42MTEsNzMuNDAzIEMxMjIuNjExLDcxLjQ5NCAxMjIuMTc3LDY5Ljg4IDEyMS4zNTYsNjguNzE4IEMxMjAuNTgyLDY4LjE4NSAxMTkuNjY4LDY3LjkxOSAxMTguNjM4LDY3LjkxOSBDMTE3LjMxNSw2Ny45MTkgMTE1Ljg4Myw2OC4zNiAxMTQuMzgyLDY5LjIyNyBDMTA5LjA3MSw3Mi4yOTMgMTA0Ljc1MSw3OS43MzMgMTA0Ljc1MSw4NS44MjYgQzEwNC43NTEsODcuNzM1IDEwNS4xODUsODkuMzQzIDEwNi4wMDYsOTAuNTA1IEwxMDYuMDA2LDkwLjUwNSBaIiBpZD0iRmlsbC0yMSIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNDkuMzE4LDcuMjYyIEwxMzkuMzM0LDE2LjE0IEwxNTUuMjI3LDI3LjE3MSBMMTYwLjgxNiwyMS4wNTkgTDE0OS4zMTgsNy4yNjIiIGlkPSJGaWxsLTIyIiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE2OS42NzYsMTMuODQgTDE1OS45MjgsMTkuNDY3IEMxNTYuMjg2LDIxLjU3IDE1MC40LDIxLjU4IDE0Ni43ODEsMTkuNDkxIEMxNDMuMTYxLDE3LjQwMiAxNDMuMTgsMTQuMDAzIDE0Ni44MjIsMTEuOSBMMTU2LjMxNyw2LjI5MiBMMTQ5LjU4OCwyLjQwNyBMNjcuNzUyLDQ5LjQ3OCBMMTEzLjY3NSw3NS45OTIgTDExNi43NTYsNzQuMjEzIEMxMTcuMzg3LDczLjg0OCAxMTcuNjI1LDczLjMxNSAxMTcuMzc0LDcyLjgyMyBDMTE1LjAxNyw2OC4xOTEgMTE0Ljc4MSw2My4yNzcgMTE2LjY5MSw1OC41NjEgQzEyMi4zMjksNDQuNjQxIDE0MS4yLDMzLjc0NiAxNjUuMzA5LDMwLjQ5MSBDMTczLjQ3OCwyOS4zODggMTgxLjk4OSwyOS41MjQgMTkwLjAxMywzMC44ODUgQzE5MC44NjUsMzEuMDMgMTkxLjc4OSwzMC44OTMgMTkyLjQyLDMwLjUyOCBMMTk1LjUwMSwyOC43NSBMMTY5LjY3NiwxMy44NCIgaWQ9IkZpbGwtMjMiIGZpbGw9IiNGQUZBRkEiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3Ni40NTkgQzExMy41OTQsNzYuNDU5IDExMy41MTQsNzYuNDM4IDExMy40NDIsNzYuMzk3IEw2Ny41MTgsNDkuODgyIEM2Ny4zNzQsNDkuNzk5IDY3LjI4NCw0OS42NDUgNjcuMjg1LDQ5LjQ3OCBDNjcuMjg1LDQ5LjMxMSA2Ny4zNzQsNDkuMTU3IDY3LjUxOSw0OS4wNzMgTDE0OS4zNTUsMi4wMDIgQzE0OS40OTksMS45MTkgMTQ5LjY3NywxLjkxOSAxNDkuODIxLDIuMDAyIEwxNTYuNTUsNS44ODcgQzE1Ni43NzQsNi4wMTcgMTU2Ljg1LDYuMzAyIDE1Ni43MjIsNi41MjYgQzE1Ni41OTIsNi43NDkgMTU2LjMwNyw2LjgyNiAxNTYuMDgzLDYuNjk2IEwxNDkuNTg3LDIuOTQ2IEw2OC42ODcsNDkuNDc5IEwxMTMuNjc1LDc1LjQ1MiBMMTE2LjUyMyw3My44MDggQzExNi43MTUsNzMuNjk3IDExNy4xNDMsNzMuMzk5IDExNi45NTgsNzMuMDM1IEMxMTQuNTQyLDY4LjI4NyAxMTQuMyw2My4yMjEgMTE2LjI1OCw1OC4zODUgQzExOS4wNjQsNTEuNDU4IDEyNS4xNDMsNDUuMTQzIDEzMy44NCw0MC4xMjIgQzE0Mi40OTcsMzUuMTI0IDE1My4zNTgsMzEuNjMzIDE2NS4yNDcsMzAuMDI4IEMxNzMuNDQ1LDI4LjkyMSAxODIuMDM3LDI5LjA1OCAxOTAuMDkxLDMwLjQyNSBDMTkwLjgzLDMwLjU1IDE5MS42NTIsMzAuNDMyIDE5Mi4xODYsMzAuMTI0IEwxOTQuNTY3LDI4Ljc1IEwxNjkuNDQyLDE0LjI0NCBDMTY5LjIxOSwxNC4xMTUgMTY5LjE0MiwxMy44MjkgMTY5LjI3MSwxMy42MDYgQzE2OS40LDEzLjM4MiAxNjkuNjg1LDEzLjMwNiAxNjkuOTA5LDEzLjQzNSBMMTk1LjczNCwyOC4zNDUgQzE5NS44NzksMjguNDI4IDE5NS45NjgsMjguNTgzIDE5NS45NjgsMjguNzUgQzE5NS45NjgsMjguOTE2IDE5NS44NzksMjkuMDcxIDE5NS43MzQsMjkuMTU0IEwxOTIuNjUzLDMwLjkzMyBDMTkxLjkzMiwzMS4zNSAxOTAuODksMzEuNTA4IDE4OS45MzUsMzEuMzQ2IEMxODEuOTcyLDI5Ljk5NSAxNzMuNDc4LDI5Ljg2IDE2NS4zNzIsMzAuOTU0IEMxNTMuNjAyLDMyLjU0MyAxNDIuODYsMzUuOTkzIDEzNC4zMDcsNDAuOTMxIEMxMjUuNzkzLDQ1Ljg0NyAxMTkuODUxLDUyLjAwNCAxMTcuMTI0LDU4LjczNiBDMTE1LjI3LDYzLjMxNCAxMTUuNTAxLDY4LjExMiAxMTcuNzksNzIuNjExIEMxMTguMTYsNzMuMzM2IDExNy44NDUsNzQuMTI0IDExNi45OSw3NC42MTcgTDExMy45MDksNzYuMzk3IEMxMTMuODM2LDc2LjQzOCAxMTMuNzU2LDc2LjQ1OSAxMTMuNjc1LDc2LjQ1OSIgaWQ9IkZpbGwtMjQiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUzLjMxNiwyMS4yNzkgQzE1MC45MDMsMjEuMjc5IDE0OC40OTUsMjAuNzUxIDE0Ni42NjQsMTkuNjkzIEMxNDQuODQ2LDE4LjY0NCAxNDMuODQ0LDE3LjIzMiAxNDMuODQ0LDE1LjcxOCBDMTQzLjg0NCwxNC4xOTEgMTQ0Ljg2LDEyLjc2MyAxNDYuNzA1LDExLjY5OCBMMTU2LjE5OCw2LjA5MSBDMTU2LjMwOSw2LjAyNSAxNTYuNDUyLDYuMDYyIDE1Ni41MTgsNi4xNzMgQzE1Ni41ODMsNi4yODQgMTU2LjU0Nyw2LjQyNyAxNTYuNDM2LDYuNDkzIEwxNDYuOTQsMTIuMTAyIEMxNDUuMjQ0LDEzLjA4MSAxNDQuMzEyLDE0LjM2NSAxNDQuMzEyLDE1LjcxOCBDMTQ0LjMxMiwxNy4wNTggMTQ1LjIzLDE4LjMyNiAxNDYuODk3LDE5LjI4OSBDMTUwLjQ0NiwyMS4zMzggMTU2LjI0LDIxLjMyNyAxNTkuODExLDE5LjI2NSBMMTY5LjU1OSwxMy42MzcgQzE2OS42NywxMy41NzMgMTY5LjgxMywxMy42MTEgMTY5Ljg3OCwxMy43MjMgQzE2OS45NDMsMTMuODM0IDE2OS45MDQsMTMuOTc3IDE2OS43OTMsMTQuMDQyIEwxNjAuMDQ1LDE5LjY3IEMxNTguMTg3LDIwLjc0MiAxNTUuNzQ5LDIxLjI3OSAxNTMuMzE2LDIxLjI3OSIgaWQ9IkZpbGwtMjUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEzLjY3NSw3NS45OTIgTDY3Ljc2Miw0OS40ODQiIGlkPSJGaWxsLTI2IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMy42NzUsNzYuMzQyIEMxMTMuNjE1LDc2LjM0MiAxMTMuNTU1LDc2LjMyNyAxMTMuNSw3Ni4yOTUgTDY3LjU4Nyw0OS43ODcgQzY3LjQxOSw0OS42OSA2Ny4zNjIsNDkuNDc2IDY3LjQ1OSw0OS4zMDkgQzY3LjU1Niw0OS4xNDEgNjcuNzcsNDkuMDgzIDY3LjkzNyw0OS4xOCBMMTEzLjg1LDc1LjY4OCBDMTE0LjAxOCw3NS43ODUgMTE0LjA3NSw3NiAxMTMuOTc4LDc2LjE2NyBDMTEzLjkxNCw3Ni4yNzkgMTEzLjc5Niw3Ni4zNDIgMTEzLjY3NSw3Ni4zNDIiIGlkPSJGaWxsLTI3IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY3Ljc2Miw0OS40ODQgTDY3Ljc2MiwxMDMuNDg1IEM2Ny43NjIsMTA0LjU3NSA2OC41MzIsMTA1LjkwMyA2OS40ODIsMTA2LjQ1MiBMMTExLjk1NSwxMzAuOTczIEMxMTIuOTA1LDEzMS41MjIgMTEzLjY3NSwxMzEuMDgzIDExMy42NzUsMTI5Ljk5MyBMMTEzLjY3NSw3NS45OTIiIGlkPSJGaWxsLTI4IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTExMi43MjcsMTMxLjU2MSBDMTEyLjQzLDEzMS41NjEgMTEyLjEwNywxMzEuNDY2IDExMS43OCwxMzEuMjc2IEw2OS4zMDcsMTA2Ljc1NSBDNjguMjQ0LDEwNi4xNDIgNjcuNDEyLDEwNC43MDUgNjcuNDEyLDEwMy40ODUgTDY3LjQxMiw0OS40ODQgQzY3LjQxMiw0OS4yOSA2Ny41NjksNDkuMTM0IDY3Ljc2Miw0OS4xMzQgQzY3Ljk1Niw0OS4xMzQgNjguMTEzLDQ5LjI5IDY4LjExMyw0OS40ODQgTDY4LjExMywxMDMuNDg1IEM2OC4xMTMsMTA0LjQ0NSA2OC44MiwxMDUuNjY1IDY5LjY1NywxMDYuMTQ4IEwxMTIuMTMsMTMwLjY3IEMxMTIuNDc0LDEzMC44NjggMTEyLjc5MSwxMzAuOTEzIDExMywxMzAuNzkyIEMxMTMuMjA2LDEzMC42NzMgMTEzLjMyNSwxMzAuMzgxIDExMy4zMjUsMTI5Ljk5MyBMMTEzLjMyNSw3NS45OTIgQzExMy4zMjUsNzUuNzk4IDExMy40ODIsNzUuNjQxIDExMy42NzUsNzUuNjQxIEMxMTMuODY5LDc1LjY0MSAxMTQuMDI1LDc1Ljc5OCAxMTQuMDI1LDc1Ljk5MiBMMTE0LjAyNSwxMjkuOTkzIEMxMTQuMDI1LDEzMC42NDggMTEzLjc4NiwxMzEuMTQ3IDExMy4zNSwxMzEuMzk5IEMxMTMuMTYyLDEzMS41MDcgMTEyLjk1MiwxMzEuNTYxIDExMi43MjcsMTMxLjU2MSIgaWQ9IkZpbGwtMjkiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTEyLjg2LDQwLjUxMiBDMTEyLjg2LDQwLjUxMiAxMTIuODYsNDAuNTEyIDExMi44NTksNDAuNTEyIEMxMTAuNTQxLDQwLjUxMiAxMDguMzYsMzkuOTkgMTA2LjcxNywzOS4wNDEgQzEwNS4wMTIsMzguMDU3IDEwNC4wNzQsMzYuNzI2IDEwNC4wNzQsMzUuMjkyIEMxMDQuMDc0LDMzLjg0NyAxMDUuMDI2LDMyLjUwMSAxMDYuNzU0LDMxLjUwNCBMMTE4Ljc5NSwyNC41NTEgQzEyMC40NjMsMjMuNTg5IDEyMi42NjksMjMuMDU4IDEyNS4wMDcsMjMuMDU4IEMxMjcuMzI1LDIzLjA1OCAxMjkuNTA2LDIzLjU4MSAxMzEuMTUsMjQuNTMgQzEzMi44NTQsMjUuNTE0IDEzMy43OTMsMjYuODQ1IDEzMy43OTMsMjguMjc4IEMxMzMuNzkzLDI5LjcyNCAxMzIuODQxLDMxLjA2OSAxMzEuMTEzLDMyLjA2NyBMMTE5LjA3MSwzOS4wMTkgQzExNy40MDMsMzkuOTgyIDExNS4xOTcsNDAuNTEyIDExMi44Niw0MC41MTIgTDExMi44Niw0MC41MTIgWiBNMTI1LjAwNywyMy43NTkgQzEyMi43OSwyMy43NTkgMTIwLjcwOSwyNC4yNTYgMTE5LjE0NiwyNS4xNTggTDEwNy4xMDQsMzIuMTEgQzEwNS42MDIsMzIuOTc4IDEwNC43NzQsMzQuMTA4IDEwNC43NzQsMzUuMjkyIEMxMDQuNzc0LDM2LjQ2NSAxMDUuNTg5LDM3LjU4MSAxMDcuMDY3LDM4LjQzNCBDMTA4LjYwNSwzOS4zMjMgMTEwLjY2MywzOS44MTIgMTEyLjg1OSwzOS44MTIgTDExMi44NiwzOS44MTIgQzExNS4wNzYsMzkuODEyIDExNy4xNTgsMzkuMzE1IDExOC43MjEsMzguNDEzIEwxMzAuNzYyLDMxLjQ2IEMxMzIuMjY0LDMwLjU5MyAxMzMuMDkyLDI5LjQ2MyAxMzMuMDkyLDI4LjI3OCBDMTMzLjA5MiwyNy4xMDYgMTMyLjI3OCwyNS45OSAxMzAuOCwyNS4xMzYgQzEyOS4yNjEsMjQuMjQ4IDEyNy4yMDQsMjMuNzU5IDEyNS4wMDcsMjMuNzU5IEwxMjUuMDA3LDIzLjc1OSBaIiBpZD0iRmlsbC0zMCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNjUuNjMsMTYuMjE5IEwxNTkuODk2LDE5LjUzIEMxNTYuNzI5LDIxLjM1OCAxNTEuNjEsMjEuMzY3IDE0OC40NjMsMTkuNTUgQzE0NS4zMTYsMTcuNzMzIDE0NS4zMzIsMTQuNzc4IDE0OC40OTksMTIuOTQ5IEwxNTQuMjMzLDkuNjM5IEwxNjUuNjMsMTYuMjE5IiBpZD0iRmlsbC0zMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xNTQuMjMzLDEwLjQ0OCBMMTY0LjIyOCwxNi4yMTkgTDE1OS41NDYsMTguOTIzIEMxNTguMTEyLDE5Ljc1IDE1Ni4xOTQsMjAuMjA2IDE1NC4xNDcsMjAuMjA2IEMxNTIuMTE4LDIwLjIwNiAxNTAuMjI0LDE5Ljc1NyAxNDguODE0LDE4Ljk0MyBDMTQ3LjUyNCwxOC4xOTkgMTQ2LjgxNCwxNy4yNDkgMTQ2LjgxNCwxNi4yNjkgQzE0Ni44MTQsMTUuMjc4IDE0Ny41MzcsMTQuMzE0IDE0OC44NSwxMy41NTYgTDE1NC4yMzMsMTAuNDQ4IE0xNTQuMjMzLDkuNjM5IEwxNDguNDk5LDEyLjk0OSBDMTQ1LjMzMiwxNC43NzggMTQ1LjMxNiwxNy43MzMgMTQ4LjQ2MywxOS41NSBDMTUwLjAzMSwyMC40NTUgMTUyLjA4NiwyMC45MDcgMTU0LjE0NywyMC45MDcgQzE1Ni4yMjQsMjAuOTA3IDE1OC4zMDYsMjAuNDQ3IDE1OS44OTYsMTkuNTMgTDE2NS42MywxNi4yMTkgTDE1NC4yMzMsOS42MzkiIGlkPSJGaWxsLTMyIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NS40NDUsNzIuNjY3IEwxNDUuNDQ1LDcyLjY2NyBDMTQzLjY3Miw3Mi42NjcgMTQyLjIwNCw3MS44MTcgMTQxLjIwMiw3MC40MjIgQzE0MS4xMzUsNzAuMzMgMTQxLjE0NSw3MC4xNDcgMTQxLjIyNSw3MC4wNjYgQzE0MS4zMDUsNjkuOTg1IDE0MS40MzIsNjkuOTQ2IDE0MS41MjUsNzAuMDExIEMxNDIuMzA2LDcwLjU1OSAxNDMuMjMxLDcwLjgyMyAxNDQuMjc2LDcwLjgyMiBDMTQ1LjU5OCw3MC44MjIgMTQ3LjAzLDcwLjM3NiAxNDguNTMyLDY5LjUwOSBDMTUzLjg0Miw2Ni40NDMgMTU4LjE2Myw1OC45ODcgMTU4LjE2Myw1Mi44OTQgQzE1OC4xNjMsNTAuOTY3IDE1Ny43MjEsNDkuMzMyIDE1Ni44ODQsNDguMTY4IEMxNTYuODE4LDQ4LjA3NiAxNTYuODI4LDQ3Ljk0OCAxNTYuOTA4LDQ3Ljg2NyBDMTU2Ljk4OCw0Ny43ODYgMTU3LjExNCw0Ny43NzQgMTU3LjIwOCw0Ny44NCBDMTU4Ljg3OCw0OS4wMTIgMTU5Ljc5OCw1MS4yMiAxNTkuNzk4LDU0LjA1OSBDMTU5Ljc5OCw2MC4zMDEgMTU1LjM3Myw2OC4wNDYgMTQ5LjkzMyw3MS4xODYgQzE0OC4zNiw3Mi4wOTQgMTQ2Ljg1LDcyLjY2NyAxNDUuNDQ1LDcyLjY2NyBMMTQ1LjQ0NSw3Mi42NjcgWiBNMTQyLjQ3Niw3MSBDMTQzLjI5LDcxLjY1MSAxNDQuMjk2LDcyLjAwMiAxNDUuNDQ1LDcyLjAwMiBDMTQ2Ljc2Nyw3Mi4wMDIgMTQ4LjE5OCw3MS41NSAxNDkuNyw3MC42ODIgQzE1NS4wMSw2Ny42MTcgMTU5LjMzMSw2MC4xNTkgMTU5LjMzMSw1NC4wNjUgQzE1OS4zMzEsNTIuMDg1IDE1OC44NjgsNTAuNDM1IDE1OC4wMDYsNDkuMjcyIEMxNTguNDE3LDUwLjMwNyAxNTguNjMsNTEuNTMyIDE1OC42Myw1Mi44OTIgQzE1OC42Myw1OS4xMzQgMTU0LjIwNSw2Ni43NjcgMTQ4Ljc2NSw2OS45MDcgQzE0Ny4xOTIsNzAuODE2IDE0NS42ODEsNzEuMjgzIDE0NC4yNzYsNzEuMjgzIEMxNDMuNjM0LDcxLjI4MyAxNDMuMDMzLDcxLjE5MiAxNDIuNDc2LDcxIEwxNDIuNDc2LDcxIFoiIGlkPSJGaWxsLTMzIiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0OC42NDgsNjkuNzA0IEMxNTQuMDMyLDY2LjU5NiAxNTguMzk2LDU5LjA2OCAxNTguMzk2LDUyLjg5MSBDMTU4LjM5Niw1MC44MzkgMTU3LjkxMyw0OS4xOTggMTU3LjA3NCw0OC4wMyBDMTU1LjI4OSw0Ni43NzggMTUyLjY5OSw0Ni44MzYgMTQ5LjgxNiw0OC41MDEgQzE0NC40MzMsNTEuNjA5IDE0MC4wNjgsNTkuMTM3IDE0MC4wNjgsNjUuMzE0IEMxNDAuMDY4LDY3LjM2NSAxNDAuNTUyLDY5LjAwNiAxNDEuMzkxLDcwLjE3NCBDMTQzLjE3Niw3MS40MjcgMTQ1Ljc2NSw3MS4zNjkgMTQ4LjY0OCw2OS43MDQiIGlkPSJGaWxsLTM0IiBmaWxsPSIjRkFGQUZBIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTE0NC4yNzYsNzEuMjc2IEwxNDQuMjc2LDcxLjI3NiBDMTQzLjEzMyw3MS4yNzYgMTQyLjExOCw3MC45NjkgMTQxLjI1Nyw3MC4zNjUgQzE0MS4yMzYsNzAuMzUxIDE0MS4yMTcsNzAuMzMyIDE0MS4yMDIsNzAuMzExIEMxNDAuMzA3LDY5LjA2NyAxMzkuODM1LDY3LjMzOSAxMzkuODM1LDY1LjMxNCBDMTM5LjgzNSw1OS4wNzMgMTQ0LjI2LDUxLjQzOSAxNDkuNyw0OC4yOTggQzE1MS4yNzMsNDcuMzkgMTUyLjc4NCw0Ni45MjkgMTU0LjE4OSw0Ni45MjkgQzE1NS4zMzIsNDYuOTI5IDE1Ni4zNDcsNDcuMjM2IDE1Ny4yMDgsNDcuODM5IEMxNTcuMjI5LDQ3Ljg1NCAxNTcuMjQ4LDQ3Ljg3MyAxNTcuMjYzLDQ3Ljg5NCBDMTU4LjE1Nyw0OS4xMzggMTU4LjYzLDUwLjg2NSAxNTguNjMsNTIuODkxIEMxNTguNjMsNTkuMTMyIDE1NC4yMDUsNjYuNzY2IDE0OC43NjUsNjkuOTA3IEMxNDcuMTkyLDcwLjgxNSAxNDUuNjgxLDcxLjI3NiAxNDQuMjc2LDcxLjI3NiBMMTQ0LjI3Niw3MS4yNzYgWiBNMTQxLjU1OCw3MC4xMDQgQzE0Mi4zMzEsNzAuNjM3IDE0My4yNDUsNzEuMDA1IDE0NC4yNzYsNzEuMDA1IEMxNDUuNTk4LDcxLjAwNSAxNDcuMDMsNzAuNDY3IDE0OC41MzIsNjkuNiBDMTUzLjg0Miw2Ni41MzQgMTU4LjE2Myw1OS4wMzMgMTU4LjE2Myw1Mi45MzkgQzE1OC4xNjMsNTEuMDMxIDE1Ny43MjksNDkuMzg1IDE1Ni45MDcsNDguMjIzIEMxNTYuMTMzLDQ3LjY5MSAxNTUuMjE5LDQ3LjQwOSAxNTQuMTg5LDQ3LjQwOSBDMTUyLjg2Nyw0Ny40MDkgMTUxLjQzNSw0Ny44NDIgMTQ5LjkzMyw0OC43MDkgQzE0NC42MjMsNTEuNzc1IDE0MC4zMDIsNTkuMjczIDE0MC4zMDIsNjUuMzY2IEMxNDAuMzAyLDY3LjI3NiAxNDAuNzM2LDY4Ljk0MiAxNDEuNTU4LDcwLjEwNCBMMTQxLjU1OCw3MC4xMDQgWiIgaWQ9IkZpbGwtMzUiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTUwLjcyLDY1LjM2MSBMMTUwLjM1Nyw2NS4wNjYgQzE1MS4xNDcsNjQuMDkyIDE1MS44NjksNjMuMDQgMTUyLjUwNSw2MS45MzggQzE1My4zMTMsNjAuNTM5IDE1My45NzgsNTkuMDY3IDE1NC40ODIsNTcuNTYzIEwxNTQuOTI1LDU3LjcxMiBDMTU0LjQxMiw1OS4yNDUgMTUzLjczMyw2MC43NDUgMTUyLjkxLDYyLjE3MiBDMTUyLjI2Miw2My4yOTUgMTUxLjUyNSw2NC4zNjggMTUwLjcyLDY1LjM2MSIgaWQ9IkZpbGwtMzYiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE1LjkxNyw4NC41MTQgTDExNS41NTQsODQuMjIgQzExNi4zNDQsODMuMjQ1IDExNy4wNjYsODIuMTk0IDExNy43MDIsODEuMDkyIEMxMTguNTEsNzkuNjkyIDExOS4xNzUsNzguMjIgMTE5LjY3OCw3Ni43MTcgTDEyMC4xMjEsNzYuODY1IEMxMTkuNjA4LDc4LjM5OCAxMTguOTMsNzkuODk5IDExOC4xMDYsODEuMzI2IEMxMTcuNDU4LDgyLjQ0OCAxMTYuNzIyLDgzLjUyMSAxMTUuOTE3LDg0LjUxNCIgaWQ9IkZpbGwtMzciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTE0LDEzMC40NzYgTDExNCwxMzAuMDA4IEwxMTQsNzYuMDUyIEwxMTQsNzUuNTg0IEwxMTQsNzYuMDUyIEwxMTQsMTMwLjAwOCBMMTE0LDEzMC40NzYiIGlkPSJGaWxsLTM4IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICA8L2c+CiAgICAgICAgICAgICAgICA8ZyBpZD0iSW1wb3J0ZWQtTGF5ZXJzLUNvcHkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDYyLjAwMDAwMCwgMC4wMDAwMDApIiBza2V0Y2g6dHlwZT0iTVNTaGFwZUdyb3VwIj4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTkuODIyLDM3LjQ3NCBDMTkuODM5LDM3LjMzOSAxOS43NDcsMzcuMTk0IDE5LjU1NSwzNy4wODIgQzE5LjIyOCwzNi44OTQgMTguNzI5LDM2Ljg3MiAxOC40NDYsMzcuMDM3IEwxMi40MzQsNDAuNTA4IEMxMi4zMDMsNDAuNTg0IDEyLjI0LDQwLjY4NiAxMi4yNDMsNDAuNzkzIEMxMi4yNDUsNDAuOTI1IDEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQxLjM3MSBMMTIuMjQ1LDQxLjQxNCBMMTIuMjM4LDQxLjU0MiBDOC4xNDgsNDMuODg3IDUuNjQ3LDQ1LjMyMSA1LjY0Nyw0NS4zMjEgQzUuNjQ2LDQ1LjMyMSAzLjU3LDQ2LjM2NyAyLjg2LDUwLjUxMyBDMi44Niw1MC41MTMgMS45NDgsNTcuNDc0IDEuOTYyLDcwLjI1OCBDMS45NzcsODIuODI4IDIuNTY4LDg3LjMyOCAzLjEyOSw5MS42MDkgQzMuMzQ5LDkzLjI5MyA2LjEzLDkzLjczNCA2LjEzLDkzLjczNCBDNi40NjEsOTMuNzc0IDYuODI4LDkzLjcwNyA3LjIxLDkzLjQ4NiBMODIuNDgzLDQ5LjkzNSBDODQuMjkxLDQ4Ljg2NiA4NS4xNSw0Ni4yMTYgODUuNTM5LDQzLjY1MSBDODYuNzUyLDM1LjY2MSA4Ny4yMTQsMTAuNjczIDg1LjI2NCwzLjc3MyBDODUuMDY4LDMuMDggODQuNzU0LDIuNjkgODQuMzk2LDIuNDkxIEw4Mi4zMSwxLjcwMSBDODEuNTgzLDEuNzI5IDgwLjg5NCwyLjE2OCA4MC43NzYsMi4yMzYgQzgwLjYzNiwyLjMxNyA0MS44MDcsMjQuNTg1IDIwLjAzMiwzNy4wNzIgTDE5LjgyMiwzNy40NzQiIGlkPSJGaWxsLTEiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNODIuMzExLDEuNzAxIEw4NC4zOTYsMi40OTEgQzg0Ljc1NCwyLjY5IDg1LjA2OCwzLjA4IDg1LjI2NCwzLjc3MyBDODcuMjEzLDEwLjY3MyA4Ni43NTEsMzUuNjYgODUuNTM5LDQzLjY1MSBDODUuMTQ5LDQ2LjIxNiA4NC4yOSw0OC44NjYgODIuNDgzLDQ5LjkzNSBMNy4yMSw5My40ODYgQzYuODk3LDkzLjY2NyA2LjU5NSw5My43NDQgNi4zMTQsOTMuNzQ0IEw2LjEzMSw5My43MzMgQzYuMTMxLDkzLjczNCAzLjM0OSw5My4yOTMgMy4xMjgsOTEuNjA5IEMyLjU2OCw4Ny4zMjcgMS45NzcsODIuODI4IDEuOTYzLDcwLjI1OCBDMS45NDgsNTcuNDc0IDIuODYsNTAuNTEzIDIuODYsNTAuNTEzIEMzLjU3LDQ2LjM2NyA1LjY0Nyw0NS4zMjEgNS42NDcsNDUuMzIxIEM1LjY0Nyw0NS4zMjEgOC4xNDgsNDMuODg3IDEyLjIzOCw0MS41NDIgTDEyLjI0NSw0MS40MTQgTDEyLjI0NSw0MS4zNzEgQzEyLjI0NSw0MS4yNTQgMTIuMjQ1LDQwLjkyNSAxMi4yNDMsNDAuNzkzIEMxMi4yNCw0MC42ODYgMTIuMzAyLDQwLjU4MyAxMi40MzQsNDAuNTA4IEwxOC40NDYsMzcuMDM2IEMxOC41NzQsMzYuOTYyIDE4Ljc0NiwzNi45MjYgMTguOTI3LDM2LjkyNiBDMTkuMTQ1LDM2LjkyNiAxOS4zNzYsMzYuOTc5IDE5LjU1NCwzNy4wODIgQzE5Ljc0NywzNy4xOTQgMTkuODM5LDM3LjM0IDE5LjgyMiwzNy40NzQgTDIwLjAzMywzNy4wNzIgQzQxLjgwNiwyNC41ODUgODAuNjM2LDIuMzE4IDgwLjc3NywyLjIzNiBDODAuODk0LDIuMTY4IDgxLjU4MywxLjcyOSA4Mi4zMTEsMS43MDEgTTgyLjMxMSwwLjcwNCBMODIuMjcyLDAuNzA1IEM4MS42NTQsMC43MjggODAuOTg5LDAuOTQ5IDgwLjI5OCwxLjM2MSBMODAuMjc3LDEuMzczIEM4MC4xMjksMS40NTggNTkuNzY4LDEzLjEzNSAxOS43NTgsMzYuMDc5IEMxOS41LDM1Ljk4MSAxOS4yMTQsMzUuOTI5IDE4LjkyNywzNS45MjkgQzE4LjU2MiwzNS45MjkgMTguMjIzLDM2LjAxMyAxNy45NDcsMzYuMTczIEwxMS45MzUsMzkuNjQ0IEMxMS40OTMsMzkuODk5IDExLjIzNiw0MC4zMzQgMTEuMjQ2LDQwLjgxIEwxMS4yNDcsNDAuOTYgTDUuMTY3LDQ0LjQ0NyBDNC43OTQsNDQuNjQ2IDIuNjI1LDQ1Ljk3OCAxLjg3Nyw1MC4zNDUgTDEuODcxLDUwLjM4NCBDMS44NjIsNTAuNDU0IDAuOTUxLDU3LjU1NyAwLjk2NSw3MC4yNTkgQzAuOTc5LDgyLjg3OSAxLjU2OCw4Ny4zNzUgMi4xMzcsOTEuNzI0IEwyLjEzOSw5MS43MzkgQzIuNDQ3LDk0LjA5NCA1LjYxNCw5NC42NjIgNS45NzUsOTQuNzE5IEw2LjAwOSw5NC43MjMgQzYuMTEsOTQuNzM2IDYuMjEzLDk0Ljc0MiA2LjMxNCw5NC43NDIgQzYuNzksOTQuNzQyIDcuMjYsOTQuNjEgNy43MSw5NC4zNSBMODIuOTgzLDUwLjc5OCBDODQuNzk0LDQ5LjcyNyA4NS45ODIsNDcuMzc1IDg2LjUyNSw0My44MDEgQzg3LjcxMSwzNS45ODcgODguMjU5LDEwLjcwNSA4Ni4yMjQsMy41MDIgQzg1Ljk3MSwyLjYwOSA4NS41MiwxLjk3NSA4NC44ODEsMS42MiBMODQuNzQ5LDEuNTU4IEw4Mi42NjQsMC43NjkgQzgyLjU1MSwwLjcyNSA4Mi40MzEsMC43MDQgODIuMzExLDAuNzA0IiBpZD0iRmlsbC0yIiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTY2LjI2NywxMS41NjUgTDY3Ljc2MiwxMS45OTkgTDExLjQyMyw0NC4zMjUiIGlkPSJGaWxsLTMiIGZpbGw9IiNGRkZGRkYiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMjAyLDkwLjU0NSBDMTIuMDI5LDkwLjU0NSAxMS44NjIsOTAuNDU1IDExLjc2OSw5MC4yOTUgQzExLjYzMiw5MC4wNTcgMTEuNzEzLDg5Ljc1MiAxMS45NTIsODkuNjE0IEwzMC4zODksNzguOTY5IEMzMC42MjgsNzguODMxIDMwLjkzMyw3OC45MTMgMzEuMDcxLDc5LjE1MiBDMzEuMjA4LDc5LjM5IDMxLjEyNyw3OS42OTYgMzAuODg4LDc5LjgzMyBMMTIuNDUxLDkwLjQ3OCBMMTIuMjAyLDkwLjU0NSIgaWQ9IkZpbGwtNCIgZmlsbD0iIzYwN0Q4QiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMy43NjQsNDIuNjU0IEwxMy42NTYsNDIuNTkyIEwxMy43MDIsNDIuNDIxIEwxOC44MzcsMzkuNDU3IEwxOS4wMDcsMzkuNTAyIEwxOC45NjIsMzkuNjczIEwxMy44MjcsNDIuNjM3IEwxMy43NjQsNDIuNjU0IiBpZD0iRmlsbC01IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTguNTIsOTAuMzc1IEw4LjUyLDQ2LjQyMSBMOC41ODMsNDYuMzg1IEw3NS44NCw3LjU1NCBMNzUuODQsNTEuNTA4IEw3NS43NzgsNTEuNTQ0IEw4LjUyLDkwLjM3NSBMOC41Miw5MC4zNzUgWiBNOC43Nyw0Ni41NjQgTDguNzcsODkuOTQ0IEw3NS41OTEsNTEuMzY1IEw3NS41OTEsNy45ODUgTDguNzcsNDYuNTY0IEw4Ljc3LDQ2LjU2NCBaIiBpZD0iRmlsbC02IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTI0Ljk4Niw4My4xODIgQzI0Ljc1Niw4My4zMzEgMjQuMzc0LDgzLjU2NiAyNC4xMzcsODMuNzA1IEwxMi42MzIsOTAuNDA2IEMxMi4zOTUsOTAuNTQ1IDEyLjQyNiw5MC42NTggMTIuNyw5MC42NTggTDEzLjI2NSw5MC42NTggQzEzLjU0LDkwLjY1OCAxMy45NTgsOTAuNTQ1IDE0LjE5NSw5MC40MDYgTDI1LjcsODMuNzA1IEMyNS45MzcsODMuNTY2IDI2LjEyOCw4My40NTIgMjYuMTI1LDgzLjQ0OSBDMjYuMTIyLDgzLjQ0NyAyNi4xMTksODMuMjIgMjYuMTE5LDgyLjk0NiBDMjYuMTE5LDgyLjY3MiAyNS45MzEsODIuNTY5IDI1LjcwMSw4Mi43MTkgTDI0Ljk4Niw4My4xODIiIGlkPSJGaWxsLTciIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTMuMjY2LDkwLjc4MiBMMTIuNyw5MC43ODIgQzEyLjUsOTAuNzgyIDEyLjM4NCw5MC43MjYgMTIuMzU0LDkwLjYxNiBDMTIuMzI0LDkwLjUwNiAxMi4zOTcsOTAuMzk5IDEyLjU2OSw5MC4yOTkgTDI0LjA3NCw4My41OTcgQzI0LjMxLDgzLjQ1OSAyNC42ODksODMuMjI2IDI0LjkxOCw4My4wNzggTDI1LjYzMyw4Mi42MTQgQzI1LjcyMyw4Mi41NTUgMjUuODEzLDgyLjUyNSAyNS44OTksODIuNTI1IEMyNi4wNzEsODIuNTI1IDI2LjI0NCw4Mi42NTUgMjYuMjQ0LDgyLjk0NiBDMjYuMjQ0LDgzLjE2IDI2LjI0NSw4My4zMDkgMjYuMjQ3LDgzLjM4MyBMMjYuMjUzLDgzLjM4NyBMMjYuMjQ5LDgzLjQ1NiBDMjYuMjQ2LDgzLjUzMSAyNi4yNDYsODMuNTMxIDI1Ljc2Myw4My44MTIgTDE0LjI1OCw5MC41MTQgQzE0LDkwLjY2NSAxMy41NjQsOTAuNzgyIDEzLjI2Niw5MC43ODIgTDEzLjI2Niw5MC43ODIgWiBNMTIuNjY2LDkwLjUzMiBMMTIuNyw5MC41MzMgTDEzLjI2Niw5MC41MzMgQzEzLjUxOCw5MC41MzMgMTMuOTE1LDkwLjQyNSAxNC4xMzIsOTAuMjk5IEwyNS42MzcsODMuNTk3IEMyNS44MDUsODMuNDk5IDI1LjkzMSw4My40MjQgMjUuOTk4LDgzLjM4MyBDMjUuOTk0LDgzLjI5OSAyNS45OTQsODMuMTY1IDI1Ljk5NCw4Mi45NDYgTDI1Ljg5OSw4Mi43NzUgTDI1Ljc2OCw4Mi44MjQgTDI1LjA1NCw4My4yODcgQzI0LjgyMiw4My40MzcgMjQuNDM4LDgzLjY3MyAyNC4yLDgzLjgxMiBMMTIuNjk1LDkwLjUxNCBMMTIuNjY2LDkwLjUzMiBMMTIuNjY2LDkwLjUzMiBaIiBpZD0iRmlsbC04IiBmaWxsPSIjNjA3RDhCIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEzLjI2Niw4OS44NzEgTDEyLjcsODkuODcxIEMxMi41LDg5Ljg3MSAxMi4zODQsODkuODE1IDEyLjM1NCw4OS43MDUgQzEyLjMyNCw4OS41OTUgMTIuMzk3LDg5LjQ4OCAxMi41NjksODkuMzg4IEwyNC4wNzQsODIuNjg2IEMyNC4zMzIsODIuNTM1IDI0Ljc2OCw4Mi40MTggMjUuMDY3LDgyLjQxOCBMMjUuNjMyLDgyLjQxOCBDMjUuODMyLDgyLjQxOCAyNS45NDgsODIuNDc0IDI1Ljk3OCw4Mi41ODQgQzI2LjAwOCw4Mi42OTQgMjUuOTM1LDgyLjgwMSAyNS43NjMsODIuOTAxIEwxNC4yNTgsODkuNjAzIEMxNCw4OS43NTQgMTMuNTY0LDg5Ljg3MSAxMy4yNjYsODkuODcxIEwxMy4yNjYsODkuODcxIFogTTEyLjY2Niw4OS42MjEgTDEyLjcsODkuNjIyIEwxMy4yNjYsODkuNjIyIEMxMy41MTgsODkuNjIyIDEzLjkxNSw4OS41MTUgMTQuMTMyLDg5LjM4OCBMMjUuNjM3LDgyLjY4NiBMMjUuNjY3LDgyLjY2OCBMMjUuNjMyLDgyLjY2NyBMMjUuMDY3LDgyLjY2NyBDMjQuODE1LDgyLjY2NyAyNC40MTgsODIuNzc1IDI0LjIsODIuOTAxIEwxMi42OTUsODkuNjAzIEwxMi42NjYsODkuNjIxIEwxMi42NjYsODkuNjIxIFoiIGlkPSJGaWxsLTkiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNMTIuMzcsOTAuODAxIEwxMi4zNyw4OS41NTQgTDEyLjM3LDkwLjgwMSIgaWQ9IkZpbGwtMTAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNi4xMyw5My45MDEgQzUuMzc5LDkzLjgwOCA0LjgxNiw5My4xNjQgNC42OTEsOTIuNTI1IEMzLjg2LDg4LjI4NyAzLjU0LDgzLjc0MyAzLjUyNiw3MS4xNzMgQzMuNTExLDU4LjM4OSA0LjQyMyw1MS40MjggNC40MjMsNTEuNDI4IEM1LjEzNCw0Ny4yODIgNy4yMSw0Ni4yMzYgNy4yMSw0Ni4yMzYgQzcuMjEsNDYuMjM2IDgxLjY2NywzLjI1IDgyLjA2OSwzLjAxNyBDODIuMjkyLDIuODg4IDg0LjU1NiwxLjQzMyA4NS4yNjQsMy45NCBDODcuMjE0LDEwLjg0IDg2Ljc1MiwzNS44MjcgODUuNTM5LDQzLjgxOCBDODUuMTUsNDYuMzgzIDg0LjI5MSw0OS4wMzMgODIuNDgzLDUwLjEwMSBMNy4yMSw5My42NTMgQzYuODI4LDkzLjg3NCA2LjQ2MSw5My45NDEgNi4xMyw5My45MDEgQzYuMTMsOTMuOTAxIDMuMzQ5LDkzLjQ2IDMuMTI5LDkxLjc3NiBDMi41NjgsODcuNDk1IDEuOTc3LDgyLjk5NSAxLjk2Miw3MC40MjUgQzEuOTQ4LDU3LjY0MSAyLjg2LDUwLjY4IDIuODYsNTAuNjggQzMuNTcsNDYuNTM0IDUuNjQ3LDQ1LjQ4OSA1LjY0Nyw0NS40ODkgQzUuNjQ2LDQ1LjQ4OSA4LjA2NSw0NC4wOTIgMTIuMjQ1LDQxLjY3OSBMMTMuMTE2LDQxLjU2IEwxOS43MTUsMzcuNzMgTDE5Ljc2MSwzNy4yNjkgTDYuMTMsOTMuOTAxIiBpZD0iRmlsbC0xMSIgZmlsbD0iI0ZBRkFGQSI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjMxNyw5NC4xNjEgTDYuMTAyLDk0LjE0OCBMNi4xMDEsOTQuMTQ4IEw1Ljg1Nyw5NC4xMDEgQzUuMTM4LDkzLjk0NSAzLjA4NSw5My4zNjUgMi44ODEsOTEuODA5IEMyLjMxMyw4Ny40NjkgMS43MjcsODIuOTk2IDEuNzEzLDcwLjQyNSBDMS42OTksNTcuNzcxIDIuNjA0LDUwLjcxOCAyLjYxMyw1MC42NDggQzMuMzM4LDQ2LjQxNyA1LjQ0NSw0NS4zMSA1LjUzNSw0NS4yNjYgTDEyLjE2Myw0MS40MzkgTDEzLjAzMyw0MS4zMiBMMTkuNDc5LDM3LjU3OCBMMTkuNTEzLDM3LjI0NCBDMTkuNTI2LDM3LjEwNyAxOS42NDcsMzcuMDA4IDE5Ljc4NiwzNy4wMjEgQzE5LjkyMiwzNy4wMzQgMjAuMDIzLDM3LjE1NiAyMC4wMDksMzcuMjkzIEwxOS45NSwzNy44ODIgTDEzLjE5OCw0MS44MDEgTDEyLjMyOCw0MS45MTkgTDUuNzcyLDQ1LjcwNCBDNS43NDEsNDUuNzIgMy43ODIsNDYuNzcyIDMuMTA2LDUwLjcyMiBDMy4wOTksNTAuNzgyIDIuMTk4LDU3LjgwOCAyLjIxMiw3MC40MjQgQzIuMjI2LDgyLjk2MyAyLjgwOSw4Ny40MiAzLjM3Myw5MS43MjkgQzMuNDY0LDkyLjQyIDQuMDYyLDkyLjg4MyA0LjY4Miw5My4xODEgQzQuNTY2LDkyLjk4NCA0LjQ4Niw5Mi43NzYgNC40NDYsOTIuNTcyIEMzLjY2NSw4OC41ODggMy4yOTEsODQuMzcgMy4yNzYsNzEuMTczIEMzLjI2Miw1OC41MiA0LjE2Nyw1MS40NjYgNC4xNzYsNTEuMzk2IEM0LjkwMSw0Ny4xNjUgNy4wMDgsNDYuMDU5IDcuMDk4LDQ2LjAxNCBDNy4wOTQsNDYuMDE1IDgxLjU0MiwzLjAzNCA4MS45NDQsMi44MDIgTDgxLjk3MiwyLjc4NSBDODIuODc2LDIuMjQ3IDgzLjY5MiwyLjA5NyA4NC4zMzIsMi4zNTIgQzg0Ljg4NywyLjU3MyA4NS4yODEsMy4wODUgODUuNTA0LDMuODcyIEM4Ny41MTgsMTEgODYuOTY0LDM2LjA5MSA4NS43ODUsNDMuODU1IEM4NS4yNzgsNDcuMTk2IDg0LjIxLDQ5LjM3IDgyLjYxLDUwLjMxNyBMNy4zMzUsOTMuODY5IEM2Ljk5OSw5NC4wNjMgNi42NTgsOTQuMTYxIDYuMzE3LDk0LjE2MSBMNi4zMTcsOTQuMTYxIFogTTYuMTcsOTMuNjU0IEM2LjQ2Myw5My42OSA2Ljc3NCw5My42MTcgNy4wODUsOTMuNDM3IEw4Mi4zNTgsNDkuODg2IEM4NC4xODEsNDguODA4IDg0Ljk2LDQ1Ljk3MSA4NS4yOTIsNDMuNzggQzg2LjQ2NiwzNi4wNDkgODcuMDIzLDExLjA4NSA4NS4wMjQsNC4wMDggQzg0Ljg0NiwzLjM3NyA4NC41NTEsMi45NzYgODQuMTQ4LDIuODE2IEM4My42NjQsMi42MjMgODIuOTgyLDIuNzY0IDgyLjIyNywzLjIxMyBMODIuMTkzLDMuMjM0IEM4MS43OTEsMy40NjYgNy4zMzUsNDYuNDUyIDcuMzM1LDQ2LjQ1MiBDNy4zMDQsNDYuNDY5IDUuMzQ2LDQ3LjUyMSA0LjY2OSw1MS40NzEgQzQuNjYyLDUxLjUzIDMuNzYxLDU4LjU1NiAzLjc3NSw3MS4xNzMgQzMuNzksODQuMzI4IDQuMTYxLDg4LjUyNCA0LjkzNiw5Mi40NzYgQzUuMDI2LDkyLjkzNyA1LjQxMiw5My40NTkgNS45NzMsOTMuNjE1IEM2LjA4Nyw5My42NCA2LjE1OCw5My42NTIgNi4xNjksOTMuNjU0IEw2LjE3LDkzLjY1NCBMNi4xNyw5My42NTQgWiIgaWQ9IkZpbGwtMTIiIGZpbGw9IiM0NTVBNjQiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4zMTcsNjguOTgyIEM3LjgwNiw2OC43MDEgOC4yMDIsNjguOTI2IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNi44MjksNzEuMjk0IDYuNDMzLDcxLjA2OSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIiBpZD0iRmlsbC0xMyIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik02LjkyLDcxLjEzMyBDNi42MzEsNzEuMTMzIDYuNDMzLDcwLjkwNSA2LjQzMyw3MC41MDggQzYuNDMzLDY5Ljk0OCA2LjgyOSw2OS4yNjUgNy4zMTcsNjguOTgyIEM3LjQ2LDY4LjkgNy41OTUsNjguODYxIDcuNzE0LDY4Ljg2MSBDOC4wMDMsNjguODYxIDguMjAyLDY5LjA5IDguMjAyLDY5LjQ4NyBDOC4yMDIsNzAuMDQ3IDcuODA2LDcwLjczIDcuMzE3LDcxLjAxMiBDNy4xNzQsNzEuMDk0IDcuMDM5LDcxLjEzMyA2LjkyLDcxLjEzMyBNNy43MTQsNjguNjc0IEM3LjU1Nyw2OC42NzQgNy4zOTIsNjguNzIzIDcuMjI0LDY4LjgyMSBDNi42NzYsNjkuMTM4IDYuMjQ2LDY5Ljg3OSA2LjI0Niw3MC41MDggQzYuMjQ2LDcwLjk5NCA2LjUxNyw3MS4zMiA2LjkyLDcxLjMyIEM3LjA3OCw3MS4zMiA3LjI0Myw3MS4yNzEgNy40MTEsNzEuMTc0IEM3Ljk1OSw3MC44NTcgOC4zODksNzAuMTE3IDguMzg5LDY5LjQ4NyBDOC4zODksNjkuMDAxIDguMTE3LDY4LjY3NCA3LjcxNCw2OC42NzQiIGlkPSJGaWxsLTE0IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTYuOTIsNzAuOTQ3IEM2LjY0OSw3MC45NDcgNi42MjEsNzAuNjQgNi42MjEsNzAuNTA4IEM2LjYyMSw3MC4wMTcgNi45ODIsNjkuMzkyIDcuNDExLDY5LjE0NSBDNy41MjEsNjkuMDgyIDcuNjI1LDY5LjA0OSA3LjcxNCw2OS4wNDkgQzcuOTg2LDY5LjA0OSA4LjAxNSw2OS4zNTUgOC4wMTUsNjkuNDg3IEM4LjAxNSw2OS45NzggNy42NTIsNzAuNjAzIDcuMjI0LDcwLjg1MSBDNy4xMTUsNzAuOTE0IDcuMDEsNzAuOTQ3IDYuOTIsNzAuOTQ3IE03LjcxNCw2OC44NjEgQzcuNTk1LDY4Ljg2MSA3LjQ2LDY4LjkgNy4zMTcsNjguOTgyIEM2LjgyOSw2OS4yNjUgNi40MzMsNjkuOTQ4IDYuNDMzLDcwLjUwOCBDNi40MzMsNzAuOTA1IDYuNjMxLDcxLjEzMyA2LjkyLDcxLjEzMyBDNy4wMzksNzEuMTMzIDcuMTc0LDcxLjA5NCA3LjMxNyw3MS4wMTIgQzcuODA2LDcwLjczIDguMjAyLDcwLjA0NyA4LjIwMiw2OS40ODcgQzguMjAyLDY5LjA5IDguMDAzLDY4Ljg2MSA3LjcxNCw2OC44NjEiIGlkPSJGaWxsLTE1IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTcuNDQ0LDg1LjM1IEM3LjcwOCw4NS4xOTggNy45MjEsODUuMzE5IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuOTI1IDcuNzA4LDg2LjI5MiA3LjQ0NCw4Ni40NDQgQzcuMTgxLDg2LjU5NyA2Ljk2Nyw4Ni40NzUgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IiBpZD0iRmlsbC0xNiIgZmlsbD0iI0ZGRkZGRiI+PC9wYXRoPgogICAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik03LjIzLDg2LjUxIEM3LjA3NCw4Ni41MSA2Ljk2Nyw4Ni4zODcgNi45NjcsODYuMTczIEM2Ljk2Nyw4NS44NzEgNy4xODEsODUuNTAyIDcuNDQ0LDg1LjM1IEM3LjUyMSw4NS4zMDUgNy41OTQsODUuMjg0IDcuNjU4LDg1LjI4NCBDNy44MTQsODUuMjg0IDcuOTIxLDg1LjQwOCA3LjkyMSw4NS42MjIgQzcuOTIxLDg1LjkyNSA3LjcwOCw4Ni4yOTIgNy40NDQsODYuNDQ0IEM3LjM2Nyw4Ni40ODkgNy4yOTQsODYuNTEgNy4yMyw4Ni41MSBNNy42NTgsODUuMDk4IEM3LjU1OCw4NS4wOTggNy40NTUsODUuMTI3IDcuMzUxLDg1LjE4OCBDNy4wMzEsODUuMzczIDYuNzgxLDg1LjgwNiA2Ljc4MSw4Ni4xNzMgQzYuNzgxLDg2LjQ4MiA2Ljk2Niw4Ni42OTcgNy4yMyw4Ni42OTcgQzcuMzMsODYuNjk3IDcuNDMzLDg2LjY2NiA3LjUzOCw4Ni42MDcgQzcuODU4LDg2LjQyMiA4LjEwOCw4NS45ODkgOC4xMDgsODUuNjIyIEM4LjEwOCw4NS4zMTMgNy45MjMsODUuMDk4IDcuNjU4LDg1LjA5OCIgaWQ9IkZpbGwtMTciIGZpbGw9IiM4MDk3QTIiPjwvcGF0aD4KICAgICAgICAgICAgICAgICAgICA8cGF0aCBkPSJNNy4yMyw4Ni4zMjIgTDcuMTU0LDg2LjE3MyBDNy4xNTQsODUuOTM4IDcuMzMzLDg1LjYyOSA3LjUzOCw4NS41MTIgTDcuNjU4LDg1LjQ3MSBMNy43MzQsODUuNjIyIEM3LjczNCw4NS44NTYgNy41NTUsODYuMTY0IDcuMzUxLDg2LjI4MiBMNy4yMyw4Ni4zMjIgTTcuNjU4LDg1LjI4NCBDNy41OTQsODUuMjg0IDcuNTIxLDg1LjMwNSA3LjQ0NCw4NS4zNSBDNy4xODEsODUuNTAyIDYuOTY3LDg1Ljg3MSA2Ljk2Nyw4Ni4xNzMgQzYuOTY3LDg2LjM4NyA3LjA3NCw4Ni41MSA3LjIzLDg2LjUxIEM3LjI5NCw4Ni41MSA3LjM2Nyw4Ni40ODkgNy40NDQsODYuNDQ0IEM3LjcwOCw4Ni4yOTIgNy45MjEsODUuOTI1IDcuOTIxLDg1LjYyMiBDNy45MjEsODUuNDA4IDcuODE0LDg1LjI4NCA3LjY1OCw4NS4yODQiIGlkPSJGaWxsLTE4IiBmaWxsPSIjODA5N0EyIj48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTc3LjI3OCw3Ljc2OSBMNzcuMjc4LDUxLjQzNiBMMTAuMjA4LDkwLjE2IEwxMC4yMDgsNDYuNDkzIEw3Ny4yNzgsNy43NjkiIGlkPSJGaWxsLTE5IiBmaWxsPSIjNDU1QTY0Ij48L3BhdGg+CiAgICAgICAgICAgICAgICAgICAgPHBhdGggZD0iTTEwLjA4Myw5MC4zNzUgTDEwLjA4Myw0Ni40MjEgTDEwLjE0Niw0Ni4zODUgTDc3LjQwMyw3LjU1NCBMNzcuNDAzLDUxLjUwOCBMNzcuMzQxLDUxLjU0NCBMMTAuMDgzLDkwLjM3NSBMMTAuMDgzLDkwLjM3NSBaIE0xMC4zMzMsNDYuNTY0IEwxMC4zMzMsODkuOTQ0IEw3Ny4xNTQsNTEuMzY1IEw3Ny4xNTQsNy45ODUgTDEwLjMzMyw0Ni41NjQgTDEwLjMzMyw0Ni41NjQgWiIgaWQ9IkZpbGwtMjAiIGZpbGw9IiM2MDdEOEIiPjwvcGF0aD4KICAgICAgICAgICAgICAgIDwvZz4KICAgICAgICAgICAgICAgIDxwYXRoIGQ9Ik0xMjUuNzM3LDg4LjY0NyBMMTE4LjA5OCw5MS45ODEgTDExOC4wOTgsODQgTDEwNi42MzksODguNzEzIEwxMDYuNjM5LDk2Ljk4MiBMOTksMTAwLjMxNSBMMTEyLjM2OSwxMDMuOTYxIEwxMjUuNzM3LDg4LjY0NyIgaWQ9IkltcG9ydGVkLUxheWVycy1Db3B5LTIiIGZpbGw9IiM0NTVBNjQiIHNrZXRjaDp0eXBlPSJNU1NoYXBlR3JvdXAiPjwvcGF0aD4KICAgICAgICAgICAgPC9nPgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+');
- };
- module.exports = RotateInstructions;
- },{"./util.js":29}],24:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var SensorSample = _dereq_('./sensor-sample.js');
- var MathUtil = _dereq_('../math-util.js');
- var Util = _dereq_('../util.js');
- /**
- * An implementation of a simple complementary filter, which fuses gyroscope and
- * accelerometer data from the 'devicemotion' event.
- *
- * Accelerometer data is very noisy, but stable over the long term.
- * Gyroscope data is smooth, but tends to drift over the long term.
- *
- * This fusion is relatively simple:
- * 1. Get orientation estimates from accelerometer by applying a low-pass filter
- * on that data.
- * 2. Get orientation estimates from gyroscope by integrating over time.
- * 3. Combine the two estimates, weighing (1) in the long term, but (2) for the
- * short term.
- */
- function ComplementaryFilter(kFilter) {
- this.kFilter = kFilter;
- // Raw sensor measurements.
- this.currentAccelMeasurement = new SensorSample();
- this.currentGyroMeasurement = new SensorSample();
- this.previousGyroMeasurement = new SensorSample();
- // Set default look direction to be in the correct direction.
- if (Util.isIOS()) {
- this.filterQ = new MathUtil.Quaternion(-1, 0, 0, 1);
- } else {
- this.filterQ = new MathUtil.Quaternion(1, 0, 0, 1);
- }
- this.previousFilterQ = new MathUtil.Quaternion();
- this.previousFilterQ.copy(this.filterQ);
- // Orientation based on the accelerometer.
- this.accelQ = new MathUtil.Quaternion();
- // Whether or not the orientation has been initialized.
- this.isOrientationInitialized = false;
- // Running estimate of gravity based on the current orientation.
- this.estimatedGravity = new MathUtil.Vector3();
- // Measured gravity based on accelerometer.
- this.measuredGravity = new MathUtil.Vector3();
- // Debug only quaternion of gyro-based orientation.
- this.gyroIntegralQ = new MathUtil.Quaternion();
- }
- ComplementaryFilter.prototype.addAccelMeasurement = function(vector, timestampS) {
- this.currentAccelMeasurement.set(vector, timestampS);
- };
- ComplementaryFilter.prototype.addGyroMeasurement = function(vector, timestampS) {
- this.currentGyroMeasurement.set(vector, timestampS);
- var deltaT = timestampS - this.previousGyroMeasurement.timestampS;
- if (Util.isTimestampDeltaValid(deltaT)) {
- this.run_();
- }
- this.previousGyroMeasurement.copy(this.currentGyroMeasurement);
- };
- ComplementaryFilter.prototype.run_ = function() {
- if (!this.isOrientationInitialized) {
- this.accelQ = this.accelToQuaternion_(this.currentAccelMeasurement.sample);
- this.previousFilterQ.copy(this.accelQ);
- this.isOrientationInitialized = true;
- return;
- }
- var deltaT = this.currentGyroMeasurement.timestampS -
- this.previousGyroMeasurement.timestampS;
- // Convert gyro rotation vector to a quaternion delta.
- var gyroDeltaQ = this.gyroToQuaternionDelta_(this.currentGyroMeasurement.sample, deltaT);
- this.gyroIntegralQ.multiply(gyroDeltaQ);
- // filter_1 = K * (filter_0 + gyro * dT) + (1 - K) * accel.
- this.filterQ.copy(this.previousFilterQ);
- this.filterQ.multiply(gyroDeltaQ);
- // Calculate the delta between the current estimated gravity and the real
- // gravity vector from accelerometer.
- var invFilterQ = new MathUtil.Quaternion();
- invFilterQ.copy(this.filterQ);
- invFilterQ.inverse();
- this.estimatedGravity.set(0, 0, -1);
- this.estimatedGravity.applyQuaternion(invFilterQ);
- this.estimatedGravity.normalize();
- this.measuredGravity.copy(this.currentAccelMeasurement.sample);
- this.measuredGravity.normalize();
- // Compare estimated gravity with measured gravity, get the delta quaternion
- // between the two.
- var deltaQ = new MathUtil.Quaternion();
- deltaQ.setFromUnitVectors(this.estimatedGravity, this.measuredGravity);
- deltaQ.inverse();
- if (Util.isDebug()) {
- console.log('Delta: %d deg, G_est: (%s, %s, %s), G_meas: (%s, %s, %s)',
- MathUtil.radToDeg * Util.getQuaternionAngle(deltaQ),
- (this.estimatedGravity.x).toFixed(1),
- (this.estimatedGravity.y).toFixed(1),
- (this.estimatedGravity.z).toFixed(1),
- (this.measuredGravity.x).toFixed(1),
- (this.measuredGravity.y).toFixed(1),
- (this.measuredGravity.z).toFixed(1));
- }
- // Calculate the SLERP target: current orientation plus the measured-estimated
- // quaternion delta.
- var targetQ = new MathUtil.Quaternion();
- targetQ.copy(this.filterQ);
- targetQ.multiply(deltaQ);
- // SLERP factor: 0 is pure gyro, 1 is pure accel.
- this.filterQ.slerp(targetQ, 1 - this.kFilter);
- this.previousFilterQ.copy(this.filterQ);
- };
- ComplementaryFilter.prototype.getOrientation = function() {
- return this.filterQ;
- };
- ComplementaryFilter.prototype.accelToQuaternion_ = function(accel) {
- var normAccel = new MathUtil.Vector3();
- normAccel.copy(accel);
- normAccel.normalize();
- var quat = new MathUtil.Quaternion();
- quat.setFromUnitVectors(new MathUtil.Vector3(0, 0, -1), normAccel);
- quat.inverse();
- return quat;
- };
- ComplementaryFilter.prototype.gyroToQuaternionDelta_ = function(gyro, dt) {
- // Extract axis and angle from the gyroscope data.
- var quat = new MathUtil.Quaternion();
- var axis = new MathUtil.Vector3();
- axis.copy(gyro);
- axis.normalize();
- quat.setFromAxisAngle(axis, gyro.length() * dt);
- return quat;
- };
- module.exports = ComplementaryFilter;
- },{"../math-util.js":20,"../util.js":29,"./sensor-sample.js":27}],25:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var ComplementaryFilter = _dereq_('./complementary-filter.js');
- var PosePredictor = _dereq_('./pose-predictor.js');
- var TouchPanner = _dereq_('../touch-panner.js');
- var MathUtil = _dereq_('../math-util.js');
- var Util = _dereq_('../util.js');
- /**
- * The pose sensor, implemented using DeviceMotion APIs.
- */
- function FusionPoseSensor() {
- this.deviceId = 'webvr-polyfill:fused';
- this.deviceName = 'VR Position Device (webvr-polyfill:fused)';
- this.accelerometer = new MathUtil.Vector3();
- this.gyroscope = new MathUtil.Vector3();
- this.start();
- this.filter = new ComplementaryFilter(window.WebVRConfig.K_FILTER);
- this.posePredictor = new PosePredictor(window.WebVRConfig.PREDICTION_TIME_S);
- this.touchPanner = new TouchPanner();
- this.filterToWorldQ = new MathUtil.Quaternion();
- // Set the filter to world transform, depending on OS.
- if (Util.isIOS()) {
- this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), Math.PI / 2);
- } else {
- this.filterToWorldQ.setFromAxisAngle(new MathUtil.Vector3(1, 0, 0), -Math.PI / 2);
- }
- this.inverseWorldToScreenQ = new MathUtil.Quaternion();
- this.worldToScreenQ = new MathUtil.Quaternion();
- this.originalPoseAdjustQ = new MathUtil.Quaternion();
- this.originalPoseAdjustQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1),
- -window.orientation * Math.PI / 180);
- this.setScreenTransform_();
- // Adjust this filter for being in landscape mode.
- if (Util.isLandscapeMode()) {
- this.filterToWorldQ.multiply(this.inverseWorldToScreenQ);
- }
- // Keep track of a reset transform for resetSensor.
- this.resetQ = new MathUtil.Quaternion();
- this.isFirefoxAndroid = Util.isFirefoxAndroid();
- this.isIOS = Util.isIOS();
- this.orientationOut_ = new Float32Array(4);
- }
- FusionPoseSensor.prototype.getPosition = function() {
- // This PoseSensor doesn't support position
- return null;
- };
- FusionPoseSensor.prototype.getOrientation = function() {
- // Convert from filter space to the the same system used by the
- // deviceorientation event.
- var orientation = this.filter.getOrientation();
- // Predict orientation.
- this.predictedQ = this.posePredictor.getPrediction(orientation, this.gyroscope, this.previousTimestampS);
- // Convert to THREE coordinate system: -Z forward, Y up, X right.
- var out = new MathUtil.Quaternion();
- out.copy(this.filterToWorldQ);
- out.multiply(this.resetQ);
- if (!window.WebVRConfig.TOUCH_PANNER_DISABLED) {
- out.multiply(this.touchPanner.getOrientation());
- }
- out.multiply(this.predictedQ);
- out.multiply(this.worldToScreenQ);
- // Handle the yaw-only case.
- if (window.WebVRConfig.YAW_ONLY) {
- // Make a quaternion that only turns around the Y-axis.
- out.x = 0;
- out.z = 0;
- out.normalize();
- }
- this.orientationOut_[0] = out.x;
- this.orientationOut_[1] = out.y;
- this.orientationOut_[2] = out.z;
- this.orientationOut_[3] = out.w;
- return this.orientationOut_;
- };
- FusionPoseSensor.prototype.resetPose = function() {
- // Reduce to inverted yaw-only.
- this.resetQ.copy(this.filter.getOrientation());
- this.resetQ.x = 0;
- this.resetQ.y = 0;
- this.resetQ.z *= -1;
- this.resetQ.normalize();
- // Take into account extra transformations in landscape mode.
- if (Util.isLandscapeMode()) {
- this.resetQ.multiply(this.inverseWorldToScreenQ);
- }
- // Take into account original pose.
- this.resetQ.multiply(this.originalPoseAdjustQ);
- if (!window.WebVRConfig.TOUCH_PANNER_DISABLED) {
- this.touchPanner.resetSensor();
- }
- };
- FusionPoseSensor.prototype.onDeviceMotion_ = function(deviceMotion) {
- this.updateDeviceMotion_(deviceMotion);
- };
- FusionPoseSensor.prototype.updateDeviceMotion_ = function(deviceMotion) {
- var accGravity = deviceMotion.accelerationIncludingGravity;
- var rotRate = deviceMotion.rotationRate;
- var timestampS = deviceMotion.timeStamp / 1000;
- var deltaS = timestampS - this.previousTimestampS;
- if (deltaS <= Util.MIN_TIMESTEP || deltaS > Util.MAX_TIMESTEP) {
- console.warn('Invalid timestamps detected. Time step between successive ' +
- 'gyroscope sensor samples is very small or not monotonic');
- this.previousTimestampS = timestampS;
- return;
- }
- this.accelerometer.set(-accGravity.x, -accGravity.y, -accGravity.z);
- if (Util.isR7()) {
- this.gyroscope.set(-rotRate.beta, rotRate.alpha, rotRate.gamma);
- } else {
- this.gyroscope.set(rotRate.alpha, rotRate.beta, rotRate.gamma);
- }
- // With iOS and Firefox Android, rotationRate is reported in degrees,
- // so we first convert to radians.
- if (this.isIOS || this.isFirefoxAndroid) {
- this.gyroscope.multiplyScalar(Math.PI / 180);
- }
- this.filter.addAccelMeasurement(this.accelerometer, timestampS);
- this.filter.addGyroMeasurement(this.gyroscope, timestampS);
- this.previousTimestampS = timestampS;
- };
- FusionPoseSensor.prototype.onOrientationChange_ = function(screenOrientation) {
- this.setScreenTransform_();
- };
- /**
- * This is only needed if we are in an cross origin iframe on iOS to work around
- * this issue: https://bugs.webkit.org/show_bug.cgi?id=152299.
- */
- FusionPoseSensor.prototype.onMessage_ = function(event) {
- var message = event.data;
- // If there's no message type, ignore it.
- if (!message || !message.type) {
- return;
- }
- // Ignore all messages that aren't devicemotion.
- var type = message.type.toLowerCase();
- if (type !== 'devicemotion') {
- return;
- }
- // Update device motion.
- this.updateDeviceMotion_(message.deviceMotionEvent);
- };
- FusionPoseSensor.prototype.setScreenTransform_ = function() {
- this.worldToScreenQ.set(0, 0, 0, 1);
- switch (window.orientation) {
- case 0:
- break;
- case 90:
- this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), -Math.PI / 2);
- break;
- case -90:
- this.worldToScreenQ.setFromAxisAngle(new MathUtil.Vector3(0, 0, 1), Math.PI / 2);
- break;
- case 180:
- // TODO.
- break;
- }
- this.inverseWorldToScreenQ.copy(this.worldToScreenQ);
- this.inverseWorldToScreenQ.inverse();
- };
- FusionPoseSensor.prototype.start = function() {
- this.onDeviceMotionCallback_ = this.onDeviceMotion_.bind(this);
- this.onOrientationChangeCallback_ = this.onOrientationChange_.bind(this);
- this.onMessageCallback_ = this.onMessage_.bind(this);
- // Only listen for postMessages if we're in an iOS and embedded inside a cross
- // domain IFrame. In this case, the polyfill can still work if the containing
- // page sends synthetic devicemotion events. For an example of this, see
- // iframe-message-sender.js in VR View: https://goo.gl/XDtvFZ
- if (Util.isIOS() && Util.isInsideCrossDomainIFrame()) {
- window.addEventListener('message', this.onMessageCallback_);
- }
- window.addEventListener('orientationchange', this.onOrientationChangeCallback_);
- window.addEventListener('devicemotion', this.onDeviceMotionCallback_);
- };
- FusionPoseSensor.prototype.stop = function() {
- window.removeEventListener('devicemotion', this.onDeviceMotionCallback_);
- window.removeEventListener('orientationchange', this.onOrientationChangeCallback_);
- window.removeEventListener('message', this.onMessageCallback_);
- };
- module.exports = FusionPoseSensor;
- },{"../math-util.js":20,"../touch-panner.js":28,"../util.js":29,"./complementary-filter.js":24,"./pose-predictor.js":26}],26:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var MathUtil = _dereq_('../math-util');
- var Util = _dereq_('../util');
- /**
- * Given an orientation and the gyroscope data, predicts the future orientation
- * of the head. This makes rendering appear faster.
- *
- * Also see: http://msl.cs.uiuc.edu/~lavalle/papers/LavYerKatAnt14.pdf
- *
- * @param {Number} predictionTimeS time from head movement to the appearance of
- * the corresponding image.
- */
- function PosePredictor(predictionTimeS) {
- this.predictionTimeS = predictionTimeS;
- // The quaternion corresponding to the previous state.
- this.previousQ = new MathUtil.Quaternion();
- // Previous time a prediction occurred.
- this.previousTimestampS = null;
- // The delta quaternion that adjusts the current pose.
- this.deltaQ = new MathUtil.Quaternion();
- // The output quaternion.
- this.outQ = new MathUtil.Quaternion();
- }
- PosePredictor.prototype.getPrediction = function(currentQ, gyro, timestampS) {
- if (!this.previousTimestampS) {
- this.previousQ.copy(currentQ);
- this.previousTimestampS = timestampS;
- return currentQ;
- }
- // Calculate axis and angle based on gyroscope rotation rate data.
- var axis = new MathUtil.Vector3();
- axis.copy(gyro);
- axis.normalize();
- var angularSpeed = gyro.length();
- // If we're rotating slowly, don't do prediction.
- if (angularSpeed < MathUtil.degToRad * 20) {
- if (Util.isDebug()) {
- console.log('Moving slowly, at %s deg/s: no prediction',
- (MathUtil.radToDeg * angularSpeed).toFixed(1));
- }
- this.outQ.copy(currentQ);
- this.previousQ.copy(currentQ);
- return this.outQ;
- }
- // Get the predicted angle based on the time delta and latency.
- var deltaT = timestampS - this.previousTimestampS;
- var predictAngle = angularSpeed * this.predictionTimeS;
- this.deltaQ.setFromAxisAngle(axis, predictAngle);
- this.outQ.copy(this.previousQ);
- this.outQ.multiply(this.deltaQ);
- this.previousQ.copy(currentQ);
- this.previousTimestampS = timestampS;
- return this.outQ;
- };
- module.exports = PosePredictor;
- },{"../math-util":20,"../util":29}],27:[function(_dereq_,module,exports){
- function SensorSample(sample, timestampS) {
- this.set(sample, timestampS);
- };
- SensorSample.prototype.set = function(sample, timestampS) {
- this.sample = sample;
- this.timestampS = timestampS;
- };
- SensorSample.prototype.copy = function(sensorSample) {
- this.set(sensorSample.sample, sensorSample.timestampS);
- };
- module.exports = SensorSample;
- },{}],28:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var MathUtil = _dereq_('./math-util.js');
- var Util = _dereq_('./util.js');
- var ROTATE_SPEED = 0.5;
- /**
- * Provides a quaternion responsible for pre-panning the scene before further
- * transformations due to device sensors.
- */
- function TouchPanner() {
- window.addEventListener('touchstart', this.onTouchStart_.bind(this));
- window.addEventListener('touchmove', this.onTouchMove_.bind(this));
- window.addEventListener('touchend', this.onTouchEnd_.bind(this));
- this.isTouching = false;
- this.rotateStart = new MathUtil.Vector2();
- this.rotateEnd = new MathUtil.Vector2();
- this.rotateDelta = new MathUtil.Vector2();
- this.theta = 0;
- this.orientation = new MathUtil.Quaternion();
- }
- TouchPanner.prototype.getOrientation = function() {
- this.orientation.setFromEulerXYZ(0, 0, this.theta);
- return this.orientation;
- };
- TouchPanner.prototype.resetSensor = function() {
- this.theta = 0;
- };
- TouchPanner.prototype.onTouchStart_ = function(e) {
- // Only respond if there is exactly one touch.
- // Note that the Daydream controller passes in a `touchstart` event with
- // no `touches` property, so we must check for that case too.
- if (!e.touches || e.touches.length != 1) {
- return;
- }
- this.rotateStart.set(e.touches[0].pageX, e.touches[0].pageY);
- this.isTouching = true;
- };
- TouchPanner.prototype.onTouchMove_ = function(e) {
- if (!this.isTouching) {
- return;
- }
- this.rotateEnd.set(e.touches[0].pageX, e.touches[0].pageY);
- this.rotateDelta.subVectors(this.rotateEnd, this.rotateStart);
- this.rotateStart.copy(this.rotateEnd);
- // On iOS, direction is inverted.
- if (Util.isIOS()) {
- this.rotateDelta.x *= -1;
- }
- var element = document.body;
- this.theta += 2 * Math.PI * this.rotateDelta.x / element.clientWidth * ROTATE_SPEED;
- };
- TouchPanner.prototype.onTouchEnd_ = function(e) {
- this.isTouching = false;
- };
- module.exports = TouchPanner;
- },{"./math-util.js":20,"./util.js":29}],29:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = window.Util || {};
- Util.MIN_TIMESTEP = 0.001;
- Util.MAX_TIMESTEP = 1;
- Util.base64 = function(mimeType, base64) {
- return 'data:' + mimeType + ';base64,' + base64;
- };
- Util.clamp = function(value, min, max) {
- return Math.min(Math.max(min, value), max);
- };
- Util.lerp = function(a, b, t) {
- return a + ((b - a) * t);
- };
- /**
- * Light polyfill for `Promise.race`. Returns
- * a promise that resolves when the first promise
- * provided resolves.
- *
- * @param {Array<Promise>} promises
- */
- Util.race = function(promises) {
- if (Promise.race) {
- return Promise.race(promises);
- }
- return new Promise(function (resolve, reject) {
- for (var i = 0; i < promises.length; i++) {
- promises[i].then(resolve, reject);
- }
- });
- };
- Util.isIOS = (function() {
- var isIOS = /iPad|iPhone|iPod/.test(navigator.platform);
- return function() {
- return isIOS;
- };
- })();
- Util.isWebViewAndroid = (function() {
- var isWebViewAndroid = navigator.userAgent.indexOf('Version') !== -1 &&
- navigator.userAgent.indexOf('Android') !== -1 &&
- navigator.userAgent.indexOf('Chrome') !== -1;
- return function() {
- return isWebViewAndroid;
- };
- })();
- Util.isSafari = (function() {
- var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
- return function() {
- return isSafari;
- };
- })();
- Util.isFirefoxAndroid = (function() {
- var isFirefoxAndroid = navigator.userAgent.indexOf('Firefox') !== -1 &&
- navigator.userAgent.indexOf('Android') !== -1;
- return function() {
- return isFirefoxAndroid;
- };
- })();
- Util.isR7 = (function() {
- var isR7 = navigator.userAgent.indexOf('R7 Build') !== -1;
- return function() {
- return isR7;
- };
- })();
- Util.isLandscapeMode = function() {
- var rtn = (window.orientation == 90 || window.orientation == -90);
- return Util.isR7() ? !rtn : rtn;
- };
- // Helper method to validate the time steps of sensor timestamps.
- Util.isTimestampDeltaValid = function(timestampDeltaS) {
- if (isNaN(timestampDeltaS)) {
- return false;
- }
- if (timestampDeltaS <= Util.MIN_TIMESTEP) {
- return false;
- }
- if (timestampDeltaS > Util.MAX_TIMESTEP) {
- return false;
- }
- return true;
- };
- Util.getScreenWidth = function() {
- return Math.max(window.screen.width, window.screen.height) *
- window.devicePixelRatio;
- };
- Util.getScreenHeight = function() {
- return Math.min(window.screen.width, window.screen.height) *
- window.devicePixelRatio;
- };
- Util.requestFullscreen = function(element) {
- if (Util.isWebViewAndroid()) {
- return false;
- }
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen();
- } else if (element.mozRequestFullScreen) {
- element.mozRequestFullScreen();
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- } else {
- return false;
- }
- return true;
- };
- Util.exitFullscreen = function() {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- } else {
- return false;
- }
- return true;
- };
- Util.getFullscreenElement = function() {
- return document.fullscreenElement ||
- document.webkitFullscreenElement ||
- document.mozFullScreenElement ||
- document.msFullscreenElement;
- };
- Util.linkProgram = function(gl, vertexSource, fragmentSource, attribLocationMap) {
- // No error checking for brevity.
- var vertexShader = gl.createShader(gl.VERTEX_SHADER);
- gl.shaderSource(vertexShader, vertexSource);
- gl.compileShader(vertexShader);
- var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
- gl.shaderSource(fragmentShader, fragmentSource);
- gl.compileShader(fragmentShader);
- var program = gl.createProgram();
- gl.attachShader(program, vertexShader);
- gl.attachShader(program, fragmentShader);
- for (var attribName in attribLocationMap)
- gl.bindAttribLocation(program, attribLocationMap[attribName], attribName);
- gl.linkProgram(program);
- gl.deleteShader(vertexShader);
- gl.deleteShader(fragmentShader);
- return program;
- };
- Util.getProgramUniforms = function(gl, program) {
- var uniforms = {};
- var uniformCount = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
- var uniformName = '';
- for (var i = 0; i < uniformCount; i++) {
- var uniformInfo = gl.getActiveUniform(program, i);
- uniformName = uniformInfo.name.replace('[0]', '');
- uniforms[uniformName] = gl.getUniformLocation(program, uniformName);
- }
- return uniforms;
- };
- Util.orthoMatrix = function (out, left, right, bottom, top, near, far) {
- var lr = 1 / (left - right),
- bt = 1 / (bottom - top),
- nf = 1 / (near - far);
- out[0] = -2 * lr;
- out[1] = 0;
- out[2] = 0;
- out[3] = 0;
- out[4] = 0;
- out[5] = -2 * bt;
- out[6] = 0;
- out[7] = 0;
- out[8] = 0;
- out[9] = 0;
- out[10] = 2 * nf;
- out[11] = 0;
- out[12] = (left + right) * lr;
- out[13] = (top + bottom) * bt;
- out[14] = (far + near) * nf;
- out[15] = 1;
- return out;
- };
- Util.copyArray = function (source, dest) {
- for (var i = 0, n = source.length; i < n; i++) {
- dest[i] = source[i];
- }
- };
- Util.isMobile = function() {
- var check = false;
- (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
- return check;
- };
- Util.extend = function(dest, src) {
- for (var key in src) {
- if (src.hasOwnProperty(key)) {
- dest[key] = src[key];
- }
- }
- return dest;
- }
- Util.safariCssSizeWorkaround = function(canvas) {
- // TODO(smus): Remove this workaround when Safari for iOS is fixed.
- // iOS only workaround (for https://bugs.webkit.org/show_bug.cgi?id=152556).
- //
- // "To the last I grapple with thee;
- // from hell's heart I stab at thee;
- // for hate's sake I spit my last breath at thee."
- // -- Moby Dick, by Herman Melville
- if (Util.isIOS()) {
- var width = canvas.style.width;
- var height = canvas.style.height;
- canvas.style.width = (parseInt(width) + 1) + 'px';
- canvas.style.height = (parseInt(height)) + 'px';
- setTimeout(function() {
- canvas.style.width = width;
- canvas.style.height = height;
- }, 100);
- }
- // Debug only.
- window.Util = Util;
- window.canvas = canvas;
- };
- Util.isDebug = function() {
- return Util.getQueryParameter('debug');
- };
- Util.getQueryParameter = function(name) {
- var name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
- var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
- results = regex.exec(location.search);
- return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
- };
- Util.frameDataFromPose = (function() {
- var piOver180 = Math.PI / 180.0;
- var rad45 = Math.PI * 0.25;
- // Borrowed from glMatrix.
- function mat4_perspectiveFromFieldOfView(out, fov, near, far) {
- var upTan = Math.tan(fov ? (fov.upDegrees * piOver180) : rad45),
- downTan = Math.tan(fov ? (fov.downDegrees * piOver180) : rad45),
- leftTan = Math.tan(fov ? (fov.leftDegrees * piOver180) : rad45),
- rightTan = Math.tan(fov ? (fov.rightDegrees * piOver180) : rad45),
- xScale = 2.0 / (leftTan + rightTan),
- yScale = 2.0 / (upTan + downTan);
- out[0] = xScale;
- out[1] = 0.0;
- out[2] = 0.0;
- out[3] = 0.0;
- out[4] = 0.0;
- out[5] = yScale;
- out[6] = 0.0;
- out[7] = 0.0;
- out[8] = -((leftTan - rightTan) * xScale * 0.5);
- out[9] = ((upTan - downTan) * yScale * 0.5);
- out[10] = far / (near - far);
- out[11] = -1.0;
- out[12] = 0.0;
- out[13] = 0.0;
- out[14] = (far * near) / (near - far);
- out[15] = 0.0;
- return out;
- }
- function mat4_fromRotationTranslation(out, q, v) {
- // Quaternion math
- var x = q[0], y = q[1], z = q[2], w = q[3],
- x2 = x + x,
- y2 = y + y,
- z2 = z + z,
- xx = x * x2,
- xy = x * y2,
- xz = x * z2,
- yy = y * y2,
- yz = y * z2,
- zz = z * z2,
- wx = w * x2,
- wy = w * y2,
- wz = w * z2;
- out[0] = 1 - (yy + zz);
- out[1] = xy + wz;
- out[2] = xz - wy;
- out[3] = 0;
- out[4] = xy - wz;
- out[5] = 1 - (xx + zz);
- out[6] = yz + wx;
- out[7] = 0;
- out[8] = xz + wy;
- out[9] = yz - wx;
- out[10] = 1 - (xx + yy);
- out[11] = 0;
- out[12] = v[0];
- out[13] = v[1];
- out[14] = v[2];
- out[15] = 1;
- return out;
- };
- function mat4_translate(out, a, v) {
- var x = v[0], y = v[1], z = v[2],
- a00, a01, a02, a03,
- a10, a11, a12, a13,
- a20, a21, a22, a23;
- if (a === out) {
- out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
- out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
- out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
- out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
- } else {
- a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
- a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
- a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
- out[0] = a00; out[1] = a01; out[2] = a02; out[3] = a03;
- out[4] = a10; out[5] = a11; out[6] = a12; out[7] = a13;
- out[8] = a20; out[9] = a21; out[10] = a22; out[11] = a23;
- out[12] = a00 * x + a10 * y + a20 * z + a[12];
- out[13] = a01 * x + a11 * y + a21 * z + a[13];
- out[14] = a02 * x + a12 * y + a22 * z + a[14];
- out[15] = a03 * x + a13 * y + a23 * z + a[15];
- }
- return out;
- };
- function mat4_invert(out, a) {
- var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3],
- a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7],
- a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11],
- a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15],
- b00 = a00 * a11 - a01 * a10,
- b01 = a00 * a12 - a02 * a10,
- b02 = a00 * a13 - a03 * a10,
- b03 = a01 * a12 - a02 * a11,
- b04 = a01 * a13 - a03 * a11,
- b05 = a02 * a13 - a03 * a12,
- b06 = a20 * a31 - a21 * a30,
- b07 = a20 * a32 - a22 * a30,
- b08 = a20 * a33 - a23 * a30,
- b09 = a21 * a32 - a22 * a31,
- b10 = a21 * a33 - a23 * a31,
- b11 = a22 * a33 - a23 * a32,
- // Calculate the determinant
- det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
- if (!det) {
- return null;
- }
- det = 1.0 / det;
- out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
- out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
- out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
- out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
- out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
- out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
- out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
- out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
- out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
- out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
- out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
- out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
- out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
- out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
- out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
- out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
- return out;
- };
- var defaultOrientation = new Float32Array([0, 0, 0, 1]);
- var defaultPosition = new Float32Array([0, 0, 0]);
- function updateEyeMatrices(projection, view, pose, parameters, vrDisplay) {
- mat4_perspectiveFromFieldOfView(projection, parameters ? parameters.fieldOfView : null, vrDisplay.depthNear, vrDisplay.depthFar);
- var orientation = pose.orientation || defaultOrientation;
- var position = pose.position || defaultPosition;
- mat4_fromRotationTranslation(view, orientation, position);
- if (parameters)
- mat4_translate(view, view, parameters.offset);
- mat4_invert(view, view);
- }
- return function(frameData, pose, vrDisplay) {
- if (!frameData || !pose)
- return false;
- frameData.pose = pose;
- frameData.timestamp = pose.timestamp;
- updateEyeMatrices(
- frameData.leftProjectionMatrix, frameData.leftViewMatrix,
- pose, vrDisplay.getEyeParameters("left"), vrDisplay);
- updateEyeMatrices(
- frameData.rightProjectionMatrix, frameData.rightViewMatrix,
- pose, vrDisplay.getEyeParameters("right"), vrDisplay);
- return true;
- };
- })();
- Util.isInsideCrossDomainIFrame = function() {
- var isFramed = (window.self !== window.top);
- var refDomain = Util.getDomainFromUrl(document.referrer);
- var thisDomain = Util.getDomainFromUrl(window.location.href);
- return isFramed && (refDomain !== thisDomain);
- };
- // From http://stackoverflow.com/a/23945027.
- Util.getDomainFromUrl = function(url) {
- var domain;
- // Find & remove protocol (http, ftp, etc.) and get domain.
- if (url.indexOf("://") > -1) {
- domain = url.split('/')[2];
- }
- else {
- domain = url.split('/')[0];
- }
- //find & remove port number
- domain = domain.split(':')[0];
- return domain;
- }
- module.exports = Util;
- },{}],30:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var DeviceInfo = _dereq_('./device-info.js');
- var Util = _dereq_('./util.js');
- var DEFAULT_VIEWER = 'CardboardV1';
- var VIEWER_KEY = 'WEBVR_CARDBOARD_VIEWER';
- var CLASS_NAME = 'webvr-polyfill-viewer-selector';
- /**
- * Creates a viewer selector with the options specified. Supports being shown
- * and hidden. Generates events when viewer parameters change. Also supports
- * saving the currently selected index in localStorage.
- */
- function ViewerSelector() {
- // Try to load the selected key from local storage.
- try {
- this.selectedKey = localStorage.getItem(VIEWER_KEY);
- } catch (error) {
- console.error('Failed to load viewer profile: %s', error);
- }
- //If none exists, or if localstorage is unavailable, use the default key.
- if (!this.selectedKey) {
- this.selectedKey = DEFAULT_VIEWER;
- }
- this.dialog = this.createDialog_(DeviceInfo.Viewers);
- this.root = null;
- this.onChangeCallbacks_ = [];
- }
- ViewerSelector.prototype.show = function(root) {
- this.root = root;
- root.appendChild(this.dialog);
- // Ensure the currently selected item is checked.
- var selected = this.dialog.querySelector('#' + this.selectedKey);
- selected.checked = true;
- // Show the UI.
- this.dialog.style.display = 'block';
- };
- ViewerSelector.prototype.hide = function() {
- if (this.root && this.root.contains(this.dialog)) {
- this.root.removeChild(this.dialog);
- }
- this.dialog.style.display = 'none';
- };
- ViewerSelector.prototype.getCurrentViewer = function() {
- return DeviceInfo.Viewers[this.selectedKey];
- };
- ViewerSelector.prototype.getSelectedKey_ = function() {
- var input = this.dialog.querySelector('input[name=field]:checked');
- if (input) {
- return input.id;
- }
- return null;
- };
- ViewerSelector.prototype.onChange = function(cb) {
- this.onChangeCallbacks_.push(cb);
- };
- ViewerSelector.prototype.fireOnChange_ = function(viewer) {
- for (var i = 0; i < this.onChangeCallbacks_.length; i++) {
- this.onChangeCallbacks_[i](viewer);
- }
- };
- ViewerSelector.prototype.onSave_ = function() {
- this.selectedKey = this.getSelectedKey_();
- if (!this.selectedKey || !DeviceInfo.Viewers[this.selectedKey]) {
- console.error('ViewerSelector.onSave_: this should never happen!');
- return;
- }
- this.fireOnChange_(DeviceInfo.Viewers[this.selectedKey]);
- // Attempt to save the viewer profile, but fails in private mode.
- try {
- localStorage.setItem(VIEWER_KEY, this.selectedKey);
- } catch(error) {
- console.error('Failed to save viewer profile: %s', error);
- }
- this.hide();
- };
- /**
- * Creates the dialog.
- */
- ViewerSelector.prototype.createDialog_ = function(options) {
- var container = document.createElement('div');
- container.classList.add(CLASS_NAME);
- container.style.display = 'none';
- // Create an overlay that dims the background, and which goes away when you
- // tap it.
- var overlay = document.createElement('div');
- var s = overlay.style;
- s.position = 'fixed';
- s.left = 0;
- s.top = 0;
- s.width = '100%';
- s.height = '100%';
- s.background = 'rgba(0, 0, 0, 0.3)';
- overlay.addEventListener('click', this.hide.bind(this));
- var width = 280;
- var dialog = document.createElement('div');
- var s = dialog.style;
- s.boxSizing = 'border-box';
- s.position = 'fixed';
- s.top = '24px';
- s.left = '50%';
- s.marginLeft = (-width/2) + 'px';
- s.width = width + 'px';
- s.padding = '24px';
- s.overflow = 'hidden';
- s.background = '#fafafa';
- s.fontFamily = "'Roboto', sans-serif";
- s.boxShadow = '0px 5px 20px #666';
- dialog.appendChild(this.createH1_('Select your viewer'));
- for (var id in options) {
- dialog.appendChild(this.createChoice_(id, options[id].label));
- }
- dialog.appendChild(this.createButton_('Save', this.onSave_.bind(this)));
- container.appendChild(overlay);
- container.appendChild(dialog);
- return container;
- };
- ViewerSelector.prototype.createH1_ = function(name) {
- var h1 = document.createElement('h1');
- var s = h1.style;
- s.color = 'black';
- s.fontSize = '20px';
- s.fontWeight = 'bold';
- s.marginTop = 0;
- s.marginBottom = '24px';
- h1.innerHTML = name;
- return h1;
- };
- ViewerSelector.prototype.createChoice_ = function(id, name) {
- /*
- <div class="choice">
- <input id="v1" type="radio" name="field" value="v1">
- <label for="v1">Cardboard V1</label>
- </div>
- */
- var div = document.createElement('div');
- div.style.marginTop = '8px';
- div.style.color = 'black';
- var input = document.createElement('input');
- input.style.fontSize = '30px';
- input.setAttribute('id', id);
- input.setAttribute('type', 'radio');
- input.setAttribute('value', id);
- input.setAttribute('name', 'field');
- var label = document.createElement('label');
- label.style.marginLeft = '4px';
- label.setAttribute('for', id);
- label.innerHTML = name;
- div.appendChild(input);
- div.appendChild(label);
- return div;
- };
- ViewerSelector.prototype.createButton_ = function(label, onclick) {
- var button = document.createElement('button');
- button.innerHTML = label;
- var s = button.style;
- s.float = 'right';
- s.textTransform = 'uppercase';
- s.color = '#1094f7';
- s.fontSize = '14px';
- s.letterSpacing = 0;
- s.border = 0;
- s.background = 'none';
- s.marginTop = '16px';
- button.addEventListener('click', onclick);
- return button;
- };
- module.exports = ViewerSelector;
- },{"./device-info.js":14,"./util.js":29}],31:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('./util.js');
- /**
- * Android and iOS compatible wakelock implementation.
- *
- * Refactored thanks to dkovalev@.
- */
- function AndroidWakeLock() {
- var video = document.createElement('video');
- video.setAttribute('loop', '');
- function addSourceToVideo(element, type, dataURI) {
- var source = document.createElement('source');
- source.src = dataURI;
- source.type = 'video/' + type;
- element.appendChild(source);
- }
- addSourceToVideo(video,'webm', Util.base64('video/webm', 'GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA='));
- addSourceToVideo(video, 'mp4', Util.base64('video/mp4', 'AAAAHGZ0eXBpc29tAAACAGlzb21pc28ybXA0MQAAAAhmcmVlAAAAG21kYXQAAAGzABAHAAABthADAowdbb9/AAAC6W1vb3YAAABsbXZoZAAAAAB8JbCAfCWwgAAAA+gAAAAAAAEAAAEAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAIVdHJhawAAAFx0a2hkAAAAD3wlsIB8JbCAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAIAAAACAAAAAABsW1kaWEAAAAgbWRoZAAAAAB8JbCAfCWwgAAAA+gAAAAAVcQAAAAAAC1oZGxyAAAAAAAAAAB2aWRlAAAAAAAAAAAAAAAAVmlkZW9IYW5kbGVyAAAAAVxtaW5mAAAAFHZtaGQAAAABAAAAAAAAAAAAAAAkZGluZgAAABxkcmVmAAAAAAAAAAEAAAAMdXJsIAAAAAEAAAEcc3RibAAAALhzdHNkAAAAAAAAAAEAAACobXA0dgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAIAAgASAAAAEgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABj//wAAAFJlc2RzAAAAAANEAAEABDwgEQAAAAADDUAAAAAABS0AAAGwAQAAAbWJEwAAAQAAAAEgAMSNiB9FAEQBFGMAAAGyTGF2YzUyLjg3LjQGAQIAAAAYc3R0cwAAAAAAAAABAAAAAQAAAAAAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAFHN0c3oAAAAAAAAAEwAAAAEAAAAUc3RjbwAAAAAAAAABAAAALAAAAGB1ZHRhAAAAWG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqXRvbwAAABtkYXRhAAAAAQAAAABMYXZmNTIuNzguMw=='));
- this.request = function() {
- if (video.paused) {
- video.play();
- }
- };
- this.release = function() {
- video.pause();
- };
- }
- function iOSWakeLock() {
- var timer = null;
- this.request = function() {
- if (!timer) {
- timer = setInterval(function() {
- window.location = window.location;
- setTimeout(window.stop, 0);
- }, 30000);
- }
- }
- this.release = function() {
- if (timer) {
- clearInterval(timer);
- timer = null;
- }
- }
- }
- function getWakeLock() {
- var userAgent = navigator.userAgent || navigator.vendor || window.opera;
- if (userAgent.match(/iPhone/i) || userAgent.match(/iPod/i)) {
- return iOSWakeLock;
- } else {
- return AndroidWakeLock;
- }
- }
- module.exports = getWakeLock();
- },{"./util.js":29}],32:[function(_dereq_,module,exports){
- /*
- * Copyright 2015 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('./util.js');
- var CardboardVRDisplay = _dereq_('./cardboard-vr-display.js');
- var MouseKeyboardVRDisplay = _dereq_('./mouse-keyboard-vr-display.js');
- // Uncomment to add positional tracking via webcam.
- //var WebcamPositionSensorVRDevice = require('./webcam-position-sensor-vr-device.js');
- var VRDisplay = _dereq_('./base.js').VRDisplay;
- var VRFrameData = _dereq_('./base.js').VRFrameData;
- var HMDVRDevice = _dereq_('./base.js').HMDVRDevice;
- var PositionSensorVRDevice = _dereq_('./base.js').PositionSensorVRDevice;
- var VRDisplayHMDDevice = _dereq_('./display-wrappers.js').VRDisplayHMDDevice;
- var VRDisplayPositionSensorDevice = _dereq_('./display-wrappers.js').VRDisplayPositionSensorDevice;
- var version = _dereq_('../package.json').version;
- function WebVRPolyfill() {
- this.displays = [];
- this.devices = []; // For deprecated objects
- this.devicesPopulated = false;
- this.nativeWebVRAvailable = this.isWebVRAvailable();
- this.nativeLegacyWebVRAvailable = this.isDeprecatedWebVRAvailable();
- this.nativeGetVRDisplaysFunc = this.nativeWebVRAvailable ?
- navigator.getVRDisplays :
- null;
- if (!this.nativeLegacyWebVRAvailable && !this.nativeWebVRAvailable) {
- this.enablePolyfill();
- if (window.WebVRConfig.ENABLE_DEPRECATED_API) {
- this.enableDeprecatedPolyfill();
- }
- }
- // Put a shim in place to update the API to 1.1 if needed.
- InstallWebVRSpecShim();
- }
- WebVRPolyfill.prototype.isWebVRAvailable = function() {
- return ('getVRDisplays' in navigator);
- };
- WebVRPolyfill.prototype.isDeprecatedWebVRAvailable = function() {
- return ('getVRDevices' in navigator) || ('mozGetVRDevices' in navigator);
- };
- WebVRPolyfill.prototype.connectDisplay = function(vrDisplay) {
- vrDisplay.fireVRDisplayConnect_();
- this.displays.push(vrDisplay);
- };
- WebVRPolyfill.prototype.populateDevices = function() {
- if (this.devicesPopulated) {
- return;
- }
- // Initialize our virtual VR devices.
- var vrDisplay = null;
- // Add a Cardboard VRDisplay on compatible mobile devices
- if (this.isCardboardCompatible()) {
- vrDisplay = new CardboardVRDisplay();
- this.connectDisplay(vrDisplay);
- // For backwards compatibility
- if (window.WebVRConfig.ENABLE_DEPRECATED_API) {
- this.devices.push(new VRDisplayHMDDevice(vrDisplay));
- this.devices.push(new VRDisplayPositionSensorDevice(vrDisplay));
- }
- }
- // Add a Mouse and Keyboard driven VRDisplay for desktops/laptops
- if (!this.isMobile() && !window.WebVRConfig.MOUSE_KEYBOARD_CONTROLS_DISABLED) {
- vrDisplay = new MouseKeyboardVRDisplay();
- this.connectDisplay(vrDisplay);
- // For backwards compatibility
- if (window.WebVRConfig.ENABLE_DEPRECATED_API) {
- this.devices.push(new VRDisplayHMDDevice(vrDisplay));
- this.devices.push(new VRDisplayPositionSensorDevice(vrDisplay));
- }
- }
- // Uncomment to add positional tracking via webcam.
- //if (!this.isMobile() && window.WebVRConfig.ENABLE_DEPRECATED_API) {
- // positionDevice = new WebcamPositionSensorVRDevice();
- // this.devices.push(positionDevice);
- //}
- this.devicesPopulated = true;
- };
- WebVRPolyfill.prototype.enablePolyfill = function() {
- // Provide navigator.getVRDisplays.
- navigator.getVRDisplays = this.getVRDisplays.bind(this);
- // Polyfill native VRDisplay.getFrameData
- if (this.nativeWebVRAvailable && window.VRFrameData) {
- var NativeVRFrameData = window.VRFrameData;
- var nativeFrameData = new window.VRFrameData();
- var nativeGetFrameData = window.VRDisplay.prototype.getFrameData;
- window.VRFrameData = VRFrameData;
- window.VRDisplay.prototype.getFrameData = function(frameData) {
- if (frameData instanceof NativeVRFrameData) {
- nativeGetFrameData.call(this, frameData);
- return;
- }
- /*
- Copy frame data from the native object into the polyfilled object.
- */
- nativeGetFrameData.call(this, nativeFrameData);
- frameData.pose = nativeFrameData.pose;
- Util.copyArray(nativeFrameData.leftProjectionMatrix, frameData.leftProjectionMatrix);
- Util.copyArray(nativeFrameData.rightProjectionMatrix, frameData.rightProjectionMatrix);
- Util.copyArray(nativeFrameData.leftViewMatrix, frameData.leftViewMatrix);
- Util.copyArray(nativeFrameData.rightViewMatrix, frameData.rightViewMatrix);
- //todo: copy
- };
- }
- // Provide the `VRDisplay` object.
- window.VRDisplay = VRDisplay;
- // Provide the `navigator.vrEnabled` property.
- if (navigator && typeof navigator.vrEnabled === 'undefined') {
- var self = this;
- Object.defineProperty(navigator, 'vrEnabled', {
- get: function () {
- return self.isCardboardCompatible() &&
- (self.isFullScreenAvailable() || Util.isIOS());
- }
- });
- }
- if (!('VRFrameData' in window)) {
- // Provide the VRFrameData object.
- window.VRFrameData = VRFrameData;
- }
- };
- WebVRPolyfill.prototype.enableDeprecatedPolyfill = function() {
- // Provide navigator.getVRDevices.
- navigator.getVRDevices = this.getVRDevices.bind(this);
- // Provide the CardboardHMDVRDevice and PositionSensorVRDevice objects.
- window.HMDVRDevice = HMDVRDevice;
- window.PositionSensorVRDevice = PositionSensorVRDevice;
- };
- WebVRPolyfill.prototype.getVRDisplays = function() {
- this.populateDevices();
- var polyfillDisplays = this.displays;
- if (!this.nativeWebVRAvailable) {
- return Promise.resolve(polyfillDisplays);
- }
- // Set up a race condition if this browser has a bug where
- // `navigator.getVRDisplays()` never resolves.
- var timeoutId;
- var vrDisplaysNative = this.nativeGetVRDisplaysFunc.call(navigator);
- var timeoutPromise = new Promise(function(resolve) {
- timeoutId = setTimeout(function() {
- console.warn('Native WebVR implementation detected, but `getVRDisplays()` failed to resolve. Falling back to polyfill.');
- resolve([]);
- }, window.WebVRConfig.GET_VR_DISPLAYS_TIMEOUT);
- });
- return Util.race([
- vrDisplaysNative,
- timeoutPromise
- ]).then(function(nativeDisplays) {
- clearTimeout(timeoutId);
- if (window.WebVRConfig.ALWAYS_APPEND_POLYFILL_DISPLAY) {
- return nativeDisplays.concat(polyfillDisplays);
- } else {
- return nativeDisplays.length > 0 ? nativeDisplays : polyfillDisplays;
- }
- });
- };
- WebVRPolyfill.prototype.getVRDevices = function() {
- console.warn('getVRDevices is deprecated. Please update your code to use getVRDisplays instead.');
- var self = this;
- return new Promise(function(resolve, reject) {
- try {
- if (!self.devicesPopulated) {
- if (self.nativeWebVRAvailable) {
- return navigator.getVRDisplays(function(displays) {
- for (var i = 0; i < displays.length; ++i) {
- self.devices.push(new VRDisplayHMDDevice(displays[i]));
- self.devices.push(new VRDisplayPositionSensorDevice(displays[i]));
- }
- self.devicesPopulated = true;
- resolve(self.devices);
- }, reject);
- }
- if (self.nativeLegacyWebVRAvailable) {
- return (navigator.getVRDDevices || navigator.mozGetVRDevices)(function(devices) {
- for (var i = 0; i < devices.length; ++i) {
- if (devices[i] instanceof HMDVRDevice) {
- self.devices.push(devices[i]);
- }
- if (devices[i] instanceof PositionSensorVRDevice) {
- self.devices.push(devices[i]);
- }
- }
- self.devicesPopulated = true;
- resolve(self.devices);
- }, reject);
- }
- }
- self.populateDevices();
- resolve(self.devices);
- } catch (e) {
- reject(e);
- }
- });
- };
- WebVRPolyfill.prototype.NativeVRFrameData = window.VRFrameData;
- /**
- * Determine if a device is mobile.
- */
- WebVRPolyfill.prototype.isMobile = function() {
- return /Android/i.test(navigator.userAgent) ||
- /iPhone|iPad|iPod/i.test(navigator.userAgent);
- };
- WebVRPolyfill.prototype.isCardboardCompatible = function() {
- // For now, support all iOS and Android devices.
- // Also enable the WebVRConfig.FORCE_VR flag for debugging.
- return this.isMobile() || window.WebVRConfig.FORCE_ENABLE_VR;
- };
- WebVRPolyfill.prototype.isFullScreenAvailable = function() {
- return (document.fullscreenEnabled ||
- document.mozFullScreenEnabled ||
- document.webkitFullscreenEnabled ||
- false);
- };
- // Installs a shim that updates a WebVR 1.0 spec implementation to WebVR 1.1
- function InstallWebVRSpecShim() {
- if ('VRDisplay' in window && !('VRFrameData' in window)) {
- // Provide the VRFrameData object.
- window.VRFrameData = VRFrameData;
- // A lot of Chrome builds don't have depthNear and depthFar, even
- // though they're in the WebVR 1.0 spec. Patch them in if they're not present.
- if(!('depthNear' in window.VRDisplay.prototype)) {
- window.VRDisplay.prototype.depthNear = 0.01;
- }
- if(!('depthFar' in window.VRDisplay.prototype)) {
- window.VRDisplay.prototype.depthFar = 10000.0;
- }
- window.VRDisplay.prototype.getFrameData = function(frameData) {
- return Util.frameDataFromPose(frameData, this.getPose(), this);
- }
- }
- };
- WebVRPolyfill.InstallWebVRSpecShim = InstallWebVRSpecShim;
- WebVRPolyfill.version = version;
- module.exports.WebVRPolyfill = WebVRPolyfill;
- },{"../package.json":8,"./base.js":9,"./cardboard-vr-display.js":12,"./display-wrappers.js":15,"./mouse-keyboard-vr-display.js":21,"./util.js":29}],33:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var EventEmitter = _dereq_('eventemitter3');
- var shaka = _dereq_('shaka-player');
- var Types = _dereq_('../video-type');
- var Util = _dereq_('../util');
- var DEFAULT_BITS_PER_SECOND = 1000000;
- /**
- * Supports regular video URLs (eg. mp4), as well as adaptive manifests like
- * DASH (.mpd) and soon HLS (.m3u8).
- *
- * Events:
- * load(video): When the video is loaded.
- * error(message): If an error occurs.
- *
- * To play/pause/seek/etc, please use the underlying video element.
- */
- function AdaptivePlayer(params) {
- this.video = document.createElement('video');
- // Loop by default.
- if (params.loop === true) {
- this.video.setAttribute('loop', true);
- }
- if (params.volume !== undefined) {
- // XXX: .setAttribute('volume', params.volume) doesn't work for some reason.
- this.video.volume = params.volume;
- }
- // Not muted by default.
- if (params.muted === true) {
- this.video.muted = params.muted;
- }
- // For FF, make sure we enable preload.
- this.video.setAttribute('preload', 'auto');
- // Enable inline video playback in iOS 10+.
- this.video.setAttribute('playsinline', true);
- this.video.setAttribute('crossorigin', 'anonymous');
- }
- AdaptivePlayer.prototype = new EventEmitter();
- AdaptivePlayer.prototype.load = function(url) {
- var self = this;
- // TODO(smus): Investigate whether or not differentiation is best done by
- // mimeType after all. Cursory research suggests that adaptive streaming
- // manifest mime types aren't properly supported.
- //
- // For now, make determination based on extension.
- var extension = Util.getExtension(url);
- switch (extension) {
- case 'm3u8': // HLS
- this.type = Types.HLS;
- if (Util.isSafari()) {
- this.loadVideo_(url).then(function() {
- self.emit('load', self.video, self.type);
- }).catch(this.onError_.bind(this));
- } else {
- self.onError_('HLS is only supported on Safari.');
- }
- break;
- case 'mpd': // MPEG-DASH
- this.type = Types.DASH;
- this.loadShakaVideo_(url).then(function() {
- console.log('The video has now been loaded!');
- self.emit('load', self.video, self.type);
- }).catch(this.onError_.bind(this));
- break;
- default: // A regular video, not an adaptive manifest.
- this.type = Types.VIDEO;
- this.loadVideo_(url).then(function() {
- self.emit('load', self.video, self.type);
- }).catch(this.onError_.bind(this));
- break;
- }
- };
- AdaptivePlayer.prototype.destroy = function() {
- this.video.pause();
- this.video.src = '';
- this.video = null;
- };
- /*** PRIVATE API ***/
- AdaptivePlayer.prototype.onError_ = function(e) {
- console.error(e);
- this.emit('error', e);
- };
- AdaptivePlayer.prototype.loadVideo_ = function(url) {
- var self = this, video = self.video;
- return new Promise(function(resolve, reject) {
- video.src = url;
- video.addEventListener('canplaythrough', resolve);
- video.addEventListener('loadedmetadata', function() {
- self.emit('timeupdate', {
- currentTime: video.currentTime,
- duration: video.duration
- });
- });
- video.addEventListener('error', reject);
- video.load();
- });
- };
- AdaptivePlayer.prototype.initShaka_ = function() {
- this.player = new shaka.Player(this.video);
- this.player.configure({
- abr: { defaultBandwidthEstimate: DEFAULT_BITS_PER_SECOND }
- });
- // Listen for error events.
- this.player.addEventListener('error', this.onError_);
- };
- AdaptivePlayer.prototype.loadShakaVideo_ = function(url) {
- // Install built-in polyfills to patch browser incompatibilities.
- shaka.polyfill.installAll();
- if (!shaka.Player.isBrowserSupported()) {
- console.error('Shaka is not supported on this browser.');
- return;
- }
- this.initShaka_();
- return this.player.load(url);
- };
- module.exports = AdaptivePlayer;
- },{"../util":45,"../video-type":46,"eventemitter3":3,"shaka-player":5}],34:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Eyes = {
- LEFT: 1,
- RIGHT: 2
- };
- module.exports = Eyes;
- },{}],35:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var EventEmitter = _dereq_('eventemitter3');
- var TWEEN = _dereq_('@tweenjs/tween.js');
- var Util = _dereq_('../util');
- // Constants for the focus/blur animation.
- var NORMAL_SCALE = new THREE.Vector3(1, 1, 1);
- var FOCUS_SCALE = new THREE.Vector3(1.2, 1.2, 1.2);
- var FOCUS_DURATION = 200;
- // Constants for the active/inactive animation.
- var INACTIVE_COLOR = new THREE.Color(1, 1, 1);
- var ACTIVE_COLOR = new THREE.Color(0.8, 0, 0);
- var ACTIVE_DURATION = 100;
- // Constants for opacity.
- var MAX_INNER_OPACITY = 0.8;
- var MAX_OUTER_OPACITY = 0.5;
- var FADE_START_ANGLE_DEG = 35;
- var FADE_END_ANGLE_DEG = 60;
- /**
- * Responsible for rectangular hot spots that the user can interact with.
- *
- * Specific duties:
- * Adding and removing hotspots.
- * Rendering the hotspots (debug mode only).
- * Notifying when hotspots are interacted with.
- *
- * Emits the following events:
- * click (id): a hotspot is clicked.
- * focus (id): a hotspot is focused.
- * blur (id): a hotspot is no longer hovered over.
- */
- function HotspotRenderer(worldRenderer) {
- this.worldRenderer = worldRenderer;
- this.scene = worldRenderer.scene;
- // Note: this event must be added to document.body and not to window for it to
- // work inside iOS iframes.
- var body = document.body;
- // Bind events for hotspot interaction.
- if (!Util.isMobile()) {
- // Only enable mouse events on desktop.
- body.addEventListener('mousedown', this.onMouseDown_.bind(this), false);
- body.addEventListener('mousemove', this.onMouseMove_.bind(this), false);
- body.addEventListener('mouseup', this.onMouseUp_.bind(this), false);
- }
- body.addEventListener('touchstart', this.onTouchStart_.bind(this), false);
- body.addEventListener('touchend', this.onTouchEnd_.bind(this), false);
- // Add a placeholder for hotspots.
- this.hotspotRoot = new THREE.Object3D();
- // Align the center with the center of the camera too.
- this.hotspotRoot.rotation.y = Math.PI / 2;
- this.scene.add(this.hotspotRoot);
- // All hotspot IDs.
- this.hotspots = {};
- // Currently selected hotspots.
- this.selectedHotspots = {};
- // Hotspots that the last touchstart / mousedown event happened for.
- this.downHotspots = {};
- // For raycasting. Initialize mouse to be off screen initially.
- this.pointer = new THREE.Vector2(1, 1);
- this.raycaster = new THREE.Raycaster();
- }
- HotspotRenderer.prototype = new EventEmitter();
- /**
- * @param pitch {Number} The latitude of center, specified in degrees, between
- * -90 and 90, with 0 at the horizon.
- * @param yaw {Number} The longitude of center, specified in degrees, between
- * -180 and 180, with 0 at the image center.
- * @param radius {Number} The radius of the hotspot, specified in meters.
- * @param distance {Number} The distance of the hotspot from camera, specified
- * in meters.
- * @param hotspotId {String} The ID of the hotspot.
- */
- HotspotRenderer.prototype.add = function(pitch, yaw, radius, distance, id) {
- // If a hotspot already exists with this ID, stop.
- if (this.hotspots[id]) {
- // TODO: Proper error reporting.
- console.error('Attempt to add hotspot with existing id %s.', id);
- return;
- }
- var hotspot = this.createHotspot_(radius, distance);
- hotspot.name = id;
- // Position the hotspot based on the pitch and yaw specified.
- var quat = new THREE.Quaternion();
- quat.setFromEuler(new THREE.Euler(THREE.Math.degToRad(pitch), THREE.Math.degToRad(yaw), 0, 'ZYX'));
- hotspot.position.applyQuaternion(quat);
- hotspot.lookAt(new THREE.Vector3());
- this.hotspotRoot.add(hotspot);
- this.hotspots[id] = hotspot;
- }
- /**
- * Removes a hotspot based on the ID.
- *
- * @param ID {String} Identifier of the hotspot to be removed.
- */
- HotspotRenderer.prototype.remove = function(id) {
- // If there's no hotspot with this ID, fail.
- if (!this.hotspots[id]) {
- // TODO: Proper error reporting.
- console.error('Attempt to remove non-existing hotspot with id %s.', id);
- return;
- }
- // Remove the mesh from the scene.
- this.hotspotRoot.remove(this.hotspots[id]);
- // If this hotspot was selected, make sure it gets unselected.
- delete this.selectedHotspots[id];
- delete this.downHotspots[id];
- delete this.hotspots[id];
- this.emit('blur', id);
- };
- /**
- * Clears all hotspots from the pano. Often called when changing panos.
- */
- HotspotRenderer.prototype.clearAll = function() {
- for (var id in this.hotspots) {
- this.remove(id);
- }
- };
- HotspotRenderer.prototype.getCount = function() {
- var count = 0;
- for (var id in this.hotspots) {
- count += 1;
- }
- return count;
- };
- HotspotRenderer.prototype.update = function(camera) {
- if (this.worldRenderer.isVRMode()) {
- this.pointer.set(0, 0);
- }
- // Update the picking ray with the camera and mouse position.
- this.raycaster.setFromCamera(this.pointer, camera);
- // Fade hotspots out if they are really far from center to avoid overly
- // distorted visuals.
- this.fadeOffCenterHotspots_(camera);
- var hotspots = this.hotspotRoot.children;
- // Go through all hotspots to see if they are currently selected.
- for (var i = 0; i < hotspots.length; i++) {
- var hotspot = hotspots[i];
- //hotspot.lookAt(camera.position);
- var id = hotspot.name;
- // Check if hotspot is intersected with the picking ray.
- var intersects = this.raycaster.intersectObjects(hotspot.children);
- var isIntersected = (intersects.length > 0);
- // If newly selected, emit a focus event.
- if (isIntersected && !this.selectedHotspots[id]) {
- this.emit('focus', id);
- this.focus_(id);
- }
- // If no longer selected, emit a blur event.
- if (!isIntersected && this.selectedHotspots[id]) {
- this.emit('blur', id);
- this.blur_(id);
- }
- // Update the set of selected hotspots.
- if (isIntersected) {
- this.selectedHotspots[id] = true;
- } else {
- delete this.selectedHotspots[id];
- }
- }
- };
- /**
- * Toggle whether or not hotspots are visible.
- */
- HotspotRenderer.prototype.setVisibility = function(isVisible) {
- this.hotspotRoot.visible = isVisible;
- };
- HotspotRenderer.prototype.onTouchStart_ = function(e) {
- // In VR mode, don't touch the pointer position.
- if (!this.worldRenderer.isVRMode()) {
- this.updateTouch_(e);
- }
- // Force a camera update to see if any hotspots were selected.
- this.update(this.worldRenderer.camera);
- this.downHotspots = {};
- for (var id in this.selectedHotspots) {
- this.downHotspots[id] = true;
- this.down_(id);
- }
- return false;
- };
- HotspotRenderer.prototype.onTouchEnd_ = function(e) {
- // If no hotspots are pressed, emit an empty click event.
- if (Util.isEmptyObject(this.downHotspots)) {
- this.emit('click');
- return;
- }
- // Only emit a click if the finger was down on the same hotspot before.
- for (var id in this.downHotspots) {
- this.emit('click', id);
- this.up_(id);
- e.preventDefault();
- }
- };
- HotspotRenderer.prototype.updateTouch_ = function(e) {
- var size = this.getSize_();
- var touch = e.touches[0];
- this.pointer.x = (touch.clientX / size.width) * 2 - 1;
- this.pointer.y = - (touch.clientY / size.height) * 2 + 1;
- };
- HotspotRenderer.prototype.onMouseDown_ = function(e) {
- this.updateMouse_(e);
- this.downHotspots = {};
- for (var id in this.selectedHotspots) {
- this.downHotspots[id] = true;
- this.down_(id);
- }
- };
- HotspotRenderer.prototype.onMouseMove_ = function(e) {
- this.updateMouse_(e);
- };
- HotspotRenderer.prototype.onMouseUp_ = function(e) {
- this.updateMouse_(e);
- // If no hotspots are pressed, emit an empty click event.
- if (Util.isEmptyObject(this.downHotspots)) {
- this.emit('click');
- return;
- }
- // Only emit a click if the mouse was down on the same hotspot before.
- for (var id in this.selectedHotspots) {
- if (id in this.downHotspots) {
- this.emit('click', id);
- this.up_(id);
- }
- }
- };
- HotspotRenderer.prototype.updateMouse_ = function(e) {
- var size = this.getSize_();
- this.pointer.x = (e.clientX / size.width) * 2 - 1;
- this.pointer.y = - (e.clientY / size.height) * 2 + 1;
- };
- HotspotRenderer.prototype.getSize_ = function() {
- var canvas = this.worldRenderer.renderer.domElement;
- return this.worldRenderer.renderer.getSize();
- };
- HotspotRenderer.prototype.createHotspot_ = function(radius, distance) {
- var innerGeometry = new THREE.CircleGeometry(radius, 32);
- var innerMaterial = new THREE.MeshBasicMaterial({
- color: 0xffffff, side: THREE.DoubleSide, transparent: true,
- opacity: MAX_INNER_OPACITY, depthTest: false
- });
- var inner = new THREE.Mesh(innerGeometry, innerMaterial);
- inner.name = 'inner';
- var outerMaterial = new THREE.MeshBasicMaterial({
- color: 0xffffff, side: THREE.DoubleSide, transparent: true,
- opacity: MAX_OUTER_OPACITY, depthTest: false
- });
- var outerGeometry = new THREE.RingGeometry(radius * 0.85, radius, 32);
- var outer = new THREE.Mesh(outerGeometry, outerMaterial);
- outer.name = 'outer';
- // Position at the extreme end of the sphere.
- var hotspot = new THREE.Object3D();
- hotspot.position.z = -distance;
- hotspot.scale.copy(NORMAL_SCALE);
- hotspot.add(inner);
- hotspot.add(outer);
- return hotspot;
- };
- /**
- * Large aspect ratios tend to cause visually jarring distortions on the sides.
- * Here we fade hotspots out to avoid them.
- */
- HotspotRenderer.prototype.fadeOffCenterHotspots_ = function(camera) {
- var lookAt = new THREE.Vector3(1, 0, 0);
- lookAt.applyQuaternion(camera.quaternion);
- // Take into account the camera parent too.
- lookAt.applyQuaternion(camera.parent.quaternion);
- // Go through each hotspot. Calculate how far off center it is.
- for (var id in this.hotspots) {
- var hotspot = this.hotspots[id];
- var angle = hotspot.position.angleTo(lookAt);
- var angleDeg = THREE.Math.radToDeg(angle);
- var isVisible = angleDeg < 45;
- var opacity;
- if (angleDeg < FADE_START_ANGLE_DEG) {
- opacity = 1;
- } else if (angleDeg > FADE_END_ANGLE_DEG) {
- opacity = 0;
- } else {
- // We are in the case START < angle < END. Linearly interpolate.
- var range = FADE_END_ANGLE_DEG - FADE_START_ANGLE_DEG;
- var value = FADE_END_ANGLE_DEG - angleDeg;
- opacity = value / range;
- }
- // Opacity a function of angle. If angle is large, opacity is zero. At some
- // point, ramp opacity down.
- this.setOpacity_(id, opacity);
- }
- };
- HotspotRenderer.prototype.focus_ = function(id) {
- var hotspot = this.hotspots[id];
- // Tween scale of hotspot.
- this.tween = new TWEEN.Tween(hotspot.scale).to(FOCUS_SCALE, FOCUS_DURATION)
- .easing(TWEEN.Easing.Quadratic.InOut)
- .start();
-
- if (this.worldRenderer.isVRMode()) {
- this.timeForHospotClick = setTimeout(function () {
- this.emit('click', id);
- }, 1200 )
- }
- };
- HotspotRenderer.prototype.blur_ = function(id) {
- var hotspot = this.hotspots[id];
- this.tween = new TWEEN.Tween(hotspot.scale).to(NORMAL_SCALE, FOCUS_DURATION)
- .easing(TWEEN.Easing.Quadratic.InOut)
- .start();
-
- if (this.timeForHospotClick) {
- clearTimeout( this.timeForHospotClick );
- }
- };
- HotspotRenderer.prototype.down_ = function(id) {
- // Become active.
- var hotspot = this.hotspots[id];
- var outer = hotspot.getObjectByName('inner');
- this.tween = new TWEEN.Tween(outer.material.color).to(ACTIVE_COLOR, ACTIVE_DURATION)
- .start();
- };
- HotspotRenderer.prototype.up_ = function(id) {
- // Become inactive.
- var hotspot = this.hotspots[id];
- var outer = hotspot.getObjectByName('inner');
- this.tween = new TWEEN.Tween(outer.material.color).to(INACTIVE_COLOR, ACTIVE_DURATION)
- .start();
- };
- HotspotRenderer.prototype.setOpacity_ = function(id, opacity) {
- var hotspot = this.hotspots[id];
- var outer = hotspot.getObjectByName('outer');
- var inner = hotspot.getObjectByName('inner');
- outer.material.opacity = opacity * MAX_OUTER_OPACITY;
- inner.material.opacity = opacity * MAX_INNER_OPACITY;
- };
- module.exports = HotspotRenderer;
- },{"../util":45,"@tweenjs/tween.js":1,"eventemitter3":3}],36:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var EventEmitter = _dereq_('eventemitter3');
- var Message = _dereq_('../message');
- var Util = _dereq_('../util');
- /**
- * Sits in an embedded iframe, receiving messages from a containing
- * iFrame. This facilitates an API which provides the following features:
- *
- * Playing and pausing content.
- * Adding hotspots.
- * Sending messages back to the containing iframe when hotspot is clicked
- * Sending analytics events to containing iframe.
- *
- * Note: this script used to also respond to synthetic devicemotion events, but
- * no longer does so. This is because as of iOS 9.2, Safari disallows listening
- * for devicemotion events within cross-device iframes. To work around this, the
- * webvr-polyfill responds to the postMessage event containing devicemotion
- * information (sent by the iframe-message-sender in the VR View API).
- */
- function IFrameMessageReceiver() {
- window.addEventListener('message', this.onMessage_.bind(this), false);
- }
- IFrameMessageReceiver.prototype = new EventEmitter();
- IFrameMessageReceiver.prototype.onMessage_ = function(event) {
- if (Util.isDebug()) {
- console.log('onMessage_', event);
- }
- var message = event.data;
- var type = message.type.toLowerCase();
- var data = message.data;
- switch (type) {
- case Message.SET_CONTENT:
- case Message.SET_VOLUME:
- case Message.MUTED:
- case Message.ADD_HOTSPOT:
- case Message.PLAY:
- case Message.PAUSE:
- case Message.SET_CURRENT_TIME:
- case Message.GET_POSITION:
- case Message.SET_FULLSCREEN:
- this.emit(type, data);
- break;
- default:
- if (Util.isDebug()) {
- console.warn('Got unknown message of type %s from %s', message.type, message.origin);
- }
- }
- };
- module.exports = IFrameMessageReceiver;
- },{"../message":44,"../util":45,"eventemitter3":3}],37:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /**
- * Shows a 2D loading indicator while various pieces of EmbedVR load.
- */
- function LoadingIndicator() {
- this.el = this.build_();
- document.body.appendChild(this.el);
- this.show();
- }
- LoadingIndicator.prototype.build_ = function() {
- var overlay = document.createElement('div');
- var s = overlay.style;
- s.position = 'fixed';
- s.top = 0;
- s.left = 0;
- s.width = '100%';
- s.height = '100%';
- s.background = '#eee';
- var img = document.createElement('img');
- img.src = 'images/loading.gif';
- var s = img.style;
- s.position = 'absolute';
- s.top = '50%';
- s.left = '50%';
- s.transform = 'translate(-50%, -50%)';
- overlay.appendChild(img);
- return overlay;
- };
- LoadingIndicator.prototype.hide = function() {
- this.el.style.display = 'none';
- };
- LoadingIndicator.prototype.show = function() {
- this.el.style.display = 'block';
- };
- module.exports = LoadingIndicator;
- },{}],38:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- // Initialize the loading indicator as quickly as possible to give the user
- // immediate feedback.
- var LoadingIndicator = _dereq_('./loading-indicator');
- var loadIndicator = new LoadingIndicator();
- var ES6Promise = _dereq_('es6-promise');
- // Polyfill ES6 promises for IE.
- ES6Promise.polyfill();
- var IFrameMessageReceiver = _dereq_('./iframe-message-receiver');
- var Message = _dereq_('../message');
- var SceneInfo = _dereq_('./scene-info');
- var Stats = _dereq_('../../node_modules/stats-js/build/stats.min');
- var Util = _dereq_('../util');
- var WebVRPolyfill = _dereq_('webvr-polyfill');
- var WorldRenderer = _dereq_('./world-renderer');
- var receiver = new IFrameMessageReceiver();
- receiver.on(Message.PLAY, onPlayRequest);
- receiver.on(Message.PAUSE, onPauseRequest);
- receiver.on(Message.ADD_HOTSPOT, onAddHotspot);
- receiver.on(Message.SET_CONTENT, onSetContent);
- receiver.on(Message.SET_VOLUME, onSetVolume);
- receiver.on(Message.MUTED, onMuted);
- receiver.on(Message.SET_CURRENT_TIME, onUpdateCurrentTime);
- receiver.on(Message.GET_POSITION, onGetPosition);
- receiver.on(Message.SET_FULLSCREEN, onSetFullscreen);
- window.addEventListener('load', onLoad);
- var stats = new Stats();
- var scene = SceneInfo.loadFromGetParams();
- var worldRenderer = new WorldRenderer(scene);
- worldRenderer.on('error', onRenderError);
- worldRenderer.on('load', onRenderLoad);
- worldRenderer.on('modechange', onModeChange);
- worldRenderer.on('ended', onEnded);
- worldRenderer.on('play', onPlay);
- worldRenderer.hotspotRenderer.on('click', onHotspotClick);
- window.worldRenderer = worldRenderer;
- var isReadySent = false;
- var volume = 0;
- function onLoad() {
- if (!Util.isWebGLEnabled()) {
- showError('WebGL not supported.');
- return;
- }
- // Load the scene.
- worldRenderer.setScene(scene);
- if (scene.isDebug) {
- // Show stats.
- showStats();
- }
- if (scene.isYawOnly) {
- WebVRConfig = window.WebVRConfig || {};
- WebVRConfig.YAW_ONLY = true;
- }
- requestAnimationFrame(loop);
- }
- function onVideoTap() {
- worldRenderer.videoProxy.play();
- hidePlayButton();
- // Prevent multiple play() calls on the video element.
- document.body.removeEventListener('touchend', onVideoTap);
- }
- function onRenderLoad(event) {
- if (event.videoElement) {
- var scene = SceneInfo.loadFromGetParams();
- // On mobile, tell the user they need to tap to start. Otherwise, autoplay.
- if (Util.isMobile()) {
- // Tell user to tap to start.
- showPlayButton();
- document.body.addEventListener('touchend', onVideoTap);
- } else {
- event.videoElement.play();
- }
- // Attach to pause and play events, to notify the API.
- event.videoElement.addEventListener('pause', onPause);
- event.videoElement.addEventListener('play', onPlay);
- event.videoElement.addEventListener('timeupdate', onGetCurrentTime);
- event.videoElement.addEventListener('ended', onEnded);
- }
- // Hide loading indicator.
- loadIndicator.hide();
- // Autopan only on desktop, for photos only, and only if autopan is enabled.
- if (!Util.isMobile() && !worldRenderer.sceneInfo.video && !worldRenderer.sceneInfo.isAutopanOff) {
- worldRenderer.autopan();
- }
- // Notify the API that we are ready, but only do this once.
- if (!isReadySent) {
- if (event.videoElement) {
- Util.sendParentMessage({
- type: 'ready',
- data: {
- duration: event.videoElement.duration
- }
- });
- } else {
- Util.sendParentMessage({
- type: 'ready'
- });
- }
- isReadySent = true;
- }
- }
- function onPlayRequest() {
- if (!worldRenderer.videoProxy) {
- onApiError('Attempt to pause, but no video found.');
- return;
- }
- worldRenderer.videoProxy.play();
- }
- function onPauseRequest() {
- if (!worldRenderer.videoProxy) {
- onApiError('Attempt to pause, but no video found.');
- return;
- }
- worldRenderer.videoProxy.pause();
- }
- function onAddHotspot(e) {
- if (Util.isDebug()) {
- console.log('onAddHotspot', e);
- }
- // TODO: Implement some validation?
- var pitch = parseFloat(e.pitch);
- var yaw = parseFloat(e.yaw);
- var radius = parseFloat(e.radius);
- var distance = parseFloat(e.distance);
- var id = e.id;
- worldRenderer.hotspotRenderer.add(pitch, yaw, radius, distance, id);
- }
- function onSetContent(e) {
- if (Util.isDebug()) {
- console.log('onSetContent', e);
- }
- // Remove all of the hotspots.
- worldRenderer.hotspotRenderer.clearAll();
- // Fade to black.
- worldRenderer.sphereRenderer.setOpacity(0, 500).then(function() {
- // Then load the new scene.
- var scene = SceneInfo.loadFromAPIParams(e.contentInfo);
- worldRenderer.destroy();
- // Update the URL to reflect the new scene. This is important particularily
- // on iOS where we use a fake fullscreen mode.
- var url = scene.getCurrentUrl();
- //console.log('Updating url to be %s', url);
- window.history.pushState(null, 'VR View', url);
- // And set the new scene.
- return worldRenderer.setScene(scene);
- }).then(function() {
- // Then fade the scene back in.
- worldRenderer.sphereRenderer.setOpacity(1, 500);
- });
- }
- function onSetVolume(e) {
- // Only work for video. If there's no video, send back an error.
- if (!worldRenderer.videoProxy) {
- onApiError('Attempt to set volume, but no video found.');
- return;
- }
- worldRenderer.videoProxy.setVolume(e.volumeLevel);
- volume = e.volumeLevel;
- Util.sendParentMessage({
- type: 'volumechange',
- data: e.volumeLevel
- });
- }
- function onMuted(e) {
- // Only work for video. If there's no video, send back an error.
- if (!worldRenderer.videoProxy) {
- onApiError('Attempt to mute, but no video found.');
- return;
- }
- worldRenderer.videoProxy.mute(e.muteState);
- Util.sendParentMessage({
- type: 'muted',
- data: e.muteState
- });
- }
- function onUpdateCurrentTime(time) {
- if (!worldRenderer.videoProxy) {
- onApiError('Attempt to pause, but no video found.');
- return;
- }
- worldRenderer.videoProxy.setCurrentTime(time);
- onGetCurrentTime();
- }
- function onGetCurrentTime() {
- var time = worldRenderer.videoProxy.getCurrentTime();
- Util.sendParentMessage({
- type: 'timeupdate',
- data: time
- });
- }
- function onSetFullscreen() {
- if (!worldRenderer.videoProxy) {
- onApiError('Attempt to set fullscreen, but no video found.');
- return;
- }
- worldRenderer.manager.onFSClick_();
- }
- function onApiError(message) {
- console.error(message);
- Util.sendParentMessage({
- type: 'error',
- data: {message: message}
- });
- }
- function onModeChange(mode) {
- Util.sendParentMessage({
- type: 'modechange',
- data: {mode: mode}
- });
- }
- function onHotspotClick(id) {
- Util.sendParentMessage({
- type: 'click',
- data: {id: id}
- });
- }
- function onPlay() {
- Util.sendParentMessage({
- type: 'paused',
- data: false
- });
- }
- function onPause() {
- Util.sendParentMessage({
- type: 'paused',
- data: true
- });
- }
- function onEnded() {
- Util.sendParentMessage({
- type: 'ended',
- data: true
- });
- }
- function onSceneError(message) {
- showError('Loader: ' + message);
- }
- function onRenderError(message) {
- showError('Render: ' + message);
- }
- function showError(message) {
- // Hide loading indicator.
- loadIndicator.hide();
- // Sanitize `message` as it could contain user supplied
- // values. Re-add the space character as to not modify the
- // error messages used throughout the codebase.
- message = encodeURI(message).replace(/%20/g, ' ');
- var error = document.querySelector('#error');
- error.classList.add('visible');
- error.querySelector('.message').innerHTML = message;
- error.querySelector('.title').innerHTML = 'Error';
- }
- function hideError() {
- var error = document.querySelector('#error');
- error.classList.remove('visible');
- }
- function showPlayButton() {
- var playButton = document.querySelector('#play-overlay');
- playButton.classList.add('visible');
- }
- function hidePlayButton() {
- var playButton = document.querySelector('#play-overlay');
- playButton.classList.remove('visible');
- }
- function showStats() {
- stats.setMode(0); // 0: fps, 1: ms
- // Align bottom-left.
- stats.domElement.style.position = 'absolute';
- stats.domElement.style.left = '0px';
- stats.domElement.style.bottom = '0px';
- document.body.appendChild(stats.domElement);
- }
- function loop(time) {
- // Use the VRDisplay RAF if it is present.
- if (worldRenderer.vrDisplay) {
- worldRenderer.vrDisplay.requestAnimationFrame(loop);
- } else {
- requestAnimationFrame(loop);
- }
- stats.begin();
- // Update the video if needed.
- if (worldRenderer.videoProxy) {
- worldRenderer.videoProxy.update(time);
- }
- worldRenderer.render(time);
- worldRenderer.submitFrame();
- stats.end();
- }
- function onGetPosition() {
- Util.sendParentMessage({
- type: 'getposition',
- data: {
- Yaw: worldRenderer.camera.rotation.y * 180 / Math.PI,
- Pitch: worldRenderer.camera.rotation.x * 180 / Math.PI
- }
- });
- }
- },{"../../node_modules/stats-js/build/stats.min":6,"../message":44,"../util":45,"./iframe-message-receiver":36,"./loading-indicator":37,"./scene-info":40,"./world-renderer":43,"es6-promise":2,"webvr-polyfill":22}],39:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- function ReticleRenderer(camera) {
- this.camera = camera;
- this.reticle = this.createReticle_();
- // In front of the hotspot itself, which is at r=0.99.
- this.reticle.position.z = -0.97;
- camera.add(this.reticle);
- this.setVisibility(false);
- }
- ReticleRenderer.prototype.setVisibility = function(isVisible) {
- // TODO: Tween the transition.
- this.reticle.visible = isVisible;
- };
- ReticleRenderer.prototype.createReticle_ = function() {
- // Make a torus.
- var geometry = new THREE.TorusGeometry(0.02, 0.005, 10, 20);
- var material = new THREE.MeshBasicMaterial({color: 0x000000});
- var torus = new THREE.Mesh(geometry, material);
- return torus;
- };
- module.exports = ReticleRenderer;
- },{}],40:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('../util');
- var CAMEL_TO_UNDERSCORE = {
- video: 'video',
- image: 'image',
- preview: 'preview',
- loop: 'loop',
- volume: 'volume',
- muted: 'muted',
- isStereo: 'is_stereo',
- defaultYaw: 'default_yaw',
- isYawOnly: 'is_yaw_only',
- isDebug: 'is_debug',
- isVROff: 'is_vr_off',
- isAutopanOff: 'is_autopan_off',
- hideFullscreenButton: 'hide_fullscreen_button'
- };
- /**
- * Contains all information about a given scene.
- */
- function SceneInfo(opt_params) {
- var params = opt_params || {};
- params.player = {
- loop: opt_params.loop,
- volume: opt_params.volume,
- muted: opt_params.muted
- };
- this.image = params.image !== undefined ? encodeURI(params.image) : undefined;
- this.preview = params.preview !== undefined ? encodeURI(params.preview) : undefined;
- this.video = params.video !== undefined ? encodeURI(params.video) : undefined;
- this.defaultYaw = THREE.Math.degToRad(params.defaultYaw || 0);
- this.isStereo = Util.parseBoolean(params.isStereo);
- this.isYawOnly = Util.parseBoolean(params.isYawOnly);
- this.isDebug = Util.parseBoolean(params.isDebug);
- this.isVROff = Util.parseBoolean(params.isVROff);
- this.isAutopanOff = Util.parseBoolean(params.isAutopanOff);
- this.loop = Util.parseBoolean(params.player.loop);
- this.volume = parseFloat(
- params.player.volume ? params.player.volume : '1');
- this.muted = Util.parseBoolean(params.player.muted);
- this.hideFullscreenButton = Util.parseBoolean(params.hideFullscreenButton);
- }
- SceneInfo.loadFromGetParams = function() {
- var params = {};
- for (var camelCase in CAMEL_TO_UNDERSCORE) {
- var underscore = CAMEL_TO_UNDERSCORE[camelCase];
- params[camelCase] = Util.getQueryParameter(underscore)
- || ((window.WebVRConfig && window.WebVRConfig.PLAYER) ? window.WebVRConfig.PLAYER[underscore] : "");
- }
- var scene = new SceneInfo(params);
- if (!scene.isValid()) {
- console.warn('Invalid scene: %s', scene.errorMessage);
- }
- return scene;
- };
- SceneInfo.loadFromAPIParams = function(underscoreParams) {
- var params = {};
- for (var camelCase in CAMEL_TO_UNDERSCORE) {
- var underscore = CAMEL_TO_UNDERSCORE[camelCase];
- if (underscoreParams[underscore]) {
- params[camelCase] = underscoreParams[underscore];
- }
- }
- var scene = new SceneInfo(params);
- if (!scene.isValid()) {
- console.warn('Invalid scene: %s', scene.errorMessage);
- }
- return scene;
- };
- SceneInfo.prototype.isValid = function() {
- // Either it's an image or a video.
- if (!this.image && !this.video) {
- this.errorMessage = 'Either image or video URL must be specified.';
- return false;
- }
- if (this.image && !this.isValidImage_(this.image)) {
- this.errorMessage = 'Invalid image URL: ' + this.image;
- return false;
- }
- this.errorMessage = null;
- return true;
- };
- /**
- * Generates a URL to reflect this scene.
- */
- SceneInfo.prototype.getCurrentUrl = function() {
- var url = location.protocol + '//' + location.host + location.pathname + '?';
- for (var camelCase in CAMEL_TO_UNDERSCORE) {
- var underscore = CAMEL_TO_UNDERSCORE[camelCase];
- var value = this[camelCase];
- if (value !== undefined) {
- url += underscore + '=' + value + '&';
- }
- }
- // Chop off the trailing ampersand.
- return url.substring(0, url.length - 1);
- };
- SceneInfo.prototype.isValidImage_ = function(imageUrl) {
- return true;
- };
- module.exports = SceneInfo;
- },{"../util":45}],41:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Eyes = _dereq_('./eyes');
- var TWEEN = _dereq_('@tweenjs/tween.js');
- var Util = _dereq_('../util');
- var VideoType = _dereq_('../video-type');
- function SphereRenderer(scene) {
- this.scene = scene;
- // Create a transparent mask.
- this.createOpacityMask_();
- }
- /**
- * Sets the photosphere based on the image in the source. Supports stereo and
- * mono photospheres.
- *
- * @return {Promise}
- */
- SphereRenderer.prototype.setPhotosphere = function(src, opt_params) {
- return new Promise(function(resolve, reject) {
- this.resolve = resolve;
- this.reject = reject;
- var params = opt_params || {};
- this.isStereo = !!params.isStereo;
- this.src = src;
- // Load texture.
- var loader = new THREE.TextureLoader();
- loader.crossOrigin = 'anonymous';
- loader.load(src, this.onTextureLoaded_.bind(this), undefined,
- this.onTextureError_.bind(this));
- }.bind(this));
- };
- /**
- * @return {Promise} Yeah.
- */
- SphereRenderer.prototype.set360Video = function (videoElement, videoType, opt_params) {
- return new Promise(function(resolve, reject) {
- this.resolve = resolve;
- this.reject = reject;
- var params = opt_params || {};
- this.isStereo = !!params.isStereo;
- // Load the video texture.
- var videoTexture = new THREE.VideoTexture(videoElement);
- videoTexture.minFilter = THREE.LinearFilter;
- videoTexture.magFilter = THREE.LinearFilter;
- videoTexture.generateMipmaps = false;
- if (Util.isSafari() && videoType === VideoType.HLS) {
- // fix black screen issue on safari
- videoTexture.format = THREE.RGBAFormat;
- videoTexture.flipY = false;
- } else {
- videoTexture.format = THREE.RGBFormat;
- }
- videoTexture.needsUpdate = true;
- this.onTextureLoaded_(videoTexture);
- }.bind(this));
- };
- /**
- * Set the opacity of the panorama.
- *
- * @param {Number} opacity How opaque we want the panorama to be. 0 means black,
- * 1 means full color.
- * @param {Number} duration Number of milliseconds the transition should take.
- *
- * @return {Promise} When the opacity change is complete.
- */
- SphereRenderer.prototype.setOpacity = function(opacity, duration) {
- var scene = this.scene;
- // If we want the opacity
- var overlayOpacity = 1 - opacity;
- return new Promise(function(resolve, reject) {
- var mask = scene.getObjectByName('opacityMask');
- var tween = new TWEEN.Tween({opacity: mask.material.opacity})
- .to({opacity: overlayOpacity}, duration)
- .easing(TWEEN.Easing.Quadratic.InOut);
- tween.onUpdate(function(e) {
- mask.material.opacity = this.opacity;
- });
- tween.onComplete(resolve).start();
- });
- };
- SphereRenderer.prototype.onTextureLoaded_ = function(texture) {
- var sphereLeft;
- var sphereRight;
- if (this.isStereo) {
- sphereLeft = this.createPhotosphere_(texture, {offsetY: 0.5, scaleY: 0.5});
- sphereRight = this.createPhotosphere_(texture, {offsetY: 0, scaleY: 0.5});
- } else {
- sphereLeft = this.createPhotosphere_(texture);
- sphereRight = this.createPhotosphere_(texture);
- }
- // Display in left and right eye respectively.
- sphereLeft.layers.set(Eyes.LEFT);
- sphereLeft.eye = Eyes.LEFT;
- sphereLeft.name = 'eyeLeft';
- sphereRight.layers.set(Eyes.RIGHT);
- sphereRight.eye = Eyes.RIGHT;
- sphereRight.name = 'eyeRight';
- this.scene.getObjectByName('photo').children = [sphereLeft, sphereRight];
- this.resolve();
- };
- SphereRenderer.prototype.onTextureError_ = function(error) {
- this.reject('Unable to load texture from "' + this.src + '"');
- };
- SphereRenderer.prototype.createPhotosphere_ = function(texture, opt_params) {
- var p = opt_params || {};
- p.scaleX = p.scaleX || 1;
- p.scaleY = p.scaleY || 1;
- p.offsetX = p.offsetX || 0;
- p.offsetY = p.offsetY || 0;
- p.phiStart = p.phiStart || 0;
- p.phiLength = p.phiLength || Math.PI * 2;
- p.thetaStart = p.thetaStart || 0;
- p.thetaLength = p.thetaLength || Math.PI;
- var geometry = new THREE.SphereGeometry(1, 48, 48,
- p.phiStart, p.phiLength, p.thetaStart, p.thetaLength);
- geometry.applyMatrix(new THREE.Matrix4().makeScale(-1, 1, 1));
- var uvs = geometry.faceVertexUvs[0];
- for (var i = 0; i < uvs.length; i ++) {
- for (var j = 0; j < 3; j ++) {
- uvs[i][j].x *= p.scaleX;
- uvs[i][j].x += p.offsetX;
- uvs[i][j].y *= p.scaleY;
- uvs[i][j].y += p.offsetY;
- }
- }
- var material;
- if (texture.format === THREE.RGBAFormat && texture.flipY === false) {
- material = new THREE.ShaderMaterial({
- uniforms: {
- texture: { value: texture }
- },
- vertexShader: [
- "varying vec2 vUV;",
- "void main() {",
- " vUV = vec2( uv.x, 1.0 - uv.y );",
- " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );",
- "}"
- ].join("\n"),
- fragmentShader: [
- "uniform sampler2D texture;",
- "varying vec2 vUV;",
- "void main() {",
- " gl_FragColor = texture2D( texture, vUV )" + (Util.isIOS() ? ".bgra" : "") + ";",
- "}"
- ].join("\n")
- });
- } else {
- material = new THREE.MeshBasicMaterial({ map: texture });
- }
- var out = new THREE.Mesh(geometry, material);
- //out.visible = false;
- out.renderOrder = -1;
- return out;
- };
- SphereRenderer.prototype.createOpacityMask_ = function() {
- var geometry = new THREE.SphereGeometry(0.49, 48, 48);
- var material = new THREE.MeshBasicMaterial({
- color: 0x000000, side: THREE.DoubleSide, opacity: 0, transparent: true});
- var opacityMask = new THREE.Mesh(geometry, material);
- opacityMask.name = 'opacityMask';
- opacityMask.renderOrder = 1;
- this.scene.add(opacityMask);
- return opacityMask;
- };
- module.exports = SphereRenderer;
- },{"../util":45,"../video-type":46,"./eyes":34,"@tweenjs/tween.js":1}],42:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = _dereq_('../util');
- /**
- * A proxy class for working around the fact that as soon as a video is play()ed
- * on iOS, Safari auto-fullscreens the video.
- *
- * TODO(smus): The entire raison d'etre for this class is to work around this
- * issue. Once Safari implements some way to suppress this fullscreen player, we
- * can remove this code.
- */
- function VideoProxy(videoElement) {
- this.videoElement = videoElement;
- // True if we're currently manually advancing the playhead (only on iOS).
- this.isFakePlayback = false;
- // When the video started playing.
- this.startTime = null;
- }
- VideoProxy.prototype.play = function() {
- if (Util.isIOS9OrLess()) {
- this.startTime = performance.now();
- this.isFakePlayback = true;
- // Make an audio element to playback just the audio part.
- this.audioElement = new Audio();
- this.audioElement.src = this.videoElement.src;
- this.audioElement.play();
- } else {
- this.videoElement.play().then(function(e) {
- console.log('Playing video.', e);
- });
- }
- };
- VideoProxy.prototype.pause = function() {
- if (Util.isIOS9OrLess() && this.isFakePlayback) {
- this.isFakePlayback = true;
- this.audioElement.pause();
- } else {
- this.videoElement.pause();
- }
- };
- VideoProxy.prototype.setVolume = function(volumeLevel) {
- if (this.videoElement) {
- // On iOS 10, the VideoElement.volume property is read-only. So we special
- // case muting and unmuting.
- if (Util.isIOS()) {
- this.videoElement.muted = (volumeLevel === 0);
- } else {
- this.videoElement.volume = volumeLevel;
- }
- }
- if (this.audioElement) {
- this.audioElement.volume = volumeLevel;
- }
- };
- /**
- * Set the attribute mute of the elements according with the muteState param.
- *
- * @param bool muteState
- */
- VideoProxy.prototype.mute = function(muteState) {
- if (this.videoElement) {
- this.videoElement.muted = muteState;
- }
- if (this.audioElement) {
- this.audioElement.muted = muteState;
- }
- };
- VideoProxy.prototype.getCurrentTime = function() {
- return Util.isIOS9OrLess() ? this.audioElement.currentTime : this.videoElement.currentTime;
- };
- /**
- *
- * @param {Object} time
- */
- VideoProxy.prototype.setCurrentTime = function(time) {
- if (this.videoElement) {
- this.videoElement.currentTime = time.currentTime;
- }
- if (this.audioElement) {
- this.audioElement.currentTime = time.currentTime;
- }
- };
- /**
- * Called on RAF to progress playback.
- */
- VideoProxy.prototype.update = function() {
- // Fakes playback for iOS only.
- if (!this.isFakePlayback) {
- return;
- }
- var duration = this.videoElement.duration;
- var now = performance.now();
- var delta = now - this.startTime;
- var deltaS = delta / 1000;
- this.videoElement.currentTime = deltaS;
- // Loop through the video
- if (deltaS > duration) {
- this.startTime = now;
- this.videoElement.currentTime = 0;
- // Also restart the audio.
- this.audioElement.currentTime = 0;
- }
- };
- module.exports = VideoProxy;
- },{"../util":45}],43:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var AdaptivePlayer = _dereq_('./adaptive-player');
- var EventEmitter = _dereq_('eventemitter3');
- var Eyes = _dereq_('./eyes');
- var HotspotRenderer = _dereq_('./hotspot-renderer');
- var ReticleRenderer = _dereq_('./reticle-renderer');
- var SphereRenderer = _dereq_('./sphere-renderer');
- var TWEEN = _dereq_('@tweenjs/tween.js');
- var Util = _dereq_('../util');
- var VideoProxy = _dereq_('./video-proxy');
- var WebVRManager = _dereq_('webvr-boilerplate');
- var AUTOPAN_DURATION = 3000;
- var AUTOPAN_ANGLE = 0.4;
- /**
- * The main WebGL rendering entry point. Manages the scene, camera, VR-related
- * rendering updates. Interacts with the WebVRManager.
- *
- * Coordinates the other renderers: SphereRenderer, HotspotRenderer,
- * ReticleRenderer.
- *
- * Also manages the AdaptivePlayer and VideoProxy.
- *
- * Emits the following events:
- * load: when the scene is loaded.
- * error: if there is an error loading the scene.
- * modechange(Boolean isVR): if the mode (eg. VR, fullscreen, etc) changes.
- */
- function WorldRenderer(params) {
- this.init_(params.hideFullscreenButton);
- this.sphereRenderer = new SphereRenderer(this.scene);
- this.hotspotRenderer = new HotspotRenderer(this);
- this.hotspotRenderer.on('focus', this.onHotspotFocus_.bind(this));
- this.hotspotRenderer.on('blur', this.onHotspotBlur_.bind(this));
- this.reticleRenderer = new ReticleRenderer(this.camera);
- // Get the VR Display as soon as we initialize.
- navigator.getVRDisplays().then(function(displays) {
- if (displays.length > 0) {
- this.vrDisplay = displays[0];
- }
- }.bind(this));
- }
- WorldRenderer.prototype = new EventEmitter();
- WorldRenderer.prototype.render = function(time) {
- this.controls.update();
- TWEEN.update(time);
- this.effect.render(this.scene, this.camera);
- this.hotspotRenderer.update(this.camera);
- };
- /**
- * @return {Promise} When the scene is fully loaded.
- */
- WorldRenderer.prototype.setScene = function(scene) {
- var self = this;
- var promise = new Promise(function(resolve, reject) {
- self.sceneResolve = resolve;
- self.sceneReject = reject;
- });
- if (!scene || !scene.isValid()) {
- this.didLoadFail_(scene.errorMessage);
- return;
- }
- var params = {
- isStereo: scene.isStereo,
- loop: scene.loop,
- volume: scene.volume,
- muted: scene.muted
- };
- this.setDefaultYaw_(scene.defaultYaw || 0);
- // Disable VR mode if explicitly disabled, or if we're loading a video on iOS
- // 9 or earlier.
- if (scene.isVROff || (scene.video && Util.isIOS9OrLess())) {
- this.manager.setVRCompatibleOverride(false);
- }
- // Set various callback overrides in iOS.
- if (Util.isIOS()) {
- this.manager.setFullscreenCallback(function() {
- Util.sendParentMessage({type: 'enter-fullscreen'});
- });
- this.manager.setExitFullscreenCallback(function() {
- Util.sendParentMessage({type: 'exit-fullscreen'});
- });
- this.manager.setVRCallback(function() {
- Util.sendParentMessage({type: 'enter-vr'});
- });
- }
- // If we're dealing with an image, and not a video.
- if (scene.image && !scene.video) {
- if (scene.preview) {
- // First load the preview.
- this.sphereRenderer.setPhotosphere(scene.preview, params).then(function() {
- // As soon as something is loaded, emit the load event to hide the
- // loading progress bar.
- self.didLoad_();
- // Then load the full resolution image.
- self.sphereRenderer.setPhotosphere(scene.image, params);
- }).catch(self.didLoadFail_.bind(self));
- } else {
- // No preview -- go straight to rendering the full image.
- this.sphereRenderer.setPhotosphere(scene.image, params).then(function() {
- self.didLoad_();
- }).catch(self.didLoadFail_.bind(self));
- }
- } else if (scene.video) {
- if (Util.isIE11()) {
- // On IE 11, if an 'image' param is provided, load it instead of showing
- // an error.
- //
- // TODO(smus): Once video textures are supported, remove this fallback.
- if (scene.image) {
- this.sphereRenderer.setPhotosphere(scene.image, params).then(function() {
- self.didLoad_();
- }).catch(self.didLoadFail_.bind(self));
- } else {
- this.didLoadFail_('Video is not supported on IE11.');
- }
- } else {
- this.player = new AdaptivePlayer(params);
- this.player.on('load', function(videoElement, videoType) {
- self.sphereRenderer.set360Video(videoElement, videoType, params).then(function() {
- self.didLoad_({videoElement: videoElement});
- }).catch(self.didLoadFail_.bind(self));
- });
- this.player.on('error', function(error) {
- self.didLoadFail_('Video load error: ' + error);
- });
- this.player.load(scene.video);
- this.videoProxy = new VideoProxy(this.player.video);
- }
- }
- this.sceneInfo = scene;
- if (Util.isDebug()) {
- console.log('Loaded scene', scene);
- }
- return promise;
- };
- WorldRenderer.prototype.isVRMode = function() {
- return !!this.vrDisplay && this.vrDisplay.isPresenting;
- };
- WorldRenderer.prototype.submitFrame = function() {
- if (this.isVRMode()) {
- this.vrDisplay.submitFrame();
- }
- };
- WorldRenderer.prototype.disposeEye_ = function(eye) {
- if (eye) {
- if (eye.material.map) {
- eye.material.map.dispose();
- }
- eye.material.dispose();
- eye.geometry.dispose();
- }
- };
- WorldRenderer.prototype.dispose = function() {
- var eyeLeft = this.scene.getObjectByName('eyeLeft');
- this.disposeEye_(eyeLeft);
- var eyeRight = this.scene.getObjectByName('eyeRight');
- this.disposeEye_(eyeRight);
- };
- WorldRenderer.prototype.destroy = function() {
- if (this.player) {
- this.player.removeAllListeners();
- this.player.destroy();
- this.player = null;
- }
- var photo = this.scene.getObjectByName('photo');
- var eyeLeft = this.scene.getObjectByName('eyeLeft');
- var eyeRight = this.scene.getObjectByName('eyeRight');
- if (eyeLeft) {
- this.disposeEye_(eyeLeft);
- photo.remove(eyeLeft);
- this.scene.remove(eyeLeft);
- }
- if (eyeRight) {
- this.disposeEye_(eyeRight);
- photo.remove(eyeRight);
- this.scene.remove(eyeRight);
- }
- };
- WorldRenderer.prototype.didLoad_ = function(opt_event) {
- var event = opt_event || {};
- this.emit('load', event);
- if (this.sceneResolve) {
- this.sceneResolve();
- }
- };
- WorldRenderer.prototype.didLoadFail_ = function(message) {
- this.emit('error', message);
- if (this.sceneReject) {
- this.sceneReject(message);
- }
- };
- /**
- * Sets the default yaw.
- * @param {Number} angleRad The yaw in radians.
- */
- WorldRenderer.prototype.setDefaultYaw_ = function(angleRad) {
- // Rotate the camera parent to take into account the scene's rotation.
- // By default, it should be at the center of the image.
- var display = this.controls.getVRDisplay();
- // For desktop, we subtract the current display Y axis
- var theta = display.theta_ || 0;
- // For devices with orientation we make the current view center
- if (display.poseSensor_) {
- display.poseSensor_.resetPose();
- }
- this.camera.parent.rotation.y = (Math.PI / 2.0) + angleRad - theta;
- };
- /**
- * Do the initial camera tween to rotate the camera, giving an indication that
- * there is live content there (on desktop only).
- */
- WorldRenderer.prototype.autopan = function(duration) {
- var targetY = this.camera.parent.rotation.y - AUTOPAN_ANGLE;
- var tween = new TWEEN.Tween(this.camera.parent.rotation)
- .to({y: targetY}, AUTOPAN_DURATION)
- .easing(TWEEN.Easing.Quadratic.Out)
- .start();
- };
- WorldRenderer.prototype.init_ = function(hideFullscreenButton) {
- var container = document.querySelector('body');
- var aspect = window.innerWidth / window.innerHeight;
- var camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 100);
- camera.layers.enable(1);
- var cameraDummy = new THREE.Object3D();
- cameraDummy.add(camera);
- // Antialiasing disabled to improve performance.
- var renderer = new THREE.WebGLRenderer({antialias: false});
- renderer.setClearColor(0x000000, 0);
- renderer.setSize(window.innerWidth, window.innerHeight);
- renderer.setPixelRatio(window.devicePixelRatio);
- container.appendChild(renderer.domElement);
- var controls = new THREE.VRControls(camera);
- var effect = new THREE.VREffect(renderer);
- // Disable eye separation.
- effect.scale = 0;
- effect.setSize(window.innerWidth, window.innerHeight);
- // Present submission of frames automatically. This is done manually in
- // submitFrame().
- effect.autoSubmitFrame = false;
- this.camera = camera;
- this.renderer = renderer;
- this.effect = effect;
- this.controls = controls;
- this.manager = new WebVRManager(renderer, effect, {predistorted: false, hideButton: hideFullscreenButton});
- this.scene = this.createScene_();
- this.scene.add(this.camera.parent);
- // Watch the resize event.
- window.addEventListener('resize', this.onResize_.bind(this));
- // Prevent context menu.
- window.addEventListener('contextmenu', this.onContextMenu_.bind(this));
- window.addEventListener('vrdisplaypresentchange',
- this.onVRDisplayPresentChange_.bind(this));
- };
- WorldRenderer.prototype.onResize_ = function() {
- this.effect.setSize(window.innerWidth, window.innerHeight);
- this.camera.aspect = window.innerWidth / window.innerHeight;
- this.camera.updateProjectionMatrix();
- };
- WorldRenderer.prototype.onVRDisplayPresentChange_ = function(e) {
- if (Util.isDebug()) {
- console.log('onVRDisplayPresentChange_');
- }
- var isVR = this.isVRMode();
- // If the mode changed to VR and there is at least one hotspot, show reticle.
- var isReticleVisible = isVR && this.hotspotRenderer.getCount() > 0;
- this.reticleRenderer.setVisibility(isReticleVisible);
- // Resize the renderer for good measure.
- this.onResize_();
- // Analytics.
- if (window.analytics) {
- analytics.logModeChanged(isVR);
- }
- // When exiting VR mode from iOS, make sure we emit back an exit-fullscreen event.
- if (!isVR && Util.isIOS()) {
- Util.sendParentMessage({type: 'exit-fullscreen'});
- }
- // Emit a mode change event back to any listeners.
- this.emit('modechange', isVR);
- };
- WorldRenderer.prototype.createScene_ = function(opt_params) {
- var scene = new THREE.Scene();
- // Add a group for the photosphere.
- var photoGroup = new THREE.Object3D();
- photoGroup.name = 'photo';
- scene.add(photoGroup);
- return scene;
- };
- WorldRenderer.prototype.onHotspotFocus_ = function(id) {
- // Set the default cursor to be a pointer.
- this.setCursor_('pointer');
- };
- WorldRenderer.prototype.onHotspotBlur_ = function(id) {
- // Reset the default cursor to be the default one.
- this.setCursor_('');
- };
- WorldRenderer.prototype.setCursor_ = function(cursor) {
- this.renderer.domElement.style.cursor = cursor;
- };
- WorldRenderer.prototype.onContextMenu_ = function(e) {
- e.preventDefault();
- e.stopPropagation();
- return false;
- };
- module.exports = WorldRenderer;
- },{"../util":45,"./adaptive-player":33,"./eyes":34,"./hotspot-renderer":35,"./reticle-renderer":39,"./sphere-renderer":41,"./video-proxy":42,"@tweenjs/tween.js":1,"eventemitter3":3,"webvr-boilerplate":7}],44:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /**
- * Messages from the API to the embed.
- */
- var Message = {
- PLAY: 'play',
- PAUSE: 'pause',
- TIMEUPDATE: 'timeupdate',
- ADD_HOTSPOT: 'addhotspot',
- SET_CONTENT: 'setimage',
- SET_VOLUME: 'setvolume',
- MUTED: 'muted',
- SET_CURRENT_TIME: 'setcurrenttime',
- DEVICE_MOTION: 'devicemotion',
- GET_POSITION: 'getposition',
- SET_FULLSCREEN: 'setfullscreen',
- };
- module.exports = Message;
- },{}],45:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var Util = window.Util || {};
- Util.isDataURI = function(src) {
- return src && src.indexOf('data:') == 0;
- };
- Util.generateUUID = function() {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- }
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
- s4() + '-' + s4() + s4() + s4();
- };
- Util.isMobile = function() {
- var check = false;
- (function(a){if(/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
- return check;
- };
- Util.isIOS = function() {
- return /(iPad|iPhone|iPod)/g.test(navigator.userAgent);
- };
- Util.isSafari = function() {
- return /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
- };
- Util.cloneObject = function(obj) {
- var out = {};
- for (key in obj) {
- out[key] = obj[key];
- }
- return out;
- };
- Util.hashCode = function(s) {
- return s.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0);
- };
- Util.loadTrackSrc = function(context, src, callback, opt_progressCallback) {
- var request = new XMLHttpRequest();
- request.open('GET', src, true);
- request.responseType = 'arraybuffer';
- // Decode asynchronously.
- request.onload = function() {
- context.decodeAudioData(request.response, function(buffer) {
- callback(buffer);
- }, function(e) {
- console.error(e);
- });
- };
- if (opt_progressCallback) {
- request.onprogress = function(e) {
- var percent = e.loaded / e.total;
- opt_progressCallback(percent);
- };
- }
- request.send();
- };
- Util.isPow2 = function(n) {
- return (n & (n - 1)) == 0;
- };
- Util.capitalize = function(s) {
- return s.charAt(0).toUpperCase() + s.slice(1);
- };
- Util.isIFrame = function() {
- try {
- return window.self !== window.top;
- } catch (e) {
- return true;
- }
- };
- // From http://goo.gl/4WX3tg
- Util.getQueryParameter = function(name) {
- name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
- var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
- results = regex.exec(location.search);
- return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
- };
- // From http://stackoverflow.com/questions/11871077/proper-way-to-detect-webgl-support.
- Util.isWebGLEnabled = function() {
- var canvas = document.createElement('canvas');
- try { gl = canvas.getContext("webgl"); }
- catch (x) { gl = null; }
- if (gl == null) {
- try { gl = canvas.getContext("experimental-webgl"); experimental = true; }
- catch (x) { gl = null; }
- }
- return !!gl;
- };
- Util.clone = function(obj) {
- return JSON.parse(JSON.stringify(obj));
- };
- // From http://stackoverflow.com/questions/10140604/fastest-hypotenuse-in-javascript
- Util.hypot = Math.hypot || function(x, y) {
- return Math.sqrt(x*x + y*y);
- };
- // From http://stackoverflow.com/a/17447718/693934
- Util.isIE11 = function() {
- return navigator.userAgent.match(/Trident/);
- };
- Util.getRectCenter = function(rect) {
- return new THREE.Vector2(rect.x + rect.width/2, rect.y + rect.height/2);
- };
- Util.getScreenWidth = function() {
- return Math.max(window.screen.width, window.screen.height) *
- window.devicePixelRatio;
- };
- Util.getScreenHeight = function() {
- return Math.min(window.screen.width, window.screen.height) *
- window.devicePixelRatio;
- };
- Util.isIOS9OrLess = function() {
- if (!Util.isIOS()) {
- return false;
- }
- var re = /(iPhone|iPad|iPod) OS ([\d_]+)/;
- var iOSVersion = navigator.userAgent.match(re);
- if (!iOSVersion) {
- return false;
- }
- // Get the last group.
- var versionString = iOSVersion[iOSVersion.length - 1];
- var majorVersion = parseFloat(versionString);
- return majorVersion <= 9;
- };
- Util.getExtension = function(url) {
- return url.split('.').pop().split('?')[0];
- };
- Util.createGetParams = function(params) {
- var out = '?';
- for (var k in params) {
- var paramString = k + '=' + params[k] + '&';
- out += paramString;
- }
- // Remove the trailing ampersand.
- out.substring(0, params.length - 2);
- return out;
- };
- Util.sendParentMessage = function(message) {
- if (window.parent) {
- parent.postMessage(message, '*');
- }
- };
- Util.parseBoolean = function(value) {
- if (value == 'false' || value == 0) {
- return false;
- } else if (value == 'true' || value == 1) {
- return true;
- } else {
- return !!value;
- }
- };
- /**
- * @param base {String} An absolute directory root.
- * @param relative {String} A relative path.
- *
- * @returns {String} An absolute path corresponding to the rootPath.
- *
- * From http://stackoverflow.com/a/14780463/693934.
- */
- Util.relativeToAbsolutePath = function(base, relative) {
- var stack = base.split('/');
- var parts = relative.split('/');
- for (var i = 0; i < parts.length; i++) {
- if (parts[i] == '.') {
- continue;
- }
- if (parts[i] == '..') {
- stack.pop();
- } else {
- stack.push(parts[i]);
- }
- }
- return stack.join('/');
- };
- /**
- * @return {Boolean} True iff the specified path is an absolute path.
- */
- Util.isPathAbsolute = function(path) {
- return ! /^(?:\/|[a-z]+:\/\/)/.test(path);
- }
- Util.isEmptyObject = function(obj) {
- return Object.getOwnPropertyNames(obj).length == 0;
- };
- Util.isDebug = function() {
- return Util.parseBoolean(Util.getQueryParameter('debug'));
- };
- Util.getCurrentScript = function() {
- // Note: in IE11, document.currentScript doesn't work, so we fall back to this
- // hack, taken from https://goo.gl/TpExuH.
- if (!document.currentScript) {
- console.warn('This browser does not support document.currentScript. Trying fallback.');
- }
- return document.currentScript || document.scripts[document.scripts.length - 1];
- }
- module.exports = Util;
- },{}],46:[function(_dereq_,module,exports){
- /*
- * Copyright 2016 Google Inc. All Rights Reserved.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- /**
- * Video Types
- */
- var VideoTypes = {
- HLS: 1,
- DASH: 2,
- VIDEO: 3
- };
- module.exports = VideoTypes;
- },{}]},{},[38]);
|