router.js 250 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116
  1. /**
  2. * @license Angular v8.1.0
  3. * (c) 2010-2019 Google LLC. https://angular.io/
  4. * License: MIT
  5. */
  6. import { LocationStrategy, Location, PlatformLocation, APP_BASE_HREF, ViewportScroller, HashLocationStrategy, PathLocationStrategy, LOCATION_INITIALIZED } from '@angular/common';
  7. import { Component, ɵisObservable, ɵisPromise, NgModuleRef, InjectionToken, NgModuleFactory, ɵConsole, NgZone, isDevMode, Directive, Attribute, Renderer2, ElementRef, Input, HostListener, HostBinding, Optional, ContentChildren, EventEmitter, ViewContainerRef, ComponentFactoryResolver, ChangeDetectorRef, Output, Injectable, NgModuleFactoryLoader, Compiler, Injector, ApplicationRef, SystemJsNgModuleLoader, NgProbeToken, ANALYZE_FOR_ENTRY_COMPONENTS, SkipSelf, Inject, APP_INITIALIZER, APP_BOOTSTRAP_LISTENER, NgModule, Version } from '@angular/core';
  8. import { of, from, BehaviorSubject, EmptyError, Observable, combineLatest, defer, Subject, EMPTY } from 'rxjs';
  9. import { map, concatAll, last as last$1, catchError, first, mergeMap, every, switchMap, take, startWith, scan, filter, concatMap, reduce, tap, finalize, mergeAll } from 'rxjs/operators';
  10. import { ɵgetDOM } from '@angular/platform-browser';
  11. /**
  12. * @fileoverview added by tsickle
  13. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  14. */
  15. /**
  16. * @license
  17. * Copyright Google Inc. All Rights Reserved.
  18. *
  19. * Use of this source code is governed by an MIT-style license that can be
  20. * found in the LICENSE file at https://angular.io/license
  21. */
  22. /**
  23. * \@description
  24. *
  25. * Base for events the Router goes through, as opposed to events tied to a specific
  26. * Route. `RouterEvent`s will only be fired one time for any given navigation.
  27. *
  28. * Example:
  29. *
  30. * ```
  31. * class MyService {
  32. * constructor(public router: Router, logger: Logger) {
  33. * router.events.pipe(
  34. * filter(e => e instanceof RouterEvent)
  35. * ).subscribe(e => {
  36. * logger.log(e.id, e.url);
  37. * });
  38. * }
  39. * }
  40. * ```
  41. *
  42. * \@publicApi
  43. */
  44. class RouterEvent {
  45. /**
  46. * @param {?} id
  47. * @param {?} url
  48. */
  49. constructor(id, url) {
  50. this.id = id;
  51. this.url = url;
  52. }
  53. }
  54. /**
  55. * \@description
  56. *
  57. * Represents an event triggered when a navigation starts.
  58. *
  59. * \@publicApi
  60. */
  61. class NavigationStart extends RouterEvent {
  62. /**
  63. * @param {?} id
  64. * @param {?} url
  65. * @param {?=} navigationTrigger
  66. * @param {?=} restoredState
  67. */
  68. constructor(
  69. /** @docsNotRequired */
  70. id,
  71. /** @docsNotRequired */
  72. url,
  73. /** @docsNotRequired */
  74. navigationTrigger = 'imperative',
  75. /** @docsNotRequired */
  76. restoredState = null) {
  77. super(id, url);
  78. this.navigationTrigger = navigationTrigger;
  79. this.restoredState = restoredState;
  80. }
  81. /**
  82. * \@docsNotRequired
  83. * @return {?}
  84. */
  85. toString() { return `NavigationStart(id: ${this.id}, url: '${this.url}')`; }
  86. }
  87. /**
  88. * \@description
  89. *
  90. * Represents an event triggered when a navigation ends successfully.
  91. *
  92. * \@publicApi
  93. */
  94. class NavigationEnd extends RouterEvent {
  95. /**
  96. * @param {?} id
  97. * @param {?} url
  98. * @param {?} urlAfterRedirects
  99. */
  100. constructor(
  101. /** @docsNotRequired */
  102. id,
  103. /** @docsNotRequired */
  104. url, urlAfterRedirects) {
  105. super(id, url);
  106. this.urlAfterRedirects = urlAfterRedirects;
  107. }
  108. /**
  109. * \@docsNotRequired
  110. * @return {?}
  111. */
  112. toString() {
  113. return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
  114. }
  115. }
  116. /**
  117. * \@description
  118. *
  119. * Represents an event triggered when a navigation is canceled.
  120. *
  121. * \@publicApi
  122. */
  123. class NavigationCancel extends RouterEvent {
  124. /**
  125. * @param {?} id
  126. * @param {?} url
  127. * @param {?} reason
  128. */
  129. constructor(
  130. /** @docsNotRequired */
  131. id,
  132. /** @docsNotRequired */
  133. url, reason) {
  134. super(id, url);
  135. this.reason = reason;
  136. }
  137. /**
  138. * \@docsNotRequired
  139. * @return {?}
  140. */
  141. toString() { return `NavigationCancel(id: ${this.id}, url: '${this.url}')`; }
  142. }
  143. /**
  144. * \@description
  145. *
  146. * Represents an event triggered when a navigation fails due to an unexpected error.
  147. *
  148. * \@publicApi
  149. */
  150. class NavigationError extends RouterEvent {
  151. /**
  152. * @param {?} id
  153. * @param {?} url
  154. * @param {?} error
  155. */
  156. constructor(
  157. /** @docsNotRequired */
  158. id,
  159. /** @docsNotRequired */
  160. url, error) {
  161. super(id, url);
  162. this.error = error;
  163. }
  164. /**
  165. * \@docsNotRequired
  166. * @return {?}
  167. */
  168. toString() {
  169. return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
  170. }
  171. }
  172. /**
  173. * \@description
  174. *
  175. * Represents an event triggered when routes are recognized.
  176. *
  177. * \@publicApi
  178. */
  179. class RoutesRecognized extends RouterEvent {
  180. /**
  181. * @param {?} id
  182. * @param {?} url
  183. * @param {?} urlAfterRedirects
  184. * @param {?} state
  185. */
  186. constructor(
  187. /** @docsNotRequired */
  188. id,
  189. /** @docsNotRequired */
  190. url, urlAfterRedirects, state) {
  191. super(id, url);
  192. this.urlAfterRedirects = urlAfterRedirects;
  193. this.state = state;
  194. }
  195. /**
  196. * \@docsNotRequired
  197. * @return {?}
  198. */
  199. toString() {
  200. return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  201. }
  202. }
  203. /**
  204. * \@description
  205. *
  206. * Represents the start of the Guard phase of routing.
  207. *
  208. * \@publicApi
  209. */
  210. class GuardsCheckStart extends RouterEvent {
  211. /**
  212. * @param {?} id
  213. * @param {?} url
  214. * @param {?} urlAfterRedirects
  215. * @param {?} state
  216. */
  217. constructor(
  218. /** @docsNotRequired */
  219. id,
  220. /** @docsNotRequired */
  221. url, urlAfterRedirects, state) {
  222. super(id, url);
  223. this.urlAfterRedirects = urlAfterRedirects;
  224. this.state = state;
  225. }
  226. /**
  227. * @return {?}
  228. */
  229. toString() {
  230. return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  231. }
  232. }
  233. /**
  234. * \@description
  235. *
  236. * Represents the end of the Guard phase of routing.
  237. *
  238. * \@publicApi
  239. */
  240. class GuardsCheckEnd extends RouterEvent {
  241. /**
  242. * @param {?} id
  243. * @param {?} url
  244. * @param {?} urlAfterRedirects
  245. * @param {?} state
  246. * @param {?} shouldActivate
  247. */
  248. constructor(
  249. /** @docsNotRequired */
  250. id,
  251. /** @docsNotRequired */
  252. url, urlAfterRedirects, state, shouldActivate) {
  253. super(id, url);
  254. this.urlAfterRedirects = urlAfterRedirects;
  255. this.state = state;
  256. this.shouldActivate = shouldActivate;
  257. }
  258. /**
  259. * @return {?}
  260. */
  261. toString() {
  262. return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
  263. }
  264. }
  265. /**
  266. * \@description
  267. *
  268. * Represents the start of the Resolve phase of routing. The timing of this
  269. * event may change, thus it's experimental. In the current iteration it will run
  270. * in the "resolve" phase whether there's things to resolve or not. In the future this
  271. * behavior may change to only run when there are things to be resolved.
  272. *
  273. * \@publicApi
  274. */
  275. class ResolveStart extends RouterEvent {
  276. /**
  277. * @param {?} id
  278. * @param {?} url
  279. * @param {?} urlAfterRedirects
  280. * @param {?} state
  281. */
  282. constructor(
  283. /** @docsNotRequired */
  284. id,
  285. /** @docsNotRequired */
  286. url, urlAfterRedirects, state) {
  287. super(id, url);
  288. this.urlAfterRedirects = urlAfterRedirects;
  289. this.state = state;
  290. }
  291. /**
  292. * @return {?}
  293. */
  294. toString() {
  295. return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  296. }
  297. }
  298. /**
  299. * \@description
  300. *
  301. * Represents the end of the Resolve phase of routing. See note on
  302. * `ResolveStart` for use of this experimental API.
  303. *
  304. * \@publicApi
  305. */
  306. class ResolveEnd extends RouterEvent {
  307. /**
  308. * @param {?} id
  309. * @param {?} url
  310. * @param {?} urlAfterRedirects
  311. * @param {?} state
  312. */
  313. constructor(
  314. /** @docsNotRequired */
  315. id,
  316. /** @docsNotRequired */
  317. url, urlAfterRedirects, state) {
  318. super(id, url);
  319. this.urlAfterRedirects = urlAfterRedirects;
  320. this.state = state;
  321. }
  322. /**
  323. * @return {?}
  324. */
  325. toString() {
  326. return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  327. }
  328. }
  329. /**
  330. * \@description
  331. *
  332. * Represents an event triggered before lazy loading a route config.
  333. *
  334. * \@publicApi
  335. */
  336. class RouteConfigLoadStart {
  337. /**
  338. * @param {?} route
  339. */
  340. constructor(route) {
  341. this.route = route;
  342. }
  343. /**
  344. * @return {?}
  345. */
  346. toString() { return `RouteConfigLoadStart(path: ${this.route.path})`; }
  347. }
  348. /**
  349. * \@description
  350. *
  351. * Represents an event triggered when a route has been lazy loaded.
  352. *
  353. * \@publicApi
  354. */
  355. class RouteConfigLoadEnd {
  356. /**
  357. * @param {?} route
  358. */
  359. constructor(route) {
  360. this.route = route;
  361. }
  362. /**
  363. * @return {?}
  364. */
  365. toString() { return `RouteConfigLoadEnd(path: ${this.route.path})`; }
  366. }
  367. /**
  368. * \@description
  369. *
  370. * Represents the start of end of the Resolve phase of routing. See note on
  371. * `ChildActivationEnd` for use of this experimental API.
  372. *
  373. * \@publicApi
  374. */
  375. class ChildActivationStart {
  376. /**
  377. * @param {?} snapshot
  378. */
  379. constructor(snapshot) {
  380. this.snapshot = snapshot;
  381. }
  382. /**
  383. * @return {?}
  384. */
  385. toString() {
  386. /** @type {?} */
  387. const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  388. return `ChildActivationStart(path: '${path}')`;
  389. }
  390. }
  391. /**
  392. * \@description
  393. *
  394. * Represents the start of end of the Resolve phase of routing. See note on
  395. * `ChildActivationStart` for use of this experimental API.
  396. *
  397. * \@publicApi
  398. */
  399. class ChildActivationEnd {
  400. /**
  401. * @param {?} snapshot
  402. */
  403. constructor(snapshot) {
  404. this.snapshot = snapshot;
  405. }
  406. /**
  407. * @return {?}
  408. */
  409. toString() {
  410. /** @type {?} */
  411. const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  412. return `ChildActivationEnd(path: '${path}')`;
  413. }
  414. }
  415. /**
  416. * \@description
  417. *
  418. * Represents the start of end of the Resolve phase of routing. See note on
  419. * `ActivationEnd` for use of this experimental API.
  420. *
  421. * \@publicApi
  422. */
  423. class ActivationStart {
  424. /**
  425. * @param {?} snapshot
  426. */
  427. constructor(snapshot) {
  428. this.snapshot = snapshot;
  429. }
  430. /**
  431. * @return {?}
  432. */
  433. toString() {
  434. /** @type {?} */
  435. const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  436. return `ActivationStart(path: '${path}')`;
  437. }
  438. }
  439. /**
  440. * \@description
  441. *
  442. * Represents the start of end of the Resolve phase of routing. See note on
  443. * `ActivationStart` for use of this experimental API.
  444. *
  445. * \@publicApi
  446. */
  447. class ActivationEnd {
  448. /**
  449. * @param {?} snapshot
  450. */
  451. constructor(snapshot) {
  452. this.snapshot = snapshot;
  453. }
  454. /**
  455. * @return {?}
  456. */
  457. toString() {
  458. /** @type {?} */
  459. const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
  460. return `ActivationEnd(path: '${path}')`;
  461. }
  462. }
  463. /**
  464. * \@description
  465. *
  466. * Represents a scrolling event.
  467. *
  468. * \@publicApi
  469. */
  470. class Scroll {
  471. /**
  472. * @param {?} routerEvent
  473. * @param {?} position
  474. * @param {?} anchor
  475. */
  476. constructor(routerEvent, position, anchor) {
  477. this.routerEvent = routerEvent;
  478. this.position = position;
  479. this.anchor = anchor;
  480. }
  481. /**
  482. * @return {?}
  483. */
  484. toString() {
  485. /** @type {?} */
  486. const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
  487. return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
  488. }
  489. }
  490. /**
  491. * @fileoverview added by tsickle
  492. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  493. */
  494. /**
  495. * This component is used internally within the router to be a placeholder when an empty
  496. * router-outlet is needed. For example, with a config such as:
  497. *
  498. * `{path: 'parent', outlet: 'nav', children: [...]}`
  499. *
  500. * In order to render, there needs to be a component on this config, which will default
  501. * to this `EmptyOutletComponent`.
  502. */
  503. class ɵEmptyOutletComponent {
  504. }
  505. ɵEmptyOutletComponent.decorators = [
  506. { type: Component, args: [{ template: `<router-outlet></router-outlet>` }] }
  507. ];
  508. /**
  509. * @fileoverview added by tsickle
  510. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  511. */
  512. /**
  513. * @license
  514. * Copyright Google Inc. All Rights Reserved.
  515. *
  516. * Use of this source code is governed by an MIT-style license that can be
  517. * found in the LICENSE file at https://angular.io/license
  518. */
  519. /**
  520. * \@description
  521. *
  522. * Name of the primary outlet.
  523. *
  524. * \@publicApi
  525. * @type {?}
  526. */
  527. const PRIMARY_OUTLET = 'primary';
  528. class ParamsAsMap {
  529. /**
  530. * @param {?} params
  531. */
  532. constructor(params) { this.params = params || {}; }
  533. /**
  534. * @param {?} name
  535. * @return {?}
  536. */
  537. has(name) { return this.params.hasOwnProperty(name); }
  538. /**
  539. * @param {?} name
  540. * @return {?}
  541. */
  542. get(name) {
  543. if (this.has(name)) {
  544. /** @type {?} */
  545. const v = this.params[name];
  546. return Array.isArray(v) ? v[0] : v;
  547. }
  548. return null;
  549. }
  550. /**
  551. * @param {?} name
  552. * @return {?}
  553. */
  554. getAll(name) {
  555. if (this.has(name)) {
  556. /** @type {?} */
  557. const v = this.params[name];
  558. return Array.isArray(v) ? v : [v];
  559. }
  560. return [];
  561. }
  562. /**
  563. * @return {?}
  564. */
  565. get keys() { return Object.keys(this.params); }
  566. }
  567. /**
  568. * Convert a `Params` instance to a `ParamMap`.
  569. *
  570. * \@publicApi
  571. * @param {?} params
  572. * @return {?}
  573. */
  574. function convertToParamMap(params) {
  575. return new ParamsAsMap(params);
  576. }
  577. /** @type {?} */
  578. const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
  579. /**
  580. * @param {?} message
  581. * @return {?}
  582. */
  583. function navigationCancelingError(message) {
  584. /** @type {?} */
  585. const error = Error('NavigationCancelingError: ' + message);
  586. ((/** @type {?} */ (error)))[NAVIGATION_CANCELING_ERROR] = true;
  587. return error;
  588. }
  589. /**
  590. * @param {?} error
  591. * @return {?}
  592. */
  593. function isNavigationCancelingError(error) {
  594. return error && ((/** @type {?} */ (error)))[NAVIGATION_CANCELING_ERROR];
  595. }
  596. // Matches the route configuration (`route`) against the actual URL (`segments`).
  597. /**
  598. * @param {?} segments
  599. * @param {?} segmentGroup
  600. * @param {?} route
  601. * @return {?}
  602. */
  603. function defaultUrlMatcher(segments, segmentGroup, route) {
  604. /** @type {?} */
  605. const parts = (/** @type {?} */ (route.path)).split('/');
  606. if (parts.length > segments.length) {
  607. // The actual URL is shorter than the config, no match
  608. return null;
  609. }
  610. if (route.pathMatch === 'full' &&
  611. (segmentGroup.hasChildren() || parts.length < segments.length)) {
  612. // The config is longer than the actual URL but we are looking for a full match, return null
  613. return null;
  614. }
  615. /** @type {?} */
  616. const posParams = {};
  617. // Check each config part against the actual URL
  618. for (let index = 0; index < parts.length; index++) {
  619. /** @type {?} */
  620. const part = parts[index];
  621. /** @type {?} */
  622. const segment = segments[index];
  623. /** @type {?} */
  624. const isParameter = part.startsWith(':');
  625. if (isParameter) {
  626. posParams[part.substring(1)] = segment;
  627. }
  628. else if (part !== segment.path) {
  629. // The actual URL part does not match the config, no match
  630. return null;
  631. }
  632. }
  633. return { consumed: segments.slice(0, parts.length), posParams };
  634. }
  635. /**
  636. * @fileoverview added by tsickle
  637. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  638. */
  639. class LoadedRouterConfig {
  640. /**
  641. * @param {?} routes
  642. * @param {?} module
  643. */
  644. constructor(routes, module) {
  645. this.routes = routes;
  646. this.module = module;
  647. }
  648. }
  649. /**
  650. * @param {?} config
  651. * @param {?=} parentPath
  652. * @return {?}
  653. */
  654. function validateConfig(config, parentPath = '') {
  655. // forEach doesn't iterate undefined values
  656. for (let i = 0; i < config.length; i++) {
  657. /** @type {?} */
  658. const route = config[i];
  659. /** @type {?} */
  660. const fullPath = getFullPath(parentPath, route);
  661. validateNode(route, fullPath);
  662. }
  663. }
  664. /**
  665. * @param {?} route
  666. * @param {?} fullPath
  667. * @return {?}
  668. */
  669. function validateNode(route, fullPath) {
  670. if (!route) {
  671. throw new Error(`
  672. Invalid configuration of route '${fullPath}': Encountered undefined route.
  673. The reason might be an extra comma.
  674. Example:
  675. const routes: Routes = [
  676. { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
  677. { path: 'dashboard', component: DashboardComponent },, << two commas
  678. { path: 'detail/:id', component: HeroDetailComponent }
  679. ];
  680. `);
  681. }
  682. if (Array.isArray(route)) {
  683. throw new Error(`Invalid configuration of route '${fullPath}': Array cannot be specified`);
  684. }
  685. if (!route.component && !route.children && !route.loadChildren &&
  686. (route.outlet && route.outlet !== PRIMARY_OUTLET)) {
  687. throw new Error(`Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
  688. }
  689. if (route.redirectTo && route.children) {
  690. throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
  691. }
  692. if (route.redirectTo && route.loadChildren) {
  693. throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
  694. }
  695. if (route.children && route.loadChildren) {
  696. throw new Error(`Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
  697. }
  698. if (route.redirectTo && route.component) {
  699. throw new Error(`Invalid configuration of route '${fullPath}': redirectTo and component cannot be used together`);
  700. }
  701. if (route.path && route.matcher) {
  702. throw new Error(`Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
  703. }
  704. if (route.redirectTo === void 0 && !route.component && !route.children && !route.loadChildren) {
  705. throw new Error(`Invalid configuration of route '${fullPath}'. One of the following must be provided: component, redirectTo, children or loadChildren`);
  706. }
  707. if (route.path === void 0 && route.matcher === void 0) {
  708. throw new Error(`Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
  709. }
  710. if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
  711. throw new Error(`Invalid configuration of route '${fullPath}': path cannot start with a slash`);
  712. }
  713. if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
  714. /** @type {?} */
  715. const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
  716. throw new Error(`Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
  717. }
  718. if (route.pathMatch !== void 0 && route.pathMatch !== 'full' && route.pathMatch !== 'prefix') {
  719. throw new Error(`Invalid configuration of route '${fullPath}': pathMatch can only be set to 'prefix' or 'full'`);
  720. }
  721. if (route.children) {
  722. validateConfig(route.children, fullPath);
  723. }
  724. }
  725. /**
  726. * @param {?} parentPath
  727. * @param {?} currentRoute
  728. * @return {?}
  729. */
  730. function getFullPath(parentPath, currentRoute) {
  731. if (!currentRoute) {
  732. return parentPath;
  733. }
  734. if (!parentPath && !currentRoute.path) {
  735. return '';
  736. }
  737. else if (parentPath && !currentRoute.path) {
  738. return `${parentPath}/`;
  739. }
  740. else if (!parentPath && currentRoute.path) {
  741. return currentRoute.path;
  742. }
  743. else {
  744. return `${parentPath}/${currentRoute.path}`;
  745. }
  746. }
  747. /**
  748. * Makes a copy of the config and adds any default required properties.
  749. * @param {?} r
  750. * @return {?}
  751. */
  752. function standardizeConfig(r) {
  753. /** @type {?} */
  754. const children = r.children && r.children.map(standardizeConfig);
  755. /** @type {?} */
  756. const c = children ? Object.assign({}, r, { children }) : Object.assign({}, r);
  757. if (!c.component && (children || c.loadChildren) && (c.outlet && c.outlet !== PRIMARY_OUTLET)) {
  758. c.component = ɵEmptyOutletComponent;
  759. }
  760. return c;
  761. }
  762. /**
  763. * @fileoverview added by tsickle
  764. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  765. */
  766. /**
  767. * @param {?} a
  768. * @param {?} b
  769. * @return {?}
  770. */
  771. function shallowEqualArrays(a, b) {
  772. if (a.length !== b.length)
  773. return false;
  774. for (let i = 0; i < a.length; ++i) {
  775. if (!shallowEqual(a[i], b[i]))
  776. return false;
  777. }
  778. return true;
  779. }
  780. /**
  781. * @param {?} a
  782. * @param {?} b
  783. * @return {?}
  784. */
  785. function shallowEqual(a, b) {
  786. // Casting Object.keys return values to include `undefined` as there are some cases
  787. // in IE 11 where this can happen. Cannot provide a test because the behavior only
  788. // exists in certain circumstances in IE 11, therefore doing this cast ensures the
  789. // logic is correct for when this edge case is hit.
  790. /** @type {?} */
  791. const k1 = (/** @type {?} */ (Object.keys(a)));
  792. /** @type {?} */
  793. const k2 = (/** @type {?} */ (Object.keys(b)));
  794. if (!k1 || !k2 || k1.length != k2.length) {
  795. return false;
  796. }
  797. /** @type {?} */
  798. let key;
  799. for (let i = 0; i < k1.length; i++) {
  800. key = k1[i];
  801. if (a[key] !== b[key]) {
  802. return false;
  803. }
  804. }
  805. return true;
  806. }
  807. /**
  808. * Flattens single-level nested arrays.
  809. * @template T
  810. * @param {?} arr
  811. * @return {?}
  812. */
  813. function flatten(arr) {
  814. return Array.prototype.concat.apply([], arr);
  815. }
  816. /**
  817. * Return the last element of an array.
  818. * @template T
  819. * @param {?} a
  820. * @return {?}
  821. */
  822. function last(a) {
  823. return a.length > 0 ? a[a.length - 1] : null;
  824. }
  825. /**
  826. * @template K, V
  827. * @param {?} map
  828. * @param {?} callback
  829. * @return {?}
  830. */
  831. function forEach(map, callback) {
  832. for (const prop in map) {
  833. if (map.hasOwnProperty(prop)) {
  834. callback(map[prop], prop);
  835. }
  836. }
  837. }
  838. /**
  839. * @template A, B
  840. * @param {?} obj
  841. * @param {?} fn
  842. * @return {?}
  843. */
  844. function waitForMap(obj, fn) {
  845. if (Object.keys(obj).length === 0) {
  846. return of({});
  847. }
  848. /** @type {?} */
  849. const waitHead = [];
  850. /** @type {?} */
  851. const waitTail = [];
  852. /** @type {?} */
  853. const res = {};
  854. forEach(obj, (/**
  855. * @param {?} a
  856. * @param {?} k
  857. * @return {?}
  858. */
  859. (a, k) => {
  860. /** @type {?} */
  861. const mapped = fn(k, a).pipe(map((/**
  862. * @param {?} r
  863. * @return {?}
  864. */
  865. (r) => res[k] = r)));
  866. if (k === PRIMARY_OUTLET) {
  867. waitHead.push(mapped);
  868. }
  869. else {
  870. waitTail.push(mapped);
  871. }
  872. }));
  873. // Closure compiler has problem with using spread operator here. So just using Array.concat.
  874. return of.apply(null, waitHead.concat(waitTail)).pipe(concatAll(), last$1(), map((/**
  875. * @return {?}
  876. */
  877. () => res)));
  878. }
  879. /**
  880. * @template T
  881. * @param {?} value
  882. * @return {?}
  883. */
  884. function wrapIntoObservable(value) {
  885. if (ɵisObservable(value)) {
  886. return value;
  887. }
  888. if (ɵisPromise(value)) {
  889. // Use `Promise.resolve()` to wrap promise-like instances.
  890. // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
  891. // change detection.
  892. return from(Promise.resolve(value));
  893. }
  894. return of(value);
  895. }
  896. /**
  897. * @fileoverview added by tsickle
  898. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  899. */
  900. /**
  901. * @return {?}
  902. */
  903. function createEmptyUrlTree() {
  904. return new UrlTree(new UrlSegmentGroup([], {}), {}, null);
  905. }
  906. /**
  907. * @param {?} container
  908. * @param {?} containee
  909. * @param {?} exact
  910. * @return {?}
  911. */
  912. function containsTree(container, containee, exact) {
  913. if (exact) {
  914. return equalQueryParams(container.queryParams, containee.queryParams) &&
  915. equalSegmentGroups(container.root, containee.root);
  916. }
  917. return containsQueryParams(container.queryParams, containee.queryParams) &&
  918. containsSegmentGroup(container.root, containee.root);
  919. }
  920. /**
  921. * @param {?} container
  922. * @param {?} containee
  923. * @return {?}
  924. */
  925. function equalQueryParams(container, containee) {
  926. // TODO: This does not handle array params correctly.
  927. return shallowEqual(container, containee);
  928. }
  929. /**
  930. * @param {?} container
  931. * @param {?} containee
  932. * @return {?}
  933. */
  934. function equalSegmentGroups(container, containee) {
  935. if (!equalPath(container.segments, containee.segments))
  936. return false;
  937. if (container.numberOfChildren !== containee.numberOfChildren)
  938. return false;
  939. for (const c in containee.children) {
  940. if (!container.children[c])
  941. return false;
  942. if (!equalSegmentGroups(container.children[c], containee.children[c]))
  943. return false;
  944. }
  945. return true;
  946. }
  947. /**
  948. * @param {?} container
  949. * @param {?} containee
  950. * @return {?}
  951. */
  952. function containsQueryParams(container, containee) {
  953. // TODO: This does not handle array params correctly.
  954. return Object.keys(containee).length <= Object.keys(container).length &&
  955. Object.keys(containee).every((/**
  956. * @param {?} key
  957. * @return {?}
  958. */
  959. key => containee[key] === container[key]));
  960. }
  961. /**
  962. * @param {?} container
  963. * @param {?} containee
  964. * @return {?}
  965. */
  966. function containsSegmentGroup(container, containee) {
  967. return containsSegmentGroupHelper(container, containee, containee.segments);
  968. }
  969. /**
  970. * @param {?} container
  971. * @param {?} containee
  972. * @param {?} containeePaths
  973. * @return {?}
  974. */
  975. function containsSegmentGroupHelper(container, containee, containeePaths) {
  976. if (container.segments.length > containeePaths.length) {
  977. /** @type {?} */
  978. const current = container.segments.slice(0, containeePaths.length);
  979. if (!equalPath(current, containeePaths))
  980. return false;
  981. if (containee.hasChildren())
  982. return false;
  983. return true;
  984. }
  985. else if (container.segments.length === containeePaths.length) {
  986. if (!equalPath(container.segments, containeePaths))
  987. return false;
  988. for (const c in containee.children) {
  989. if (!container.children[c])
  990. return false;
  991. if (!containsSegmentGroup(container.children[c], containee.children[c]))
  992. return false;
  993. }
  994. return true;
  995. }
  996. else {
  997. /** @type {?} */
  998. const current = containeePaths.slice(0, container.segments.length);
  999. /** @type {?} */
  1000. const next = containeePaths.slice(container.segments.length);
  1001. if (!equalPath(container.segments, current))
  1002. return false;
  1003. if (!container.children[PRIMARY_OUTLET])
  1004. return false;
  1005. return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next);
  1006. }
  1007. }
  1008. /**
  1009. * \@description
  1010. *
  1011. * Represents the parsed URL.
  1012. *
  1013. * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
  1014. * serialized tree.
  1015. * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
  1016. *
  1017. * \@usageNotes
  1018. * ### Example
  1019. *
  1020. * ```
  1021. * \@Component({templateUrl:'template.html'})
  1022. * class MyComponent {
  1023. * constructor(router: Router) {
  1024. * const tree: UrlTree =
  1025. * router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
  1026. * const f = tree.fragment; // return 'fragment'
  1027. * const q = tree.queryParams; // returns {debug: 'true'}
  1028. * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
  1029. * const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
  1030. * g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
  1031. * g.children['support'].segments; // return 1 segment 'help'
  1032. * }
  1033. * }
  1034. * ```
  1035. *
  1036. * \@publicApi
  1037. */
  1038. class UrlTree {
  1039. /**
  1040. * \@internal
  1041. * @param {?} root
  1042. * @param {?} queryParams
  1043. * @param {?} fragment
  1044. */
  1045. constructor(root, queryParams, fragment) {
  1046. this.root = root;
  1047. this.queryParams = queryParams;
  1048. this.fragment = fragment;
  1049. }
  1050. /**
  1051. * @return {?}
  1052. */
  1053. get queryParamMap() {
  1054. if (!this._queryParamMap) {
  1055. this._queryParamMap = convertToParamMap(this.queryParams);
  1056. }
  1057. return this._queryParamMap;
  1058. }
  1059. /**
  1060. * \@docsNotRequired
  1061. * @return {?}
  1062. */
  1063. toString() { return DEFAULT_SERIALIZER.serialize(this); }
  1064. }
  1065. /**
  1066. * \@description
  1067. *
  1068. * Represents the parsed URL segment group.
  1069. *
  1070. * See `UrlTree` for more information.
  1071. *
  1072. * \@publicApi
  1073. */
  1074. class UrlSegmentGroup {
  1075. /**
  1076. * @param {?} segments
  1077. * @param {?} children
  1078. */
  1079. constructor(segments, children) {
  1080. this.segments = segments;
  1081. this.children = children;
  1082. /**
  1083. * The parent node in the url tree
  1084. */
  1085. this.parent = null;
  1086. forEach(children, (/**
  1087. * @template THIS
  1088. * @this {THIS}
  1089. * @param {?} v
  1090. * @param {?} k
  1091. * @return {THIS}
  1092. */
  1093. (v, k) => v.parent = this));
  1094. }
  1095. /**
  1096. * Whether the segment has child segments
  1097. * @return {?}
  1098. */
  1099. hasChildren() { return this.numberOfChildren > 0; }
  1100. /**
  1101. * Number of child segments
  1102. * @return {?}
  1103. */
  1104. get numberOfChildren() { return Object.keys(this.children).length; }
  1105. /**
  1106. * \@docsNotRequired
  1107. * @return {?}
  1108. */
  1109. toString() { return serializePaths(this); }
  1110. }
  1111. /**
  1112. * \@description
  1113. *
  1114. * Represents a single URL segment.
  1115. *
  1116. * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
  1117. * parameters associated with the segment.
  1118. *
  1119. * \@usageNotes
  1120. *  ### Example
  1121. *
  1122. * ```
  1123. * \@Component({templateUrl:'template.html'})
  1124. * class MyComponent {
  1125. * constructor(router: Router) {
  1126. * const tree: UrlTree = router.parseUrl('/team;id=33');
  1127. * const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
  1128. * const s: UrlSegment[] = g.segments;
  1129. * s[0].path; // returns 'team'
  1130. * s[0].parameters; // returns {id: 33}
  1131. * }
  1132. * }
  1133. * ```
  1134. *
  1135. * \@publicApi
  1136. */
  1137. class UrlSegment {
  1138. /**
  1139. * @param {?} path
  1140. * @param {?} parameters
  1141. */
  1142. constructor(path, parameters) {
  1143. this.path = path;
  1144. this.parameters = parameters;
  1145. }
  1146. /**
  1147. * @return {?}
  1148. */
  1149. get parameterMap() {
  1150. if (!this._parameterMap) {
  1151. this._parameterMap = convertToParamMap(this.parameters);
  1152. }
  1153. return this._parameterMap;
  1154. }
  1155. /**
  1156. * \@docsNotRequired
  1157. * @return {?}
  1158. */
  1159. toString() { return serializePath(this); }
  1160. }
  1161. /**
  1162. * @param {?} as
  1163. * @param {?} bs
  1164. * @return {?}
  1165. */
  1166. function equalSegments(as, bs) {
  1167. return equalPath(as, bs) && as.every((/**
  1168. * @param {?} a
  1169. * @param {?} i
  1170. * @return {?}
  1171. */
  1172. (a, i) => shallowEqual(a.parameters, bs[i].parameters)));
  1173. }
  1174. /**
  1175. * @param {?} as
  1176. * @param {?} bs
  1177. * @return {?}
  1178. */
  1179. function equalPath(as, bs) {
  1180. if (as.length !== bs.length)
  1181. return false;
  1182. return as.every((/**
  1183. * @param {?} a
  1184. * @param {?} i
  1185. * @return {?}
  1186. */
  1187. (a, i) => a.path === bs[i].path));
  1188. }
  1189. /**
  1190. * @template T
  1191. * @param {?} segment
  1192. * @param {?} fn
  1193. * @return {?}
  1194. */
  1195. function mapChildrenIntoArray(segment, fn) {
  1196. /** @type {?} */
  1197. let res = [];
  1198. forEach(segment.children, (/**
  1199. * @param {?} child
  1200. * @param {?} childOutlet
  1201. * @return {?}
  1202. */
  1203. (child, childOutlet) => {
  1204. if (childOutlet === PRIMARY_OUTLET) {
  1205. res = res.concat(fn(child, childOutlet));
  1206. }
  1207. }));
  1208. forEach(segment.children, (/**
  1209. * @param {?} child
  1210. * @param {?} childOutlet
  1211. * @return {?}
  1212. */
  1213. (child, childOutlet) => {
  1214. if (childOutlet !== PRIMARY_OUTLET) {
  1215. res = res.concat(fn(child, childOutlet));
  1216. }
  1217. }));
  1218. return res;
  1219. }
  1220. /**
  1221. * \@description
  1222. *
  1223. * Serializes and deserializes a URL string into a URL tree.
  1224. *
  1225. * The url serialization strategy is customizable. You can
  1226. * make all URLs case insensitive by providing a custom UrlSerializer.
  1227. *
  1228. * See `DefaultUrlSerializer` for an example of a URL serializer.
  1229. *
  1230. * \@publicApi
  1231. * @abstract
  1232. */
  1233. class UrlSerializer {
  1234. }
  1235. /**
  1236. * \@description
  1237. *
  1238. * A default implementation of the `UrlSerializer`.
  1239. *
  1240. * Example URLs:
  1241. *
  1242. * ```
  1243. * /inbox/33(popup:compose)
  1244. * /inbox/33;open=true/messages/44
  1245. * ```
  1246. *
  1247. * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
  1248. * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
  1249. * specify route specific parameters.
  1250. *
  1251. * \@publicApi
  1252. */
  1253. class DefaultUrlSerializer {
  1254. /**
  1255. * Parses a url into a `UrlTree`
  1256. * @param {?} url
  1257. * @return {?}
  1258. */
  1259. parse(url) {
  1260. /** @type {?} */
  1261. const p = new UrlParser(url);
  1262. return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
  1263. }
  1264. /**
  1265. * Converts a `UrlTree` into a url
  1266. * @param {?} tree
  1267. * @return {?}
  1268. */
  1269. serialize(tree) {
  1270. /** @type {?} */
  1271. const segment = `/${serializeSegment(tree.root, true)}`;
  1272. /** @type {?} */
  1273. const query = serializeQueryParams(tree.queryParams);
  1274. /** @type {?} */
  1275. const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment((/** @type {?} */ (tree.fragment)))}` : '';
  1276. return `${segment}${query}${fragment}`;
  1277. }
  1278. }
  1279. /** @type {?} */
  1280. const DEFAULT_SERIALIZER = new DefaultUrlSerializer();
  1281. /**
  1282. * @param {?} segment
  1283. * @return {?}
  1284. */
  1285. function serializePaths(segment) {
  1286. return segment.segments.map((/**
  1287. * @param {?} p
  1288. * @return {?}
  1289. */
  1290. p => serializePath(p))).join('/');
  1291. }
  1292. /**
  1293. * @param {?} segment
  1294. * @param {?} root
  1295. * @return {?}
  1296. */
  1297. function serializeSegment(segment, root) {
  1298. if (!segment.hasChildren()) {
  1299. return serializePaths(segment);
  1300. }
  1301. if (root) {
  1302. /** @type {?} */
  1303. const primary = segment.children[PRIMARY_OUTLET] ?
  1304. serializeSegment(segment.children[PRIMARY_OUTLET], false) :
  1305. '';
  1306. /** @type {?} */
  1307. const children = [];
  1308. forEach(segment.children, (/**
  1309. * @param {?} v
  1310. * @param {?} k
  1311. * @return {?}
  1312. */
  1313. (v, k) => {
  1314. if (k !== PRIMARY_OUTLET) {
  1315. children.push(`${k}:${serializeSegment(v, false)}`);
  1316. }
  1317. }));
  1318. return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
  1319. }
  1320. else {
  1321. /** @type {?} */
  1322. const children = mapChildrenIntoArray(segment, (/**
  1323. * @param {?} v
  1324. * @param {?} k
  1325. * @return {?}
  1326. */
  1327. (v, k) => {
  1328. if (k === PRIMARY_OUTLET) {
  1329. return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
  1330. }
  1331. return [`${k}:${serializeSegment(v, false)}`];
  1332. }));
  1333. return `${serializePaths(segment)}/(${children.join('//')})`;
  1334. }
  1335. }
  1336. /**
  1337. * Encodes a URI string with the default encoding. This function will only ever be called from
  1338. * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
  1339. * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
  1340. * have to be encoded per https://url.spec.whatwg.org.
  1341. * @param {?} s
  1342. * @return {?}
  1343. */
  1344. function encodeUriString(s) {
  1345. return encodeURIComponent(s)
  1346. .replace(/%40/g, '@')
  1347. .replace(/%3A/gi, ':')
  1348. .replace(/%24/g, '$')
  1349. .replace(/%2C/gi, ',');
  1350. }
  1351. /**
  1352. * This function should be used to encode both keys and values in a query string key/value. In
  1353. * the following URL, you need to call encodeUriQuery on "k" and "v":
  1354. *
  1355. * http://www.site.org/html;mk=mv?k=v#f
  1356. * @param {?} s
  1357. * @return {?}
  1358. */
  1359. function encodeUriQuery(s) {
  1360. return encodeUriString(s).replace(/%3B/gi, ';');
  1361. }
  1362. /**
  1363. * This function should be used to encode a URL fragment. In the following URL, you need to call
  1364. * encodeUriFragment on "f":
  1365. *
  1366. * http://www.site.org/html;mk=mv?k=v#f
  1367. * @param {?} s
  1368. * @return {?}
  1369. */
  1370. function encodeUriFragment(s) {
  1371. return encodeURI(s);
  1372. }
  1373. /**
  1374. * This function should be run on any URI segment as well as the key and value in a key/value
  1375. * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
  1376. * "mk", and "mv":
  1377. *
  1378. * http://www.site.org/html;mk=mv?k=v#f
  1379. * @param {?} s
  1380. * @return {?}
  1381. */
  1382. function encodeUriSegment(s) {
  1383. return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
  1384. }
  1385. /**
  1386. * @param {?} s
  1387. * @return {?}
  1388. */
  1389. function decode(s) {
  1390. return decodeURIComponent(s);
  1391. }
  1392. // Query keys/values should have the "+" replaced first, as "+" in a query string is " ".
  1393. // decodeURIComponent function will not decode "+" as a space.
  1394. /**
  1395. * @param {?} s
  1396. * @return {?}
  1397. */
  1398. function decodeQuery(s) {
  1399. return decode(s.replace(/\+/g, '%20'));
  1400. }
  1401. /**
  1402. * @param {?} path
  1403. * @return {?}
  1404. */
  1405. function serializePath(path) {
  1406. return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
  1407. }
  1408. /**
  1409. * @param {?} params
  1410. * @return {?}
  1411. */
  1412. function serializeMatrixParams(params) {
  1413. return Object.keys(params)
  1414. .map((/**
  1415. * @param {?} key
  1416. * @return {?}
  1417. */
  1418. key => `;${encodeUriSegment(key)}=${encodeUriSegment(params[key])}`))
  1419. .join('');
  1420. }
  1421. /**
  1422. * @param {?} params
  1423. * @return {?}
  1424. */
  1425. function serializeQueryParams(params) {
  1426. /** @type {?} */
  1427. const strParams = Object.keys(params).map((/**
  1428. * @param {?} name
  1429. * @return {?}
  1430. */
  1431. (name) => {
  1432. /** @type {?} */
  1433. const value = params[name];
  1434. return Array.isArray(value) ?
  1435. value.map((/**
  1436. * @param {?} v
  1437. * @return {?}
  1438. */
  1439. v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`)).join('&') :
  1440. `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
  1441. }));
  1442. return strParams.length ? `?${strParams.join("&")}` : '';
  1443. }
  1444. /** @type {?} */
  1445. const SEGMENT_RE = /^[^\/()?;=#]+/;
  1446. /**
  1447. * @param {?} str
  1448. * @return {?}
  1449. */
  1450. function matchSegments(str) {
  1451. /** @type {?} */
  1452. const match = str.match(SEGMENT_RE);
  1453. return match ? match[0] : '';
  1454. }
  1455. /** @type {?} */
  1456. const QUERY_PARAM_RE = /^[^=?&#]+/;
  1457. // Return the name of the query param at the start of the string or an empty string
  1458. /**
  1459. * @param {?} str
  1460. * @return {?}
  1461. */
  1462. function matchQueryParams(str) {
  1463. /** @type {?} */
  1464. const match = str.match(QUERY_PARAM_RE);
  1465. return match ? match[0] : '';
  1466. }
  1467. /** @type {?} */
  1468. const QUERY_PARAM_VALUE_RE = /^[^?&#]+/;
  1469. // Return the value of the query param at the start of the string or an empty string
  1470. /**
  1471. * @param {?} str
  1472. * @return {?}
  1473. */
  1474. function matchUrlQueryParamValue(str) {
  1475. /** @type {?} */
  1476. const match = str.match(QUERY_PARAM_VALUE_RE);
  1477. return match ? match[0] : '';
  1478. }
  1479. class UrlParser {
  1480. /**
  1481. * @param {?} url
  1482. */
  1483. constructor(url) {
  1484. this.url = url;
  1485. this.remaining = url;
  1486. }
  1487. /**
  1488. * @return {?}
  1489. */
  1490. parseRootSegment() {
  1491. this.consumeOptional('/');
  1492. if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
  1493. return new UrlSegmentGroup([], {});
  1494. }
  1495. // The root segment group never has segments
  1496. return new UrlSegmentGroup([], this.parseChildren());
  1497. }
  1498. /**
  1499. * @return {?}
  1500. */
  1501. parseQueryParams() {
  1502. /** @type {?} */
  1503. const params = {};
  1504. if (this.consumeOptional('?')) {
  1505. do {
  1506. this.parseQueryParam(params);
  1507. } while (this.consumeOptional('&'));
  1508. }
  1509. return params;
  1510. }
  1511. /**
  1512. * @return {?}
  1513. */
  1514. parseFragment() {
  1515. return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
  1516. }
  1517. /**
  1518. * @private
  1519. * @return {?}
  1520. */
  1521. parseChildren() {
  1522. if (this.remaining === '') {
  1523. return {};
  1524. }
  1525. this.consumeOptional('/');
  1526. /** @type {?} */
  1527. const segments = [];
  1528. if (!this.peekStartsWith('(')) {
  1529. segments.push(this.parseSegment());
  1530. }
  1531. while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
  1532. this.capture('/');
  1533. segments.push(this.parseSegment());
  1534. }
  1535. /** @type {?} */
  1536. let children = {};
  1537. if (this.peekStartsWith('/(')) {
  1538. this.capture('/');
  1539. children = this.parseParens(true);
  1540. }
  1541. /** @type {?} */
  1542. let res = {};
  1543. if (this.peekStartsWith('(')) {
  1544. res = this.parseParens(false);
  1545. }
  1546. if (segments.length > 0 || Object.keys(children).length > 0) {
  1547. res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
  1548. }
  1549. return res;
  1550. }
  1551. // parse a segment with its matrix parameters
  1552. // ie `name;k1=v1;k2`
  1553. /**
  1554. * @private
  1555. * @return {?}
  1556. */
  1557. parseSegment() {
  1558. /** @type {?} */
  1559. const path = matchSegments(this.remaining);
  1560. if (path === '' && this.peekStartsWith(';')) {
  1561. throw new Error(`Empty path url segment cannot have parameters: '${this.remaining}'.`);
  1562. }
  1563. this.capture(path);
  1564. return new UrlSegment(decode(path), this.parseMatrixParams());
  1565. }
  1566. /**
  1567. * @private
  1568. * @return {?}
  1569. */
  1570. parseMatrixParams() {
  1571. /** @type {?} */
  1572. const params = {};
  1573. while (this.consumeOptional(';')) {
  1574. this.parseParam(params);
  1575. }
  1576. return params;
  1577. }
  1578. /**
  1579. * @private
  1580. * @param {?} params
  1581. * @return {?}
  1582. */
  1583. parseParam(params) {
  1584. /** @type {?} */
  1585. const key = matchSegments(this.remaining);
  1586. if (!key) {
  1587. return;
  1588. }
  1589. this.capture(key);
  1590. /** @type {?} */
  1591. let value = '';
  1592. if (this.consumeOptional('=')) {
  1593. /** @type {?} */
  1594. const valueMatch = matchSegments(this.remaining);
  1595. if (valueMatch) {
  1596. value = valueMatch;
  1597. this.capture(value);
  1598. }
  1599. }
  1600. params[decode(key)] = decode(value);
  1601. }
  1602. // Parse a single query parameter `name[=value]`
  1603. /**
  1604. * @private
  1605. * @param {?} params
  1606. * @return {?}
  1607. */
  1608. parseQueryParam(params) {
  1609. /** @type {?} */
  1610. const key = matchQueryParams(this.remaining);
  1611. if (!key) {
  1612. return;
  1613. }
  1614. this.capture(key);
  1615. /** @type {?} */
  1616. let value = '';
  1617. if (this.consumeOptional('=')) {
  1618. /** @type {?} */
  1619. const valueMatch = matchUrlQueryParamValue(this.remaining);
  1620. if (valueMatch) {
  1621. value = valueMatch;
  1622. this.capture(value);
  1623. }
  1624. }
  1625. /** @type {?} */
  1626. const decodedKey = decodeQuery(key);
  1627. /** @type {?} */
  1628. const decodedVal = decodeQuery(value);
  1629. if (params.hasOwnProperty(decodedKey)) {
  1630. // Append to existing values
  1631. /** @type {?} */
  1632. let currentVal = params[decodedKey];
  1633. if (!Array.isArray(currentVal)) {
  1634. currentVal = [currentVal];
  1635. params[decodedKey] = currentVal;
  1636. }
  1637. currentVal.push(decodedVal);
  1638. }
  1639. else {
  1640. // Create a new value
  1641. params[decodedKey] = decodedVal;
  1642. }
  1643. }
  1644. // parse `(a/b//outlet_name:c/d)`
  1645. /**
  1646. * @private
  1647. * @param {?} allowPrimary
  1648. * @return {?}
  1649. */
  1650. parseParens(allowPrimary) {
  1651. /** @type {?} */
  1652. const segments = {};
  1653. this.capture('(');
  1654. while (!this.consumeOptional(')') && this.remaining.length > 0) {
  1655. /** @type {?} */
  1656. const path = matchSegments(this.remaining);
  1657. /** @type {?} */
  1658. const next = this.remaining[path.length];
  1659. // if is is not one of these characters, then the segment was unescaped
  1660. // or the group was not closed
  1661. if (next !== '/' && next !== ')' && next !== ';') {
  1662. throw new Error(`Cannot parse url '${this.url}'`);
  1663. }
  1664. /** @type {?} */
  1665. let outletName = (/** @type {?} */ (undefined));
  1666. if (path.indexOf(':') > -1) {
  1667. outletName = path.substr(0, path.indexOf(':'));
  1668. this.capture(outletName);
  1669. this.capture(':');
  1670. }
  1671. else if (allowPrimary) {
  1672. outletName = PRIMARY_OUTLET;
  1673. }
  1674. /** @type {?} */
  1675. const children = this.parseChildren();
  1676. segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] :
  1677. new UrlSegmentGroup([], children);
  1678. this.consumeOptional('//');
  1679. }
  1680. return segments;
  1681. }
  1682. /**
  1683. * @private
  1684. * @param {?} str
  1685. * @return {?}
  1686. */
  1687. peekStartsWith(str) { return this.remaining.startsWith(str); }
  1688. // Consumes the prefix when it is present and returns whether it has been consumed
  1689. /**
  1690. * @private
  1691. * @param {?} str
  1692. * @return {?}
  1693. */
  1694. consumeOptional(str) {
  1695. if (this.peekStartsWith(str)) {
  1696. this.remaining = this.remaining.substring(str.length);
  1697. return true;
  1698. }
  1699. return false;
  1700. }
  1701. /**
  1702. * @private
  1703. * @param {?} str
  1704. * @return {?}
  1705. */
  1706. capture(str) {
  1707. if (!this.consumeOptional(str)) {
  1708. throw new Error(`Expected "${str}".`);
  1709. }
  1710. }
  1711. }
  1712. /**
  1713. * @fileoverview added by tsickle
  1714. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1715. */
  1716. /**
  1717. * @license
  1718. * Copyright Google Inc. All Rights Reserved.
  1719. *
  1720. * Use of this source code is governed by an MIT-style license that can be
  1721. * found in the LICENSE file at https://angular.io/license
  1722. */
  1723. /**
  1724. * @template T
  1725. */
  1726. class Tree {
  1727. /**
  1728. * @param {?} root
  1729. */
  1730. constructor(root) { this._root = root; }
  1731. /**
  1732. * @return {?}
  1733. */
  1734. get root() { return this._root.value; }
  1735. /**
  1736. * \@internal
  1737. * @param {?} t
  1738. * @return {?}
  1739. */
  1740. parent(t) {
  1741. /** @type {?} */
  1742. const p = this.pathFromRoot(t);
  1743. return p.length > 1 ? p[p.length - 2] : null;
  1744. }
  1745. /**
  1746. * \@internal
  1747. * @param {?} t
  1748. * @return {?}
  1749. */
  1750. children(t) {
  1751. /** @type {?} */
  1752. const n = findNode(t, this._root);
  1753. return n ? n.children.map((/**
  1754. * @param {?} t
  1755. * @return {?}
  1756. */
  1757. t => t.value)) : [];
  1758. }
  1759. /**
  1760. * \@internal
  1761. * @param {?} t
  1762. * @return {?}
  1763. */
  1764. firstChild(t) {
  1765. /** @type {?} */
  1766. const n = findNode(t, this._root);
  1767. return n && n.children.length > 0 ? n.children[0].value : null;
  1768. }
  1769. /**
  1770. * \@internal
  1771. * @param {?} t
  1772. * @return {?}
  1773. */
  1774. siblings(t) {
  1775. /** @type {?} */
  1776. const p = findPath(t, this._root);
  1777. if (p.length < 2)
  1778. return [];
  1779. /** @type {?} */
  1780. const c = p[p.length - 2].children.map((/**
  1781. * @param {?} c
  1782. * @return {?}
  1783. */
  1784. c => c.value));
  1785. return c.filter((/**
  1786. * @param {?} cc
  1787. * @return {?}
  1788. */
  1789. cc => cc !== t));
  1790. }
  1791. /**
  1792. * \@internal
  1793. * @param {?} t
  1794. * @return {?}
  1795. */
  1796. pathFromRoot(t) { return findPath(t, this._root).map((/**
  1797. * @param {?} s
  1798. * @return {?}
  1799. */
  1800. s => s.value)); }
  1801. }
  1802. // DFS for the node matching the value
  1803. /**
  1804. * @template T
  1805. * @param {?} value
  1806. * @param {?} node
  1807. * @return {?}
  1808. */
  1809. function findNode(value, node) {
  1810. if (value === node.value)
  1811. return node;
  1812. for (const child of node.children) {
  1813. /** @type {?} */
  1814. const node = findNode(value, child);
  1815. if (node)
  1816. return node;
  1817. }
  1818. return null;
  1819. }
  1820. // Return the path to the node with the given value using DFS
  1821. /**
  1822. * @template T
  1823. * @param {?} value
  1824. * @param {?} node
  1825. * @return {?}
  1826. */
  1827. function findPath(value, node) {
  1828. if (value === node.value)
  1829. return [node];
  1830. for (const child of node.children) {
  1831. /** @type {?} */
  1832. const path = findPath(value, child);
  1833. if (path.length) {
  1834. path.unshift(node);
  1835. return path;
  1836. }
  1837. }
  1838. return [];
  1839. }
  1840. /**
  1841. * @template T
  1842. */
  1843. class TreeNode {
  1844. /**
  1845. * @param {?} value
  1846. * @param {?} children
  1847. */
  1848. constructor(value, children) {
  1849. this.value = value;
  1850. this.children = children;
  1851. }
  1852. /**
  1853. * @return {?}
  1854. */
  1855. toString() { return `TreeNode(${this.value})`; }
  1856. }
  1857. // Return the list of T indexed by outlet name
  1858. /**
  1859. * @template T
  1860. * @param {?} node
  1861. * @return {?}
  1862. */
  1863. function nodeChildrenAsMap(node) {
  1864. /** @type {?} */
  1865. const map = {};
  1866. if (node) {
  1867. node.children.forEach((/**
  1868. * @param {?} child
  1869. * @return {?}
  1870. */
  1871. child => map[child.value.outlet] = child));
  1872. }
  1873. return map;
  1874. }
  1875. /**
  1876. * @fileoverview added by tsickle
  1877. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1878. */
  1879. /**
  1880. * \@description
  1881. *
  1882. * Represents the state of the router.
  1883. *
  1884. * RouterState is a tree of activated routes. Every node in this tree knows about the "consumed" URL
  1885. * segments, the extracted parameters, and the resolved data.
  1886. *
  1887. * \@usageNotes
  1888. * ### Example
  1889. *
  1890. * ```
  1891. * \@Component({templateUrl:'template.html'})
  1892. * class MyComponent {
  1893. * constructor(router: Router) {
  1894. * const state: RouterState = router.routerState;
  1895. * const root: ActivatedRoute = state.root;
  1896. * const child = root.firstChild;
  1897. * const id: Observable<string> = child.params.map(p => p.id);
  1898. * //...
  1899. * }
  1900. * }
  1901. * ```
  1902. *
  1903. * See `ActivatedRoute` for more information.
  1904. *
  1905. * \@publicApi
  1906. */
  1907. class RouterState extends Tree {
  1908. /**
  1909. * \@internal
  1910. * @param {?} root
  1911. * @param {?} snapshot
  1912. */
  1913. constructor(root, snapshot) {
  1914. super(root);
  1915. this.snapshot = snapshot;
  1916. setRouterState((/** @type {?} */ (this)), root);
  1917. }
  1918. /**
  1919. * @return {?}
  1920. */
  1921. toString() { return this.snapshot.toString(); }
  1922. }
  1923. /**
  1924. * @param {?} urlTree
  1925. * @param {?} rootComponent
  1926. * @return {?}
  1927. */
  1928. function createEmptyState(urlTree, rootComponent) {
  1929. /** @type {?} */
  1930. const snapshot = createEmptyStateSnapshot(urlTree, rootComponent);
  1931. /** @type {?} */
  1932. const emptyUrl = new BehaviorSubject([new UrlSegment('', {})]);
  1933. /** @type {?} */
  1934. const emptyParams = new BehaviorSubject({});
  1935. /** @type {?} */
  1936. const emptyData = new BehaviorSubject({});
  1937. /** @type {?} */
  1938. const emptyQueryParams = new BehaviorSubject({});
  1939. /** @type {?} */
  1940. const fragment = new BehaviorSubject('');
  1941. /** @type {?} */
  1942. const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
  1943. activated.snapshot = snapshot.root;
  1944. return new RouterState(new TreeNode(activated, []), snapshot);
  1945. }
  1946. /**
  1947. * @param {?} urlTree
  1948. * @param {?} rootComponent
  1949. * @return {?}
  1950. */
  1951. function createEmptyStateSnapshot(urlTree, rootComponent) {
  1952. /** @type {?} */
  1953. const emptyParams = {};
  1954. /** @type {?} */
  1955. const emptyData = {};
  1956. /** @type {?} */
  1957. const emptyQueryParams = {};
  1958. /** @type {?} */
  1959. const fragment = '';
  1960. /** @type {?} */
  1961. const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, urlTree.root, -1, {});
  1962. return new RouterStateSnapshot('', new TreeNode(activated, []));
  1963. }
  1964. /**
  1965. * \@description
  1966. *
  1967. * Contains the information about a route associated with a component loaded in an
  1968. * outlet. An `ActivatedRoute` can also be used to traverse the router state tree.
  1969. *
  1970. * {\@example router/activated-route/module.ts region="activated-route"
  1971. * header="activated-route.component.ts" linenums="false"}
  1972. *
  1973. * \@publicApi
  1974. */
  1975. class ActivatedRoute {
  1976. /**
  1977. * \@internal
  1978. * @param {?} url
  1979. * @param {?} params
  1980. * @param {?} queryParams
  1981. * @param {?} fragment
  1982. * @param {?} data
  1983. * @param {?} outlet
  1984. * @param {?} component
  1985. * @param {?} futureSnapshot
  1986. */
  1987. constructor(url, params, queryParams, fragment, data, outlet, component, futureSnapshot) {
  1988. this.url = url;
  1989. this.params = params;
  1990. this.queryParams = queryParams;
  1991. this.fragment = fragment;
  1992. this.data = data;
  1993. this.outlet = outlet;
  1994. this.component = component;
  1995. this._futureSnapshot = futureSnapshot;
  1996. }
  1997. /**
  1998. * The configuration used to match this route
  1999. * @return {?}
  2000. */
  2001. get routeConfig() { return this._futureSnapshot.routeConfig; }
  2002. /**
  2003. * The root of the router state
  2004. * @return {?}
  2005. */
  2006. get root() { return this._routerState.root; }
  2007. /**
  2008. * The parent of this route in the router state tree
  2009. * @return {?}
  2010. */
  2011. get parent() { return this._routerState.parent(this); }
  2012. /**
  2013. * The first child of this route in the router state tree
  2014. * @return {?}
  2015. */
  2016. get firstChild() { return this._routerState.firstChild(this); }
  2017. /**
  2018. * The children of this route in the router state tree
  2019. * @return {?}
  2020. */
  2021. get children() { return this._routerState.children(this); }
  2022. /**
  2023. * The path from the root of the router state tree to this route
  2024. * @return {?}
  2025. */
  2026. get pathFromRoot() { return this._routerState.pathFromRoot(this); }
  2027. /**
  2028. * @return {?}
  2029. */
  2030. get paramMap() {
  2031. if (!this._paramMap) {
  2032. this._paramMap = this.params.pipe(map((/**
  2033. * @param {?} p
  2034. * @return {?}
  2035. */
  2036. (p) => convertToParamMap(p))));
  2037. }
  2038. return this._paramMap;
  2039. }
  2040. /**
  2041. * @return {?}
  2042. */
  2043. get queryParamMap() {
  2044. if (!this._queryParamMap) {
  2045. this._queryParamMap =
  2046. this.queryParams.pipe(map((/**
  2047. * @param {?} p
  2048. * @return {?}
  2049. */
  2050. (p) => convertToParamMap(p))));
  2051. }
  2052. return this._queryParamMap;
  2053. }
  2054. /**
  2055. * @return {?}
  2056. */
  2057. toString() {
  2058. return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
  2059. }
  2060. }
  2061. /**
  2062. * Returns the inherited params, data, and resolve for a given route.
  2063. * By default, this only inherits values up to the nearest path-less or component-less route.
  2064. * \@internal
  2065. * @param {?} route
  2066. * @param {?=} paramsInheritanceStrategy
  2067. * @return {?}
  2068. */
  2069. function inheritedParamsDataResolve(route, paramsInheritanceStrategy = 'emptyOnly') {
  2070. /** @type {?} */
  2071. const pathFromRoot = route.pathFromRoot;
  2072. /** @type {?} */
  2073. let inheritingStartingFrom = 0;
  2074. if (paramsInheritanceStrategy !== 'always') {
  2075. inheritingStartingFrom = pathFromRoot.length - 1;
  2076. while (inheritingStartingFrom >= 1) {
  2077. /** @type {?} */
  2078. const current = pathFromRoot[inheritingStartingFrom];
  2079. /** @type {?} */
  2080. const parent = pathFromRoot[inheritingStartingFrom - 1];
  2081. // current route is an empty path => inherits its parent's params and data
  2082. if (current.routeConfig && current.routeConfig.path === '') {
  2083. inheritingStartingFrom--;
  2084. // parent is componentless => current route should inherit its params and data
  2085. }
  2086. else if (!parent.component) {
  2087. inheritingStartingFrom--;
  2088. }
  2089. else {
  2090. break;
  2091. }
  2092. }
  2093. }
  2094. return flattenInherited(pathFromRoot.slice(inheritingStartingFrom));
  2095. }
  2096. /**
  2097. * \@internal
  2098. * @param {?} pathFromRoot
  2099. * @return {?}
  2100. */
  2101. function flattenInherited(pathFromRoot) {
  2102. return pathFromRoot.reduce((/**
  2103. * @param {?} res
  2104. * @param {?} curr
  2105. * @return {?}
  2106. */
  2107. (res, curr) => {
  2108. /** @type {?} */
  2109. const params = Object.assign({}, res.params, curr.params);
  2110. /** @type {?} */
  2111. const data = Object.assign({}, res.data, curr.data);
  2112. /** @type {?} */
  2113. const resolve = Object.assign({}, res.resolve, curr._resolvedData);
  2114. return { params, data, resolve };
  2115. }), (/** @type {?} */ ({ params: {}, data: {}, resolve: {} })));
  2116. }
  2117. /**
  2118. * \@description
  2119. *
  2120. * Contains the information about a route associated with a component loaded in an
  2121. * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
  2122. * traverse the router state tree.
  2123. *
  2124. * ```
  2125. * \@Component({templateUrl:'./my-component.html'})
  2126. * class MyComponent {
  2127. * constructor(route: ActivatedRoute) {
  2128. * const id: string = route.snapshot.params.id;
  2129. * const url: string = route.snapshot.url.join('');
  2130. * const user = route.snapshot.data.user;
  2131. * }
  2132. * }
  2133. * ```
  2134. *
  2135. * \@publicApi
  2136. */
  2137. class ActivatedRouteSnapshot {
  2138. /**
  2139. * \@internal
  2140. * @param {?} url
  2141. * @param {?} params
  2142. * @param {?} queryParams
  2143. * @param {?} fragment
  2144. * @param {?} data
  2145. * @param {?} outlet
  2146. * @param {?} component
  2147. * @param {?} routeConfig
  2148. * @param {?} urlSegment
  2149. * @param {?} lastPathIndex
  2150. * @param {?} resolve
  2151. */
  2152. constructor(url, params, queryParams, fragment, data, outlet, component, routeConfig, urlSegment, lastPathIndex, resolve) {
  2153. this.url = url;
  2154. this.params = params;
  2155. this.queryParams = queryParams;
  2156. this.fragment = fragment;
  2157. this.data = data;
  2158. this.outlet = outlet;
  2159. this.component = component;
  2160. this.routeConfig = routeConfig;
  2161. this._urlSegment = urlSegment;
  2162. this._lastPathIndex = lastPathIndex;
  2163. this._resolve = resolve;
  2164. }
  2165. /**
  2166. * The root of the router state
  2167. * @return {?}
  2168. */
  2169. get root() { return this._routerState.root; }
  2170. /**
  2171. * The parent of this route in the router state tree
  2172. * @return {?}
  2173. */
  2174. get parent() { return this._routerState.parent(this); }
  2175. /**
  2176. * The first child of this route in the router state tree
  2177. * @return {?}
  2178. */
  2179. get firstChild() { return this._routerState.firstChild(this); }
  2180. /**
  2181. * The children of this route in the router state tree
  2182. * @return {?}
  2183. */
  2184. get children() { return this._routerState.children(this); }
  2185. /**
  2186. * The path from the root of the router state tree to this route
  2187. * @return {?}
  2188. */
  2189. get pathFromRoot() { return this._routerState.pathFromRoot(this); }
  2190. /**
  2191. * @return {?}
  2192. */
  2193. get paramMap() {
  2194. if (!this._paramMap) {
  2195. this._paramMap = convertToParamMap(this.params);
  2196. }
  2197. return this._paramMap;
  2198. }
  2199. /**
  2200. * @return {?}
  2201. */
  2202. get queryParamMap() {
  2203. if (!this._queryParamMap) {
  2204. this._queryParamMap = convertToParamMap(this.queryParams);
  2205. }
  2206. return this._queryParamMap;
  2207. }
  2208. /**
  2209. * @return {?}
  2210. */
  2211. toString() {
  2212. /** @type {?} */
  2213. const url = this.url.map((/**
  2214. * @param {?} segment
  2215. * @return {?}
  2216. */
  2217. segment => segment.toString())).join('/');
  2218. /** @type {?} */
  2219. const matched = this.routeConfig ? this.routeConfig.path : '';
  2220. return `Route(url:'${url}', path:'${matched}')`;
  2221. }
  2222. }
  2223. /**
  2224. * \@description
  2225. *
  2226. * Represents the state of the router at a moment in time.
  2227. *
  2228. * This is a tree of activated route snapshots. Every node in this tree knows about
  2229. * the "consumed" URL segments, the extracted parameters, and the resolved data.
  2230. *
  2231. * \@usageNotes
  2232. * ### Example
  2233. *
  2234. * ```
  2235. * \@Component({templateUrl:'template.html'})
  2236. * class MyComponent {
  2237. * constructor(router: Router) {
  2238. * const state: RouterState = router.routerState;
  2239. * const snapshot: RouterStateSnapshot = state.snapshot;
  2240. * const root: ActivatedRouteSnapshot = snapshot.root;
  2241. * const child = root.firstChild;
  2242. * const id: Observable<string> = child.params.map(p => p.id);
  2243. * //...
  2244. * }
  2245. * }
  2246. * ```
  2247. *
  2248. * \@publicApi
  2249. */
  2250. class RouterStateSnapshot extends Tree {
  2251. /**
  2252. * \@internal
  2253. * @param {?} url
  2254. * @param {?} root
  2255. */
  2256. constructor(url, root) {
  2257. super(root);
  2258. this.url = url;
  2259. setRouterState((/** @type {?} */ (this)), root);
  2260. }
  2261. /**
  2262. * @return {?}
  2263. */
  2264. toString() { return serializeNode(this._root); }
  2265. }
  2266. /**
  2267. * @template U, T
  2268. * @param {?} state
  2269. * @param {?} node
  2270. * @return {?}
  2271. */
  2272. function setRouterState(state, node) {
  2273. node.value._routerState = state;
  2274. node.children.forEach((/**
  2275. * @param {?} c
  2276. * @return {?}
  2277. */
  2278. c => setRouterState(state, c)));
  2279. }
  2280. /**
  2281. * @param {?} node
  2282. * @return {?}
  2283. */
  2284. function serializeNode(node) {
  2285. /** @type {?} */
  2286. const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : '';
  2287. return `${node.value}${c}`;
  2288. }
  2289. /**
  2290. * The expectation is that the activate route is created with the right set of parameters.
  2291. * So we push new values into the observables only when they are not the initial values.
  2292. * And we detect that by checking if the snapshot field is set.
  2293. * @param {?} route
  2294. * @return {?}
  2295. */
  2296. function advanceActivatedRoute(route) {
  2297. if (route.snapshot) {
  2298. /** @type {?} */
  2299. const currentSnapshot = route.snapshot;
  2300. /** @type {?} */
  2301. const nextSnapshot = route._futureSnapshot;
  2302. route.snapshot = nextSnapshot;
  2303. if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
  2304. ((/** @type {?} */ (route.queryParams))).next(nextSnapshot.queryParams);
  2305. }
  2306. if (currentSnapshot.fragment !== nextSnapshot.fragment) {
  2307. ((/** @type {?} */ (route.fragment))).next(nextSnapshot.fragment);
  2308. }
  2309. if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
  2310. ((/** @type {?} */ (route.params))).next(nextSnapshot.params);
  2311. }
  2312. if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
  2313. ((/** @type {?} */ (route.url))).next(nextSnapshot.url);
  2314. }
  2315. if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
  2316. ((/** @type {?} */ (route.data))).next(nextSnapshot.data);
  2317. }
  2318. }
  2319. else {
  2320. route.snapshot = route._futureSnapshot;
  2321. // this is for resolved data
  2322. ((/** @type {?} */ (route.data))).next(route._futureSnapshot.data);
  2323. }
  2324. }
  2325. /**
  2326. * @param {?} a
  2327. * @param {?} b
  2328. * @return {?}
  2329. */
  2330. function equalParamsAndUrlSegments(a, b) {
  2331. /** @type {?} */
  2332. const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
  2333. /** @type {?} */
  2334. const parentsMismatch = !a.parent !== !b.parent;
  2335. return equalUrlParams && !parentsMismatch &&
  2336. (!a.parent || equalParamsAndUrlSegments(a.parent, (/** @type {?} */ (b.parent))));
  2337. }
  2338. /**
  2339. * @fileoverview added by tsickle
  2340. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2341. */
  2342. /**
  2343. * @param {?} routeReuseStrategy
  2344. * @param {?} curr
  2345. * @param {?} prevState
  2346. * @return {?}
  2347. */
  2348. function createRouterState(routeReuseStrategy, curr, prevState) {
  2349. /** @type {?} */
  2350. const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
  2351. return new RouterState(root, curr);
  2352. }
  2353. /**
  2354. * @param {?} routeReuseStrategy
  2355. * @param {?} curr
  2356. * @param {?=} prevState
  2357. * @return {?}
  2358. */
  2359. function createNode(routeReuseStrategy, curr, prevState) {
  2360. // reuse an activated route that is currently displayed on the screen
  2361. if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
  2362. /** @type {?} */
  2363. const value = prevState.value;
  2364. value._futureSnapshot = curr.value;
  2365. /** @type {?} */
  2366. const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
  2367. return new TreeNode(value, children);
  2368. // retrieve an activated route that is used to be displayed, but is not currently displayed
  2369. }
  2370. else {
  2371. /** @type {?} */
  2372. const detachedRouteHandle = (/** @type {?} */ (routeReuseStrategy.retrieve(curr.value)));
  2373. if (detachedRouteHandle) {
  2374. /** @type {?} */
  2375. const tree = detachedRouteHandle.route;
  2376. setFutureSnapshotsOfActivatedRoutes(curr, tree);
  2377. return tree;
  2378. }
  2379. else {
  2380. /** @type {?} */
  2381. const value = createActivatedRoute(curr.value);
  2382. /** @type {?} */
  2383. const children = curr.children.map((/**
  2384. * @param {?} c
  2385. * @return {?}
  2386. */
  2387. c => createNode(routeReuseStrategy, c)));
  2388. return new TreeNode(value, children);
  2389. }
  2390. }
  2391. }
  2392. /**
  2393. * @param {?} curr
  2394. * @param {?} result
  2395. * @return {?}
  2396. */
  2397. function setFutureSnapshotsOfActivatedRoutes(curr, result) {
  2398. if (curr.value.routeConfig !== result.value.routeConfig) {
  2399. throw new Error('Cannot reattach ActivatedRouteSnapshot created from a different route');
  2400. }
  2401. if (curr.children.length !== result.children.length) {
  2402. throw new Error('Cannot reattach ActivatedRouteSnapshot with a different number of children');
  2403. }
  2404. result.value._futureSnapshot = curr.value;
  2405. for (let i = 0; i < curr.children.length; ++i) {
  2406. setFutureSnapshotsOfActivatedRoutes(curr.children[i], result.children[i]);
  2407. }
  2408. }
  2409. /**
  2410. * @param {?} routeReuseStrategy
  2411. * @param {?} curr
  2412. * @param {?} prevState
  2413. * @return {?}
  2414. */
  2415. function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
  2416. return curr.children.map((/**
  2417. * @param {?} child
  2418. * @return {?}
  2419. */
  2420. child => {
  2421. for (const p of prevState.children) {
  2422. if (routeReuseStrategy.shouldReuseRoute(p.value.snapshot, child.value)) {
  2423. return createNode(routeReuseStrategy, child, p);
  2424. }
  2425. }
  2426. return createNode(routeReuseStrategy, child);
  2427. }));
  2428. }
  2429. /**
  2430. * @param {?} c
  2431. * @return {?}
  2432. */
  2433. function createActivatedRoute(c) {
  2434. return new ActivatedRoute(new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams), new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
  2435. }
  2436. /**
  2437. * @fileoverview added by tsickle
  2438. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2439. */
  2440. /**
  2441. * @param {?} route
  2442. * @param {?} urlTree
  2443. * @param {?} commands
  2444. * @param {?} queryParams
  2445. * @param {?} fragment
  2446. * @return {?}
  2447. */
  2448. function createUrlTree(route, urlTree, commands, queryParams, fragment) {
  2449. if (commands.length === 0) {
  2450. return tree(urlTree.root, urlTree.root, urlTree, queryParams, fragment);
  2451. }
  2452. /** @type {?} */
  2453. const nav = computeNavigation(commands);
  2454. if (nav.toRoot()) {
  2455. return tree(urlTree.root, new UrlSegmentGroup([], {}), urlTree, queryParams, fragment);
  2456. }
  2457. /** @type {?} */
  2458. const startingPosition = findStartingPosition(nav, urlTree, route);
  2459. /** @type {?} */
  2460. const segmentGroup = startingPosition.processChildren ?
  2461. updateSegmentGroupChildren(startingPosition.segmentGroup, startingPosition.index, nav.commands) :
  2462. updateSegmentGroup(startingPosition.segmentGroup, startingPosition.index, nav.commands);
  2463. return tree(startingPosition.segmentGroup, segmentGroup, urlTree, queryParams, fragment);
  2464. }
  2465. /**
  2466. * @param {?} command
  2467. * @return {?}
  2468. */
  2469. function isMatrixParams(command) {
  2470. return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
  2471. }
  2472. /**
  2473. * @param {?} oldSegmentGroup
  2474. * @param {?} newSegmentGroup
  2475. * @param {?} urlTree
  2476. * @param {?} queryParams
  2477. * @param {?} fragment
  2478. * @return {?}
  2479. */
  2480. function tree(oldSegmentGroup, newSegmentGroup, urlTree, queryParams, fragment) {
  2481. /** @type {?} */
  2482. let qp = {};
  2483. if (queryParams) {
  2484. forEach(queryParams, (/**
  2485. * @param {?} value
  2486. * @param {?} name
  2487. * @return {?}
  2488. */
  2489. (value, name) => {
  2490. qp[name] = Array.isArray(value) ? value.map((/**
  2491. * @param {?} v
  2492. * @return {?}
  2493. */
  2494. (v) => `${v}`)) : `${value}`;
  2495. }));
  2496. }
  2497. if (urlTree.root === oldSegmentGroup) {
  2498. return new UrlTree(newSegmentGroup, qp, fragment);
  2499. }
  2500. return new UrlTree(replaceSegment(urlTree.root, oldSegmentGroup, newSegmentGroup), qp, fragment);
  2501. }
  2502. /**
  2503. * @param {?} current
  2504. * @param {?} oldSegment
  2505. * @param {?} newSegment
  2506. * @return {?}
  2507. */
  2508. function replaceSegment(current, oldSegment, newSegment) {
  2509. /** @type {?} */
  2510. const children = {};
  2511. forEach(current.children, (/**
  2512. * @param {?} c
  2513. * @param {?} outletName
  2514. * @return {?}
  2515. */
  2516. (c, outletName) => {
  2517. if (c === oldSegment) {
  2518. children[outletName] = newSegment;
  2519. }
  2520. else {
  2521. children[outletName] = replaceSegment(c, oldSegment, newSegment);
  2522. }
  2523. }));
  2524. return new UrlSegmentGroup(current.segments, children);
  2525. }
  2526. class Navigation {
  2527. /**
  2528. * @param {?} isAbsolute
  2529. * @param {?} numberOfDoubleDots
  2530. * @param {?} commands
  2531. */
  2532. constructor(isAbsolute, numberOfDoubleDots, commands) {
  2533. this.isAbsolute = isAbsolute;
  2534. this.numberOfDoubleDots = numberOfDoubleDots;
  2535. this.commands = commands;
  2536. if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
  2537. throw new Error('Root segment cannot have matrix parameters');
  2538. }
  2539. /** @type {?} */
  2540. const cmdWithOutlet = commands.find((/**
  2541. * @param {?} c
  2542. * @return {?}
  2543. */
  2544. c => typeof c === 'object' && c != null && c.outlets));
  2545. if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
  2546. throw new Error('{outlets:{}} has to be the last command');
  2547. }
  2548. }
  2549. /**
  2550. * @return {?}
  2551. */
  2552. toRoot() {
  2553. return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
  2554. }
  2555. }
  2556. /**
  2557. * Transforms commands to a normalized `Navigation`
  2558. * @param {?} commands
  2559. * @return {?}
  2560. */
  2561. function computeNavigation(commands) {
  2562. if ((typeof commands[0] === 'string') && commands.length === 1 && commands[0] === '/') {
  2563. return new Navigation(true, 0, commands);
  2564. }
  2565. /** @type {?} */
  2566. let numberOfDoubleDots = 0;
  2567. /** @type {?} */
  2568. let isAbsolute = false;
  2569. /** @type {?} */
  2570. const res = commands.reduce((/**
  2571. * @param {?} res
  2572. * @param {?} cmd
  2573. * @param {?} cmdIdx
  2574. * @return {?}
  2575. */
  2576. (res, cmd, cmdIdx) => {
  2577. if (typeof cmd === 'object' && cmd != null) {
  2578. if (cmd.outlets) {
  2579. /** @type {?} */
  2580. const outlets = {};
  2581. forEach(cmd.outlets, (/**
  2582. * @param {?} commands
  2583. * @param {?} name
  2584. * @return {?}
  2585. */
  2586. (commands, name) => {
  2587. outlets[name] = typeof commands === 'string' ? commands.split('/') : commands;
  2588. }));
  2589. return [...res, { outlets }];
  2590. }
  2591. if (cmd.segmentPath) {
  2592. return [...res, cmd.segmentPath];
  2593. }
  2594. }
  2595. if (!(typeof cmd === 'string')) {
  2596. return [...res, cmd];
  2597. }
  2598. if (cmdIdx === 0) {
  2599. cmd.split('/').forEach((/**
  2600. * @param {?} urlPart
  2601. * @param {?} partIndex
  2602. * @return {?}
  2603. */
  2604. (urlPart, partIndex) => {
  2605. if (partIndex == 0 && urlPart === '.') ;
  2606. else if (partIndex == 0 && urlPart === '') { // '/a'
  2607. isAbsolute = true;
  2608. }
  2609. else if (urlPart === '..') { // '../a'
  2610. numberOfDoubleDots++;
  2611. }
  2612. else if (urlPart != '') {
  2613. res.push(urlPart);
  2614. }
  2615. }));
  2616. return res;
  2617. }
  2618. return [...res, cmd];
  2619. }), []);
  2620. return new Navigation(isAbsolute, numberOfDoubleDots, res);
  2621. }
  2622. class Position {
  2623. /**
  2624. * @param {?} segmentGroup
  2625. * @param {?} processChildren
  2626. * @param {?} index
  2627. */
  2628. constructor(segmentGroup, processChildren, index) {
  2629. this.segmentGroup = segmentGroup;
  2630. this.processChildren = processChildren;
  2631. this.index = index;
  2632. }
  2633. }
  2634. /**
  2635. * @param {?} nav
  2636. * @param {?} tree
  2637. * @param {?} route
  2638. * @return {?}
  2639. */
  2640. function findStartingPosition(nav, tree, route) {
  2641. if (nav.isAbsolute) {
  2642. return new Position(tree.root, true, 0);
  2643. }
  2644. if (route.snapshot._lastPathIndex === -1) {
  2645. return new Position(route.snapshot._urlSegment, true, 0);
  2646. }
  2647. /** @type {?} */
  2648. const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
  2649. /** @type {?} */
  2650. const index = route.snapshot._lastPathIndex + modifier;
  2651. return createPositionApplyingDoubleDots(route.snapshot._urlSegment, index, nav.numberOfDoubleDots);
  2652. }
  2653. /**
  2654. * @param {?} group
  2655. * @param {?} index
  2656. * @param {?} numberOfDoubleDots
  2657. * @return {?}
  2658. */
  2659. function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
  2660. /** @type {?} */
  2661. let g = group;
  2662. /** @type {?} */
  2663. let ci = index;
  2664. /** @type {?} */
  2665. let dd = numberOfDoubleDots;
  2666. while (dd > ci) {
  2667. dd -= ci;
  2668. g = (/** @type {?} */ (g.parent));
  2669. if (!g) {
  2670. throw new Error('Invalid number of \'../\'');
  2671. }
  2672. ci = g.segments.length;
  2673. }
  2674. return new Position(g, false, ci - dd);
  2675. }
  2676. /**
  2677. * @param {?} command
  2678. * @return {?}
  2679. */
  2680. function getPath(command) {
  2681. if (typeof command === 'object' && command != null && command.outlets) {
  2682. return command.outlets[PRIMARY_OUTLET];
  2683. }
  2684. return `${command}`;
  2685. }
  2686. /**
  2687. * @param {?} commands
  2688. * @return {?}
  2689. */
  2690. function getOutlets(commands) {
  2691. if (!(typeof commands[0] === 'object'))
  2692. return { [PRIMARY_OUTLET]: commands };
  2693. if (commands[0].outlets === undefined)
  2694. return { [PRIMARY_OUTLET]: commands };
  2695. return commands[0].outlets;
  2696. }
  2697. /**
  2698. * @param {?} segmentGroup
  2699. * @param {?} startIndex
  2700. * @param {?} commands
  2701. * @return {?}
  2702. */
  2703. function updateSegmentGroup(segmentGroup, startIndex, commands) {
  2704. if (!segmentGroup) {
  2705. segmentGroup = new UrlSegmentGroup([], {});
  2706. }
  2707. if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
  2708. return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
  2709. }
  2710. /** @type {?} */
  2711. const m = prefixedWith(segmentGroup, startIndex, commands);
  2712. /** @type {?} */
  2713. const slicedCommands = commands.slice(m.commandIndex);
  2714. if (m.match && m.pathIndex < segmentGroup.segments.length) {
  2715. /** @type {?} */
  2716. const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
  2717. g.children[PRIMARY_OUTLET] =
  2718. new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
  2719. return updateSegmentGroupChildren(g, 0, slicedCommands);
  2720. }
  2721. else if (m.match && slicedCommands.length === 0) {
  2722. return new UrlSegmentGroup(segmentGroup.segments, {});
  2723. }
  2724. else if (m.match && !segmentGroup.hasChildren()) {
  2725. return createNewSegmentGroup(segmentGroup, startIndex, commands);
  2726. }
  2727. else if (m.match) {
  2728. return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
  2729. }
  2730. else {
  2731. return createNewSegmentGroup(segmentGroup, startIndex, commands);
  2732. }
  2733. }
  2734. /**
  2735. * @param {?} segmentGroup
  2736. * @param {?} startIndex
  2737. * @param {?} commands
  2738. * @return {?}
  2739. */
  2740. function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
  2741. if (commands.length === 0) {
  2742. return new UrlSegmentGroup(segmentGroup.segments, {});
  2743. }
  2744. else {
  2745. /** @type {?} */
  2746. const outlets = getOutlets(commands);
  2747. /** @type {?} */
  2748. const children = {};
  2749. forEach(outlets, (/**
  2750. * @param {?} commands
  2751. * @param {?} outlet
  2752. * @return {?}
  2753. */
  2754. (commands, outlet) => {
  2755. if (commands !== null) {
  2756. children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
  2757. }
  2758. }));
  2759. forEach(segmentGroup.children, (/**
  2760. * @param {?} child
  2761. * @param {?} childOutlet
  2762. * @return {?}
  2763. */
  2764. (child, childOutlet) => {
  2765. if (outlets[childOutlet] === undefined) {
  2766. children[childOutlet] = child;
  2767. }
  2768. }));
  2769. return new UrlSegmentGroup(segmentGroup.segments, children);
  2770. }
  2771. }
  2772. /**
  2773. * @param {?} segmentGroup
  2774. * @param {?} startIndex
  2775. * @param {?} commands
  2776. * @return {?}
  2777. */
  2778. function prefixedWith(segmentGroup, startIndex, commands) {
  2779. /** @type {?} */
  2780. let currentCommandIndex = 0;
  2781. /** @type {?} */
  2782. let currentPathIndex = startIndex;
  2783. /** @type {?} */
  2784. const noMatch = { match: false, pathIndex: 0, commandIndex: 0 };
  2785. while (currentPathIndex < segmentGroup.segments.length) {
  2786. if (currentCommandIndex >= commands.length)
  2787. return noMatch;
  2788. /** @type {?} */
  2789. const path = segmentGroup.segments[currentPathIndex];
  2790. /** @type {?} */
  2791. const curr = getPath(commands[currentCommandIndex]);
  2792. /** @type {?} */
  2793. const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
  2794. if (currentPathIndex > 0 && curr === undefined)
  2795. break;
  2796. if (curr && next && (typeof next === 'object') && next.outlets === undefined) {
  2797. if (!compare(curr, next, path))
  2798. return noMatch;
  2799. currentCommandIndex += 2;
  2800. }
  2801. else {
  2802. if (!compare(curr, {}, path))
  2803. return noMatch;
  2804. currentCommandIndex++;
  2805. }
  2806. currentPathIndex++;
  2807. }
  2808. return { match: true, pathIndex: currentPathIndex, commandIndex: currentCommandIndex };
  2809. }
  2810. /**
  2811. * @param {?} segmentGroup
  2812. * @param {?} startIndex
  2813. * @param {?} commands
  2814. * @return {?}
  2815. */
  2816. function createNewSegmentGroup(segmentGroup, startIndex, commands) {
  2817. /** @type {?} */
  2818. const paths = segmentGroup.segments.slice(0, startIndex);
  2819. /** @type {?} */
  2820. let i = 0;
  2821. while (i < commands.length) {
  2822. if (typeof commands[i] === 'object' && commands[i].outlets !== undefined) {
  2823. /** @type {?} */
  2824. const children = createNewSegmentChildren(commands[i].outlets);
  2825. return new UrlSegmentGroup(paths, children);
  2826. }
  2827. // if we start with an object literal, we need to reuse the path part from the segment
  2828. if (i === 0 && isMatrixParams(commands[0])) {
  2829. /** @type {?} */
  2830. const p = segmentGroup.segments[startIndex];
  2831. paths.push(new UrlSegment(p.path, commands[0]));
  2832. i++;
  2833. continue;
  2834. }
  2835. /** @type {?} */
  2836. const curr = getPath(commands[i]);
  2837. /** @type {?} */
  2838. const next = (i < commands.length - 1) ? commands[i + 1] : null;
  2839. if (curr && next && isMatrixParams(next)) {
  2840. paths.push(new UrlSegment(curr, stringify(next)));
  2841. i += 2;
  2842. }
  2843. else {
  2844. paths.push(new UrlSegment(curr, {}));
  2845. i++;
  2846. }
  2847. }
  2848. return new UrlSegmentGroup(paths, {});
  2849. }
  2850. /**
  2851. * @param {?} outlets
  2852. * @return {?}
  2853. */
  2854. function createNewSegmentChildren(outlets) {
  2855. /** @type {?} */
  2856. const children = {};
  2857. forEach(outlets, (/**
  2858. * @param {?} commands
  2859. * @param {?} outlet
  2860. * @return {?}
  2861. */
  2862. (commands, outlet) => {
  2863. if (commands !== null) {
  2864. children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
  2865. }
  2866. }));
  2867. return children;
  2868. }
  2869. /**
  2870. * @param {?} params
  2871. * @return {?}
  2872. */
  2873. function stringify(params) {
  2874. /** @type {?} */
  2875. const res = {};
  2876. forEach(params, (/**
  2877. * @param {?} v
  2878. * @param {?} k
  2879. * @return {?}
  2880. */
  2881. (v, k) => res[k] = `${v}`));
  2882. return res;
  2883. }
  2884. /**
  2885. * @param {?} path
  2886. * @param {?} params
  2887. * @param {?} segment
  2888. * @return {?}
  2889. */
  2890. function compare(path, params, segment) {
  2891. return path == segment.path && shallowEqual(params, segment.parameters);
  2892. }
  2893. /**
  2894. * @fileoverview added by tsickle
  2895. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2896. */
  2897. /** @type {?} */
  2898. const activateRoutes = (/**
  2899. * @param {?} rootContexts
  2900. * @param {?} routeReuseStrategy
  2901. * @param {?} forwardEvent
  2902. * @return {?}
  2903. */
  2904. (rootContexts, routeReuseStrategy, forwardEvent) => map((/**
  2905. * @param {?} t
  2906. * @return {?}
  2907. */
  2908. t => {
  2909. new ActivateRoutes(routeReuseStrategy, (/** @type {?} */ (t.targetRouterState)), t.currentRouterState, forwardEvent)
  2910. .activate(rootContexts);
  2911. return t;
  2912. })));
  2913. class ActivateRoutes {
  2914. /**
  2915. * @param {?} routeReuseStrategy
  2916. * @param {?} futureState
  2917. * @param {?} currState
  2918. * @param {?} forwardEvent
  2919. */
  2920. constructor(routeReuseStrategy, futureState, currState, forwardEvent) {
  2921. this.routeReuseStrategy = routeReuseStrategy;
  2922. this.futureState = futureState;
  2923. this.currState = currState;
  2924. this.forwardEvent = forwardEvent;
  2925. }
  2926. /**
  2927. * @param {?} parentContexts
  2928. * @return {?}
  2929. */
  2930. activate(parentContexts) {
  2931. /** @type {?} */
  2932. const futureRoot = this.futureState._root;
  2933. /** @type {?} */
  2934. const currRoot = this.currState ? this.currState._root : null;
  2935. this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
  2936. advanceActivatedRoute(this.futureState.root);
  2937. this.activateChildRoutes(futureRoot, currRoot, parentContexts);
  2938. }
  2939. // De-activate the child route that are not re-used for the future state
  2940. /**
  2941. * @private
  2942. * @param {?} futureNode
  2943. * @param {?} currNode
  2944. * @param {?} contexts
  2945. * @return {?}
  2946. */
  2947. deactivateChildRoutes(futureNode, currNode, contexts) {
  2948. /** @type {?} */
  2949. const children = nodeChildrenAsMap(currNode);
  2950. // Recurse on the routes active in the future state to de-activate deeper children
  2951. futureNode.children.forEach((/**
  2952. * @param {?} futureChild
  2953. * @return {?}
  2954. */
  2955. futureChild => {
  2956. /** @type {?} */
  2957. const childOutletName = futureChild.value.outlet;
  2958. this.deactivateRoutes(futureChild, children[childOutletName], contexts);
  2959. delete children[childOutletName];
  2960. }));
  2961. // De-activate the routes that will not be re-used
  2962. forEach(children, (/**
  2963. * @param {?} v
  2964. * @param {?} childName
  2965. * @return {?}
  2966. */
  2967. (v, childName) => {
  2968. this.deactivateRouteAndItsChildren(v, contexts);
  2969. }));
  2970. }
  2971. /**
  2972. * @private
  2973. * @param {?} futureNode
  2974. * @param {?} currNode
  2975. * @param {?} parentContext
  2976. * @return {?}
  2977. */
  2978. deactivateRoutes(futureNode, currNode, parentContext) {
  2979. /** @type {?} */
  2980. const future = futureNode.value;
  2981. /** @type {?} */
  2982. const curr = currNode ? currNode.value : null;
  2983. if (future === curr) {
  2984. // Reusing the node, check to see if the children need to be de-activated
  2985. if (future.component) {
  2986. // If we have a normal route, we need to go through an outlet.
  2987. /** @type {?} */
  2988. const context = parentContext.getContext(future.outlet);
  2989. if (context) {
  2990. this.deactivateChildRoutes(futureNode, currNode, context.children);
  2991. }
  2992. }
  2993. else {
  2994. // if we have a componentless route, we recurse but keep the same outlet map.
  2995. this.deactivateChildRoutes(futureNode, currNode, parentContext);
  2996. }
  2997. }
  2998. else {
  2999. if (curr) {
  3000. // Deactivate the current route which will not be re-used
  3001. this.deactivateRouteAndItsChildren(currNode, parentContext);
  3002. }
  3003. }
  3004. }
  3005. /**
  3006. * @private
  3007. * @param {?} route
  3008. * @param {?} parentContexts
  3009. * @return {?}
  3010. */
  3011. deactivateRouteAndItsChildren(route, parentContexts) {
  3012. if (this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
  3013. this.detachAndStoreRouteSubtree(route, parentContexts);
  3014. }
  3015. else {
  3016. this.deactivateRouteAndOutlet(route, parentContexts);
  3017. }
  3018. }
  3019. /**
  3020. * @private
  3021. * @param {?} route
  3022. * @param {?} parentContexts
  3023. * @return {?}
  3024. */
  3025. detachAndStoreRouteSubtree(route, parentContexts) {
  3026. /** @type {?} */
  3027. const context = parentContexts.getContext(route.value.outlet);
  3028. if (context && context.outlet) {
  3029. /** @type {?} */
  3030. const componentRef = context.outlet.detach();
  3031. /** @type {?} */
  3032. const contexts = context.children.onOutletDeactivated();
  3033. this.routeReuseStrategy.store(route.value.snapshot, { componentRef, route, contexts });
  3034. }
  3035. }
  3036. /**
  3037. * @private
  3038. * @param {?} route
  3039. * @param {?} parentContexts
  3040. * @return {?}
  3041. */
  3042. deactivateRouteAndOutlet(route, parentContexts) {
  3043. /** @type {?} */
  3044. const context = parentContexts.getContext(route.value.outlet);
  3045. if (context) {
  3046. /** @type {?} */
  3047. const children = nodeChildrenAsMap(route);
  3048. /** @type {?} */
  3049. const contexts = route.value.component ? context.children : parentContexts;
  3050. forEach(children, (/**
  3051. * @param {?} v
  3052. * @param {?} k
  3053. * @return {?}
  3054. */
  3055. (v, k) => this.deactivateRouteAndItsChildren(v, contexts)));
  3056. if (context.outlet) {
  3057. // Destroy the component
  3058. context.outlet.deactivate();
  3059. // Destroy the contexts for all the outlets that were in the component
  3060. context.children.onOutletDeactivated();
  3061. }
  3062. }
  3063. }
  3064. /**
  3065. * @private
  3066. * @param {?} futureNode
  3067. * @param {?} currNode
  3068. * @param {?} contexts
  3069. * @return {?}
  3070. */
  3071. activateChildRoutes(futureNode, currNode, contexts) {
  3072. /** @type {?} */
  3073. const children = nodeChildrenAsMap(currNode);
  3074. futureNode.children.forEach((/**
  3075. * @param {?} c
  3076. * @return {?}
  3077. */
  3078. c => {
  3079. this.activateRoutes(c, children[c.value.outlet], contexts);
  3080. this.forwardEvent(new ActivationEnd(c.value.snapshot));
  3081. }));
  3082. if (futureNode.children.length) {
  3083. this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
  3084. }
  3085. }
  3086. /**
  3087. * @private
  3088. * @param {?} futureNode
  3089. * @param {?} currNode
  3090. * @param {?} parentContexts
  3091. * @return {?}
  3092. */
  3093. activateRoutes(futureNode, currNode, parentContexts) {
  3094. /** @type {?} */
  3095. const future = futureNode.value;
  3096. /** @type {?} */
  3097. const curr = currNode ? currNode.value : null;
  3098. advanceActivatedRoute(future);
  3099. // reusing the node
  3100. if (future === curr) {
  3101. if (future.component) {
  3102. // If we have a normal route, we need to go through an outlet.
  3103. /** @type {?} */
  3104. const context = parentContexts.getOrCreateContext(future.outlet);
  3105. this.activateChildRoutes(futureNode, currNode, context.children);
  3106. }
  3107. else {
  3108. // if we have a componentless route, we recurse but keep the same outlet map.
  3109. this.activateChildRoutes(futureNode, currNode, parentContexts);
  3110. }
  3111. }
  3112. else {
  3113. if (future.component) {
  3114. // if we have a normal route, we need to place the component into the outlet and recurse.
  3115. /** @type {?} */
  3116. const context = parentContexts.getOrCreateContext(future.outlet);
  3117. if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
  3118. /** @type {?} */
  3119. const stored = ((/** @type {?} */ (this.routeReuseStrategy.retrieve(future.snapshot))));
  3120. this.routeReuseStrategy.store(future.snapshot, null);
  3121. context.children.onOutletReAttached(stored.contexts);
  3122. context.attachRef = stored.componentRef;
  3123. context.route = stored.route.value;
  3124. if (context.outlet) {
  3125. // Attach right away when the outlet has already been instantiated
  3126. // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
  3127. context.outlet.attach(stored.componentRef, stored.route.value);
  3128. }
  3129. advanceActivatedRouteNodeAndItsChildren(stored.route);
  3130. }
  3131. else {
  3132. /** @type {?} */
  3133. const config = parentLoadedConfig(future.snapshot);
  3134. /** @type {?} */
  3135. const cmpFactoryResolver = config ? config.module.componentFactoryResolver : null;
  3136. context.attachRef = null;
  3137. context.route = future;
  3138. context.resolver = cmpFactoryResolver;
  3139. if (context.outlet) {
  3140. // Activate the outlet when it has already been instantiated
  3141. // Otherwise it will get activated from its `ngOnInit` when instantiated
  3142. context.outlet.activateWith(future, cmpFactoryResolver);
  3143. }
  3144. this.activateChildRoutes(futureNode, null, context.children);
  3145. }
  3146. }
  3147. else {
  3148. // if we have a componentless route, we recurse but keep the same outlet map.
  3149. this.activateChildRoutes(futureNode, null, parentContexts);
  3150. }
  3151. }
  3152. }
  3153. }
  3154. /**
  3155. * @param {?} node
  3156. * @return {?}
  3157. */
  3158. function advanceActivatedRouteNodeAndItsChildren(node) {
  3159. advanceActivatedRoute(node.value);
  3160. node.children.forEach(advanceActivatedRouteNodeAndItsChildren);
  3161. }
  3162. /**
  3163. * @param {?} snapshot
  3164. * @return {?}
  3165. */
  3166. function parentLoadedConfig(snapshot) {
  3167. for (let s = snapshot.parent; s; s = s.parent) {
  3168. /** @type {?} */
  3169. const route = s.routeConfig;
  3170. if (route && route._loadedConfig)
  3171. return route._loadedConfig;
  3172. if (route && route.component)
  3173. return null;
  3174. }
  3175. return null;
  3176. }
  3177. /**
  3178. * @fileoverview added by tsickle
  3179. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  3180. */
  3181. /**
  3182. * Simple function check, but generic so type inference will flow. Example:
  3183. *
  3184. * function product(a: number, b: number) {
  3185. * return a * b;
  3186. * }
  3187. *
  3188. * if (isFunction<product>(fn)) {
  3189. * return fn(1, 2);
  3190. * } else {
  3191. * throw "Must provide the `product` function";
  3192. * }
  3193. * @template T
  3194. * @param {?} v
  3195. * @return {?}
  3196. */
  3197. function isFunction(v) {
  3198. return typeof v === 'function';
  3199. }
  3200. /**
  3201. * @param {?} v
  3202. * @return {?}
  3203. */
  3204. function isBoolean(v) {
  3205. return typeof v === 'boolean';
  3206. }
  3207. /**
  3208. * @param {?} v
  3209. * @return {?}
  3210. */
  3211. function isUrlTree(v) {
  3212. return v instanceof UrlTree;
  3213. }
  3214. /**
  3215. * @param {?} guard
  3216. * @return {?}
  3217. */
  3218. function isCanLoad(guard) {
  3219. return guard && isFunction(guard.canLoad);
  3220. }
  3221. /**
  3222. * @param {?} guard
  3223. * @return {?}
  3224. */
  3225. function isCanActivate(guard) {
  3226. return guard && isFunction(guard.canActivate);
  3227. }
  3228. /**
  3229. * @param {?} guard
  3230. * @return {?}
  3231. */
  3232. function isCanActivateChild(guard) {
  3233. return guard && isFunction(guard.canActivateChild);
  3234. }
  3235. /**
  3236. * @template T
  3237. * @param {?} guard
  3238. * @return {?}
  3239. */
  3240. function isCanDeactivate(guard) {
  3241. return guard && isFunction(guard.canDeactivate);
  3242. }
  3243. /**
  3244. * @fileoverview added by tsickle
  3245. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  3246. */
  3247. class NoMatch {
  3248. /**
  3249. * @param {?=} segmentGroup
  3250. */
  3251. constructor(segmentGroup) { this.segmentGroup = segmentGroup || null; }
  3252. }
  3253. class AbsoluteRedirect {
  3254. /**
  3255. * @param {?} urlTree
  3256. */
  3257. constructor(urlTree) {
  3258. this.urlTree = urlTree;
  3259. }
  3260. }
  3261. /**
  3262. * @param {?} segmentGroup
  3263. * @return {?}
  3264. */
  3265. function noMatch(segmentGroup) {
  3266. return new Observable((/**
  3267. * @param {?} obs
  3268. * @return {?}
  3269. */
  3270. (obs) => obs.error(new NoMatch(segmentGroup))));
  3271. }
  3272. /**
  3273. * @param {?} newTree
  3274. * @return {?}
  3275. */
  3276. function absoluteRedirect(newTree) {
  3277. return new Observable((/**
  3278. * @param {?} obs
  3279. * @return {?}
  3280. */
  3281. (obs) => obs.error(new AbsoluteRedirect(newTree))));
  3282. }
  3283. /**
  3284. * @param {?} redirectTo
  3285. * @return {?}
  3286. */
  3287. function namedOutletsRedirect(redirectTo) {
  3288. return new Observable((/**
  3289. * @param {?} obs
  3290. * @return {?}
  3291. */
  3292. (obs) => obs.error(new Error(`Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`))));
  3293. }
  3294. /**
  3295. * @param {?} route
  3296. * @return {?}
  3297. */
  3298. function canLoadFails(route) {
  3299. return new Observable((/**
  3300. * @param {?} obs
  3301. * @return {?}
  3302. */
  3303. (obs) => obs.error(navigationCancelingError(`Cannot load children because the guard of the route "path: '${route.path}'" returned false`))));
  3304. }
  3305. /**
  3306. * Returns the `UrlTree` with the redirection applied.
  3307. *
  3308. * Lazy modules are loaded along the way.
  3309. * @param {?} moduleInjector
  3310. * @param {?} configLoader
  3311. * @param {?} urlSerializer
  3312. * @param {?} urlTree
  3313. * @param {?} config
  3314. * @return {?}
  3315. */
  3316. function applyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config) {
  3317. return new ApplyRedirects(moduleInjector, configLoader, urlSerializer, urlTree, config).apply();
  3318. }
  3319. class ApplyRedirects {
  3320. /**
  3321. * @param {?} moduleInjector
  3322. * @param {?} configLoader
  3323. * @param {?} urlSerializer
  3324. * @param {?} urlTree
  3325. * @param {?} config
  3326. */
  3327. constructor(moduleInjector, configLoader, urlSerializer, urlTree, config) {
  3328. this.configLoader = configLoader;
  3329. this.urlSerializer = urlSerializer;
  3330. this.urlTree = urlTree;
  3331. this.config = config;
  3332. this.allowRedirects = true;
  3333. this.ngModule = moduleInjector.get(NgModuleRef);
  3334. }
  3335. /**
  3336. * @return {?}
  3337. */
  3338. apply() {
  3339. /** @type {?} */
  3340. const expanded$ = this.expandSegmentGroup(this.ngModule, this.config, this.urlTree.root, PRIMARY_OUTLET);
  3341. /** @type {?} */
  3342. const urlTrees$ = expanded$.pipe(map((/**
  3343. * @param {?} rootSegmentGroup
  3344. * @return {?}
  3345. */
  3346. (rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, this.urlTree.queryParams, (/** @type {?} */ (this.urlTree.fragment))))));
  3347. return urlTrees$.pipe(catchError((/**
  3348. * @param {?} e
  3349. * @return {?}
  3350. */
  3351. (e) => {
  3352. if (e instanceof AbsoluteRedirect) {
  3353. // after an absolute redirect we do not apply any more redirects!
  3354. this.allowRedirects = false;
  3355. // we need to run matching, so we can fetch all lazy-loaded modules
  3356. return this.match(e.urlTree);
  3357. }
  3358. if (e instanceof NoMatch) {
  3359. throw this.noMatchError(e);
  3360. }
  3361. throw e;
  3362. })));
  3363. }
  3364. /**
  3365. * @private
  3366. * @param {?} tree
  3367. * @return {?}
  3368. */
  3369. match(tree) {
  3370. /** @type {?} */
  3371. const expanded$ = this.expandSegmentGroup(this.ngModule, this.config, tree.root, PRIMARY_OUTLET);
  3372. /** @type {?} */
  3373. const mapped$ = expanded$.pipe(map((/**
  3374. * @param {?} rootSegmentGroup
  3375. * @return {?}
  3376. */
  3377. (rootSegmentGroup) => this.createUrlTree(rootSegmentGroup, tree.queryParams, (/** @type {?} */ (tree.fragment))))));
  3378. return mapped$.pipe(catchError((/**
  3379. * @param {?} e
  3380. * @return {?}
  3381. */
  3382. (e) => {
  3383. if (e instanceof NoMatch) {
  3384. throw this.noMatchError(e);
  3385. }
  3386. throw e;
  3387. })));
  3388. }
  3389. /**
  3390. * @private
  3391. * @param {?} e
  3392. * @return {?}
  3393. */
  3394. noMatchError(e) {
  3395. return new Error(`Cannot match any routes. URL Segment: '${e.segmentGroup}'`);
  3396. }
  3397. /**
  3398. * @private
  3399. * @param {?} rootCandidate
  3400. * @param {?} queryParams
  3401. * @param {?} fragment
  3402. * @return {?}
  3403. */
  3404. createUrlTree(rootCandidate, queryParams, fragment) {
  3405. /** @type {?} */
  3406. const root = rootCandidate.segments.length > 0 ?
  3407. new UrlSegmentGroup([], { [PRIMARY_OUTLET]: rootCandidate }) :
  3408. rootCandidate;
  3409. return new UrlTree(root, queryParams, fragment);
  3410. }
  3411. /**
  3412. * @private
  3413. * @param {?} ngModule
  3414. * @param {?} routes
  3415. * @param {?} segmentGroup
  3416. * @param {?} outlet
  3417. * @return {?}
  3418. */
  3419. expandSegmentGroup(ngModule, routes, segmentGroup, outlet) {
  3420. if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
  3421. return this.expandChildren(ngModule, routes, segmentGroup)
  3422. .pipe(map((/**
  3423. * @param {?} children
  3424. * @return {?}
  3425. */
  3426. (children) => new UrlSegmentGroup([], children))));
  3427. }
  3428. return this.expandSegment(ngModule, segmentGroup, routes, segmentGroup.segments, outlet, true);
  3429. }
  3430. // Recursively expand segment groups for all the child outlets
  3431. /**
  3432. * @private
  3433. * @param {?} ngModule
  3434. * @param {?} routes
  3435. * @param {?} segmentGroup
  3436. * @return {?}
  3437. */
  3438. expandChildren(ngModule, routes, segmentGroup) {
  3439. return waitForMap(segmentGroup.children, (/**
  3440. * @param {?} childOutlet
  3441. * @param {?} child
  3442. * @return {?}
  3443. */
  3444. (childOutlet, child) => this.expandSegmentGroup(ngModule, routes, child, childOutlet)));
  3445. }
  3446. /**
  3447. * @private
  3448. * @param {?} ngModule
  3449. * @param {?} segmentGroup
  3450. * @param {?} routes
  3451. * @param {?} segments
  3452. * @param {?} outlet
  3453. * @param {?} allowRedirects
  3454. * @return {?}
  3455. */
  3456. expandSegment(ngModule, segmentGroup, routes, segments, outlet, allowRedirects) {
  3457. return of(...routes).pipe(map((/**
  3458. * @param {?} r
  3459. * @return {?}
  3460. */
  3461. (r) => {
  3462. /** @type {?} */
  3463. const expanded$ = this.expandSegmentAgainstRoute(ngModule, segmentGroup, routes, r, segments, outlet, allowRedirects);
  3464. return expanded$.pipe(catchError((/**
  3465. * @param {?} e
  3466. * @return {?}
  3467. */
  3468. (e) => {
  3469. if (e instanceof NoMatch) {
  3470. // TODO(i): this return type doesn't match the declared Observable<UrlSegmentGroup> -
  3471. // talk to Jason
  3472. return (/** @type {?} */ (of(null)));
  3473. }
  3474. throw e;
  3475. })));
  3476. })), concatAll(), first((/**
  3477. * @param {?} s
  3478. * @return {?}
  3479. */
  3480. (s) => !!s)), catchError((/**
  3481. * @param {?} e
  3482. * @param {?} _
  3483. * @return {?}
  3484. */
  3485. (e, _) => {
  3486. if (e instanceof EmptyError || e.name === 'EmptyError') {
  3487. if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
  3488. return of(new UrlSegmentGroup([], {}));
  3489. }
  3490. throw new NoMatch(segmentGroup);
  3491. }
  3492. throw e;
  3493. })));
  3494. }
  3495. /**
  3496. * @private
  3497. * @param {?} segmentGroup
  3498. * @param {?} segments
  3499. * @param {?} outlet
  3500. * @return {?}
  3501. */
  3502. noLeftoversInUrl(segmentGroup, segments, outlet) {
  3503. return segments.length === 0 && !segmentGroup.children[outlet];
  3504. }
  3505. /**
  3506. * @private
  3507. * @param {?} ngModule
  3508. * @param {?} segmentGroup
  3509. * @param {?} routes
  3510. * @param {?} route
  3511. * @param {?} paths
  3512. * @param {?} outlet
  3513. * @param {?} allowRedirects
  3514. * @return {?}
  3515. */
  3516. expandSegmentAgainstRoute(ngModule, segmentGroup, routes, route, paths, outlet, allowRedirects) {
  3517. if (getOutlet(route) !== outlet) {
  3518. return noMatch(segmentGroup);
  3519. }
  3520. if (route.redirectTo === undefined) {
  3521. return this.matchSegmentAgainstRoute(ngModule, segmentGroup, route, paths);
  3522. }
  3523. if (allowRedirects && this.allowRedirects) {
  3524. return this.expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, paths, outlet);
  3525. }
  3526. return noMatch(segmentGroup);
  3527. }
  3528. /**
  3529. * @private
  3530. * @param {?} ngModule
  3531. * @param {?} segmentGroup
  3532. * @param {?} routes
  3533. * @param {?} route
  3534. * @param {?} segments
  3535. * @param {?} outlet
  3536. * @return {?}
  3537. */
  3538. expandSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
  3539. if (route.path === '**') {
  3540. return this.expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet);
  3541. }
  3542. return this.expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet);
  3543. }
  3544. /**
  3545. * @private
  3546. * @param {?} ngModule
  3547. * @param {?} routes
  3548. * @param {?} route
  3549. * @param {?} outlet
  3550. * @return {?}
  3551. */
  3552. expandWildCardWithParamsAgainstRouteUsingRedirect(ngModule, routes, route, outlet) {
  3553. /** @type {?} */
  3554. const newTree = this.applyRedirectCommands([], (/** @type {?} */ (route.redirectTo)), {});
  3555. if ((/** @type {?} */ (route.redirectTo)).startsWith('/')) {
  3556. return absoluteRedirect(newTree);
  3557. }
  3558. return this.lineralizeSegments(route, newTree).pipe(mergeMap((/**
  3559. * @param {?} newSegments
  3560. * @return {?}
  3561. */
  3562. (newSegments) => {
  3563. /** @type {?} */
  3564. const group = new UrlSegmentGroup(newSegments, {});
  3565. return this.expandSegment(ngModule, group, routes, newSegments, outlet, false);
  3566. })));
  3567. }
  3568. /**
  3569. * @private
  3570. * @param {?} ngModule
  3571. * @param {?} segmentGroup
  3572. * @param {?} routes
  3573. * @param {?} route
  3574. * @param {?} segments
  3575. * @param {?} outlet
  3576. * @return {?}
  3577. */
  3578. expandRegularSegmentAgainstRouteUsingRedirect(ngModule, segmentGroup, routes, route, segments, outlet) {
  3579. const { matched, consumedSegments, lastChild, positionalParamSegments } = match(segmentGroup, route, segments);
  3580. if (!matched)
  3581. return noMatch(segmentGroup);
  3582. /** @type {?} */
  3583. const newTree = this.applyRedirectCommands(consumedSegments, (/** @type {?} */ (route.redirectTo)), (/** @type {?} */ (positionalParamSegments)));
  3584. if ((/** @type {?} */ (route.redirectTo)).startsWith('/')) {
  3585. return absoluteRedirect(newTree);
  3586. }
  3587. return this.lineralizeSegments(route, newTree).pipe(mergeMap((/**
  3588. * @param {?} newSegments
  3589. * @return {?}
  3590. */
  3591. (newSegments) => {
  3592. return this.expandSegment(ngModule, segmentGroup, routes, newSegments.concat(segments.slice(lastChild)), outlet, false);
  3593. })));
  3594. }
  3595. /**
  3596. * @private
  3597. * @param {?} ngModule
  3598. * @param {?} rawSegmentGroup
  3599. * @param {?} route
  3600. * @param {?} segments
  3601. * @return {?}
  3602. */
  3603. matchSegmentAgainstRoute(ngModule, rawSegmentGroup, route, segments) {
  3604. if (route.path === '**') {
  3605. if (route.loadChildren) {
  3606. return this.configLoader.load(ngModule.injector, route)
  3607. .pipe(map((/**
  3608. * @param {?} cfg
  3609. * @return {?}
  3610. */
  3611. (cfg) => {
  3612. route._loadedConfig = cfg;
  3613. return new UrlSegmentGroup(segments, {});
  3614. })));
  3615. }
  3616. return of(new UrlSegmentGroup(segments, {}));
  3617. }
  3618. const { matched, consumedSegments, lastChild } = match(rawSegmentGroup, route, segments);
  3619. if (!matched)
  3620. return noMatch(rawSegmentGroup);
  3621. /** @type {?} */
  3622. const rawSlicedSegments = segments.slice(lastChild);
  3623. /** @type {?} */
  3624. const childConfig$ = this.getChildConfig(ngModule, route, segments);
  3625. return childConfig$.pipe(mergeMap((/**
  3626. * @param {?} routerConfig
  3627. * @return {?}
  3628. */
  3629. (routerConfig) => {
  3630. /** @type {?} */
  3631. const childModule = routerConfig.module;
  3632. /** @type {?} */
  3633. const childConfig = routerConfig.routes;
  3634. const { segmentGroup, slicedSegments } = split(rawSegmentGroup, consumedSegments, rawSlicedSegments, childConfig);
  3635. if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
  3636. /** @type {?} */
  3637. const expanded$ = this.expandChildren(childModule, childConfig, segmentGroup);
  3638. return expanded$.pipe(map((/**
  3639. * @param {?} children
  3640. * @return {?}
  3641. */
  3642. (children) => new UrlSegmentGroup(consumedSegments, children))));
  3643. }
  3644. if (childConfig.length === 0 && slicedSegments.length === 0) {
  3645. return of(new UrlSegmentGroup(consumedSegments, {}));
  3646. }
  3647. /** @type {?} */
  3648. const expanded$ = this.expandSegment(childModule, segmentGroup, childConfig, slicedSegments, PRIMARY_OUTLET, true);
  3649. return expanded$.pipe(map((/**
  3650. * @param {?} cs
  3651. * @return {?}
  3652. */
  3653. (cs) => new UrlSegmentGroup(consumedSegments.concat(cs.segments), cs.children))));
  3654. })));
  3655. }
  3656. /**
  3657. * @private
  3658. * @param {?} ngModule
  3659. * @param {?} route
  3660. * @param {?} segments
  3661. * @return {?}
  3662. */
  3663. getChildConfig(ngModule, route, segments) {
  3664. if (route.children) {
  3665. // The children belong to the same module
  3666. return of(new LoadedRouterConfig(route.children, ngModule));
  3667. }
  3668. if (route.loadChildren) {
  3669. // lazy children belong to the loaded module
  3670. if (route._loadedConfig !== undefined) {
  3671. return of(route._loadedConfig);
  3672. }
  3673. return runCanLoadGuard(ngModule.injector, route, segments)
  3674. .pipe(mergeMap((/**
  3675. * @param {?} shouldLoad
  3676. * @return {?}
  3677. */
  3678. (shouldLoad) => {
  3679. if (shouldLoad) {
  3680. return this.configLoader.load(ngModule.injector, route)
  3681. .pipe(map((/**
  3682. * @param {?} cfg
  3683. * @return {?}
  3684. */
  3685. (cfg) => {
  3686. route._loadedConfig = cfg;
  3687. return cfg;
  3688. })));
  3689. }
  3690. return canLoadFails(route);
  3691. })));
  3692. }
  3693. return of(new LoadedRouterConfig([], ngModule));
  3694. }
  3695. /**
  3696. * @private
  3697. * @param {?} route
  3698. * @param {?} urlTree
  3699. * @return {?}
  3700. */
  3701. lineralizeSegments(route, urlTree) {
  3702. /** @type {?} */
  3703. let res = [];
  3704. /** @type {?} */
  3705. let c = urlTree.root;
  3706. while (true) {
  3707. res = res.concat(c.segments);
  3708. if (c.numberOfChildren === 0) {
  3709. return of(res);
  3710. }
  3711. if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
  3712. return namedOutletsRedirect((/** @type {?} */ (route.redirectTo)));
  3713. }
  3714. c = c.children[PRIMARY_OUTLET];
  3715. }
  3716. }
  3717. /**
  3718. * @private
  3719. * @param {?} segments
  3720. * @param {?} redirectTo
  3721. * @param {?} posParams
  3722. * @return {?}
  3723. */
  3724. applyRedirectCommands(segments, redirectTo, posParams) {
  3725. return this.applyRedirectCreatreUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
  3726. }
  3727. /**
  3728. * @private
  3729. * @param {?} redirectTo
  3730. * @param {?} urlTree
  3731. * @param {?} segments
  3732. * @param {?} posParams
  3733. * @return {?}
  3734. */
  3735. applyRedirectCreatreUrlTree(redirectTo, urlTree, segments, posParams) {
  3736. /** @type {?} */
  3737. const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
  3738. return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
  3739. }
  3740. /**
  3741. * @private
  3742. * @param {?} redirectToParams
  3743. * @param {?} actualParams
  3744. * @return {?}
  3745. */
  3746. createQueryParams(redirectToParams, actualParams) {
  3747. /** @type {?} */
  3748. const res = {};
  3749. forEach(redirectToParams, (/**
  3750. * @param {?} v
  3751. * @param {?} k
  3752. * @return {?}
  3753. */
  3754. (v, k) => {
  3755. /** @type {?} */
  3756. const copySourceValue = typeof v === 'string' && v.startsWith(':');
  3757. if (copySourceValue) {
  3758. /** @type {?} */
  3759. const sourceName = v.substring(1);
  3760. res[k] = actualParams[sourceName];
  3761. }
  3762. else {
  3763. res[k] = v;
  3764. }
  3765. }));
  3766. return res;
  3767. }
  3768. /**
  3769. * @private
  3770. * @param {?} redirectTo
  3771. * @param {?} group
  3772. * @param {?} segments
  3773. * @param {?} posParams
  3774. * @return {?}
  3775. */
  3776. createSegmentGroup(redirectTo, group, segments, posParams) {
  3777. /** @type {?} */
  3778. const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
  3779. /** @type {?} */
  3780. let children = {};
  3781. forEach(group.children, (/**
  3782. * @param {?} child
  3783. * @param {?} name
  3784. * @return {?}
  3785. */
  3786. (child, name) => {
  3787. children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
  3788. }));
  3789. return new UrlSegmentGroup(updatedSegments, children);
  3790. }
  3791. /**
  3792. * @private
  3793. * @param {?} redirectTo
  3794. * @param {?} redirectToSegments
  3795. * @param {?} actualSegments
  3796. * @param {?} posParams
  3797. * @return {?}
  3798. */
  3799. createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
  3800. return redirectToSegments.map((/**
  3801. * @param {?} s
  3802. * @return {?}
  3803. */
  3804. s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) :
  3805. this.findOrReturn(s, actualSegments)));
  3806. }
  3807. /**
  3808. * @private
  3809. * @param {?} redirectTo
  3810. * @param {?} redirectToUrlSegment
  3811. * @param {?} posParams
  3812. * @return {?}
  3813. */
  3814. findPosParam(redirectTo, redirectToUrlSegment, posParams) {
  3815. /** @type {?} */
  3816. const pos = posParams[redirectToUrlSegment.path.substring(1)];
  3817. if (!pos)
  3818. throw new Error(`Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
  3819. return pos;
  3820. }
  3821. /**
  3822. * @private
  3823. * @param {?} redirectToUrlSegment
  3824. * @param {?} actualSegments
  3825. * @return {?}
  3826. */
  3827. findOrReturn(redirectToUrlSegment, actualSegments) {
  3828. /** @type {?} */
  3829. let idx = 0;
  3830. for (const s of actualSegments) {
  3831. if (s.path === redirectToUrlSegment.path) {
  3832. actualSegments.splice(idx);
  3833. return s;
  3834. }
  3835. idx++;
  3836. }
  3837. return redirectToUrlSegment;
  3838. }
  3839. }
  3840. /**
  3841. * @param {?} moduleInjector
  3842. * @param {?} route
  3843. * @param {?} segments
  3844. * @return {?}
  3845. */
  3846. function runCanLoadGuard(moduleInjector, route, segments) {
  3847. /** @type {?} */
  3848. const canLoad = route.canLoad;
  3849. if (!canLoad || canLoad.length === 0)
  3850. return of(true);
  3851. /** @type {?} */
  3852. const obs = from(canLoad).pipe(map((/**
  3853. * @param {?} injectionToken
  3854. * @return {?}
  3855. */
  3856. (injectionToken) => {
  3857. /** @type {?} */
  3858. const guard = moduleInjector.get(injectionToken);
  3859. /** @type {?} */
  3860. let guardVal;
  3861. if (isCanLoad(guard)) {
  3862. guardVal = guard.canLoad(route, segments);
  3863. }
  3864. else if (isFunction(guard)) {
  3865. guardVal = guard(route, segments);
  3866. }
  3867. else {
  3868. throw new Error('Invalid CanLoad guard');
  3869. }
  3870. return wrapIntoObservable(guardVal);
  3871. })));
  3872. return obs.pipe(concatAll(), every((/**
  3873. * @param {?} result
  3874. * @return {?}
  3875. */
  3876. result => result === true)));
  3877. }
  3878. /**
  3879. * @param {?} segmentGroup
  3880. * @param {?} route
  3881. * @param {?} segments
  3882. * @return {?}
  3883. */
  3884. function match(segmentGroup, route, segments) {
  3885. if (route.path === '') {
  3886. if ((route.pathMatch === 'full') && (segmentGroup.hasChildren() || segments.length > 0)) {
  3887. return { matched: false, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
  3888. }
  3889. return { matched: true, consumedSegments: [], lastChild: 0, positionalParamSegments: {} };
  3890. }
  3891. /** @type {?} */
  3892. const matcher = route.matcher || defaultUrlMatcher;
  3893. /** @type {?} */
  3894. const res = matcher(segments, segmentGroup, route);
  3895. if (!res) {
  3896. return {
  3897. matched: false,
  3898. consumedSegments: (/** @type {?} */ ([])),
  3899. lastChild: 0,
  3900. positionalParamSegments: {},
  3901. };
  3902. }
  3903. return {
  3904. matched: true,
  3905. consumedSegments: (/** @type {?} */ (res.consumed)),
  3906. lastChild: (/** @type {?} */ (res.consumed.length)),
  3907. positionalParamSegments: (/** @type {?} */ (res.posParams)),
  3908. };
  3909. }
  3910. /**
  3911. * @param {?} segmentGroup
  3912. * @param {?} consumedSegments
  3913. * @param {?} slicedSegments
  3914. * @param {?} config
  3915. * @return {?}
  3916. */
  3917. function split(segmentGroup, consumedSegments, slicedSegments, config) {
  3918. if (slicedSegments.length > 0 &&
  3919. containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, slicedSegments, config)) {
  3920. /** @type {?} */
  3921. const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptySegments(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
  3922. return { segmentGroup: mergeTrivialChildren(s), slicedSegments: [] };
  3923. }
  3924. if (slicedSegments.length === 0 &&
  3925. containsEmptyPathRedirects(segmentGroup, slicedSegments, config)) {
  3926. /** @type {?} */
  3927. const s = new UrlSegmentGroup(segmentGroup.segments, addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
  3928. return { segmentGroup: mergeTrivialChildren(s), slicedSegments };
  3929. }
  3930. return { segmentGroup, slicedSegments };
  3931. }
  3932. /**
  3933. * @param {?} s
  3934. * @return {?}
  3935. */
  3936. function mergeTrivialChildren(s) {
  3937. if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
  3938. /** @type {?} */
  3939. const c = s.children[PRIMARY_OUTLET];
  3940. return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
  3941. }
  3942. return s;
  3943. }
  3944. /**
  3945. * @param {?} segmentGroup
  3946. * @param {?} slicedSegments
  3947. * @param {?} routes
  3948. * @param {?} children
  3949. * @return {?}
  3950. */
  3951. function addEmptySegmentsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
  3952. /** @type {?} */
  3953. const res = {};
  3954. for (const r of routes) {
  3955. if (isEmptyPathRedirect(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
  3956. res[getOutlet(r)] = new UrlSegmentGroup([], {});
  3957. }
  3958. }
  3959. return Object.assign({}, children, res);
  3960. }
  3961. /**
  3962. * @param {?} routes
  3963. * @param {?} primarySegmentGroup
  3964. * @return {?}
  3965. */
  3966. function createChildrenForEmptySegments(routes, primarySegmentGroup) {
  3967. /** @type {?} */
  3968. const res = {};
  3969. res[PRIMARY_OUTLET] = primarySegmentGroup;
  3970. for (const r of routes) {
  3971. if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
  3972. res[getOutlet(r)] = new UrlSegmentGroup([], {});
  3973. }
  3974. }
  3975. return res;
  3976. }
  3977. /**
  3978. * @param {?} segmentGroup
  3979. * @param {?} segments
  3980. * @param {?} routes
  3981. * @return {?}
  3982. */
  3983. function containsEmptyPathRedirectsWithNamedOutlets(segmentGroup, segments, routes) {
  3984. return routes.some((/**
  3985. * @param {?} r
  3986. * @return {?}
  3987. */
  3988. r => isEmptyPathRedirect(segmentGroup, segments, r) && getOutlet(r) !== PRIMARY_OUTLET));
  3989. }
  3990. /**
  3991. * @param {?} segmentGroup
  3992. * @param {?} segments
  3993. * @param {?} routes
  3994. * @return {?}
  3995. */
  3996. function containsEmptyPathRedirects(segmentGroup, segments, routes) {
  3997. return routes.some((/**
  3998. * @param {?} r
  3999. * @return {?}
  4000. */
  4001. r => isEmptyPathRedirect(segmentGroup, segments, r)));
  4002. }
  4003. /**
  4004. * @param {?} segmentGroup
  4005. * @param {?} segments
  4006. * @param {?} r
  4007. * @return {?}
  4008. */
  4009. function isEmptyPathRedirect(segmentGroup, segments, r) {
  4010. if ((segmentGroup.hasChildren() || segments.length > 0) && r.pathMatch === 'full') {
  4011. return false;
  4012. }
  4013. return r.path === '' && r.redirectTo !== undefined;
  4014. }
  4015. /**
  4016. * @param {?} route
  4017. * @return {?}
  4018. */
  4019. function getOutlet(route) {
  4020. return route.outlet || PRIMARY_OUTLET;
  4021. }
  4022. /**
  4023. * @fileoverview added by tsickle
  4024. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4025. */
  4026. /**
  4027. * @param {?} moduleInjector
  4028. * @param {?} configLoader
  4029. * @param {?} urlSerializer
  4030. * @param {?} config
  4031. * @return {?}
  4032. */
  4033. function applyRedirects$1(moduleInjector, configLoader, urlSerializer, config) {
  4034. return (/**
  4035. * @param {?} source
  4036. * @return {?}
  4037. */
  4038. function (source) {
  4039. return source.pipe(switchMap((/**
  4040. * @param {?} t
  4041. * @return {?}
  4042. */
  4043. t => applyRedirects(moduleInjector, configLoader, urlSerializer, t.extractedUrl, config)
  4044. .pipe(map((/**
  4045. * @param {?} urlAfterRedirects
  4046. * @return {?}
  4047. */
  4048. urlAfterRedirects => (Object.assign({}, t, { urlAfterRedirects }))))))));
  4049. });
  4050. }
  4051. /**
  4052. * @fileoverview added by tsickle
  4053. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4054. */
  4055. class CanActivate {
  4056. /**
  4057. * @param {?} path
  4058. */
  4059. constructor(path) {
  4060. this.path = path;
  4061. this.route = this.path[this.path.length - 1];
  4062. }
  4063. }
  4064. class CanDeactivate {
  4065. /**
  4066. * @param {?} component
  4067. * @param {?} route
  4068. */
  4069. constructor(component, route) {
  4070. this.component = component;
  4071. this.route = route;
  4072. }
  4073. }
  4074. /**
  4075. * @param {?} future
  4076. * @param {?} curr
  4077. * @param {?} parentContexts
  4078. * @return {?}
  4079. */
  4080. function getAllRouteGuards(future, curr, parentContexts) {
  4081. /** @type {?} */
  4082. const futureRoot = future._root;
  4083. /** @type {?} */
  4084. const currRoot = curr ? curr._root : null;
  4085. return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
  4086. }
  4087. /**
  4088. * @param {?} p
  4089. * @return {?}
  4090. */
  4091. function getCanActivateChild(p) {
  4092. /** @type {?} */
  4093. const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
  4094. if (!canActivateChild || canActivateChild.length === 0)
  4095. return null;
  4096. return { node: p, guards: canActivateChild };
  4097. }
  4098. /**
  4099. * @param {?} token
  4100. * @param {?} snapshot
  4101. * @param {?} moduleInjector
  4102. * @return {?}
  4103. */
  4104. function getToken(token, snapshot, moduleInjector) {
  4105. /** @type {?} */
  4106. const config = getClosestLoadedConfig(snapshot);
  4107. /** @type {?} */
  4108. const injector = config ? config.module.injector : moduleInjector;
  4109. return injector.get(token);
  4110. }
  4111. /**
  4112. * @param {?} snapshot
  4113. * @return {?}
  4114. */
  4115. function getClosestLoadedConfig(snapshot) {
  4116. if (!snapshot)
  4117. return null;
  4118. for (let s = snapshot.parent; s; s = s.parent) {
  4119. /** @type {?} */
  4120. const route = s.routeConfig;
  4121. if (route && route._loadedConfig)
  4122. return route._loadedConfig;
  4123. }
  4124. return null;
  4125. }
  4126. /**
  4127. * @param {?} futureNode
  4128. * @param {?} currNode
  4129. * @param {?} contexts
  4130. * @param {?} futurePath
  4131. * @param {?=} checks
  4132. * @return {?}
  4133. */
  4134. function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
  4135. canDeactivateChecks: [],
  4136. canActivateChecks: []
  4137. }) {
  4138. /** @type {?} */
  4139. const prevChildren = nodeChildrenAsMap(currNode);
  4140. // Process the children of the future route
  4141. futureNode.children.forEach((/**
  4142. * @param {?} c
  4143. * @return {?}
  4144. */
  4145. c => {
  4146. getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
  4147. delete prevChildren[c.value.outlet];
  4148. }));
  4149. // Process any children left from the current route (not active for the future route)
  4150. forEach(prevChildren, (/**
  4151. * @param {?} v
  4152. * @param {?} k
  4153. * @return {?}
  4154. */
  4155. (v, k) => deactivateRouteAndItsChildren(v, (/** @type {?} */ (contexts)).getContext(k), checks)));
  4156. return checks;
  4157. }
  4158. /**
  4159. * @param {?} futureNode
  4160. * @param {?} currNode
  4161. * @param {?} parentContexts
  4162. * @param {?} futurePath
  4163. * @param {?=} checks
  4164. * @return {?}
  4165. */
  4166. function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
  4167. canDeactivateChecks: [],
  4168. canActivateChecks: []
  4169. }) {
  4170. /** @type {?} */
  4171. const future = futureNode.value;
  4172. /** @type {?} */
  4173. const curr = currNode ? currNode.value : null;
  4174. /** @type {?} */
  4175. const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
  4176. // reusing the node
  4177. if (curr && future.routeConfig === curr.routeConfig) {
  4178. /** @type {?} */
  4179. const shouldRun = shouldRunGuardsAndResolvers(curr, future, (/** @type {?} */ (future.routeConfig)).runGuardsAndResolvers);
  4180. if (shouldRun) {
  4181. checks.canActivateChecks.push(new CanActivate(futurePath));
  4182. }
  4183. else {
  4184. // we need to set the data
  4185. future.data = curr.data;
  4186. future._resolvedData = curr._resolvedData;
  4187. }
  4188. // If we have a component, we need to go through an outlet.
  4189. if (future.component) {
  4190. getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
  4191. // if we have a componentless route, we recurse but keep the same outlet map.
  4192. }
  4193. else {
  4194. getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
  4195. }
  4196. if (shouldRun) {
  4197. /** @type {?} */
  4198. const component = context && context.outlet && context.outlet.component || null;
  4199. checks.canDeactivateChecks.push(new CanDeactivate(component, curr));
  4200. }
  4201. }
  4202. else {
  4203. if (curr) {
  4204. deactivateRouteAndItsChildren(currNode, context, checks);
  4205. }
  4206. checks.canActivateChecks.push(new CanActivate(futurePath));
  4207. // If we have a component, we need to go through an outlet.
  4208. if (future.component) {
  4209. getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
  4210. // if we have a componentless route, we recurse but keep the same outlet map.
  4211. }
  4212. else {
  4213. getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
  4214. }
  4215. }
  4216. return checks;
  4217. }
  4218. /**
  4219. * @param {?} curr
  4220. * @param {?} future
  4221. * @param {?} mode
  4222. * @return {?}
  4223. */
  4224. function shouldRunGuardsAndResolvers(curr, future, mode) {
  4225. if (typeof mode === 'function') {
  4226. return mode(curr, future);
  4227. }
  4228. switch (mode) {
  4229. case 'pathParamsChange':
  4230. return !equalPath(curr.url, future.url);
  4231. case 'pathParamsOrQueryParamsChange':
  4232. return !equalPath(curr.url, future.url) ||
  4233. !shallowEqual(curr.queryParams, future.queryParams);
  4234. case 'always':
  4235. return true;
  4236. case 'paramsOrQueryParamsChange':
  4237. return !equalParamsAndUrlSegments(curr, future) ||
  4238. !shallowEqual(curr.queryParams, future.queryParams);
  4239. case 'paramsChange':
  4240. default:
  4241. return !equalParamsAndUrlSegments(curr, future);
  4242. }
  4243. }
  4244. /**
  4245. * @param {?} route
  4246. * @param {?} context
  4247. * @param {?} checks
  4248. * @return {?}
  4249. */
  4250. function deactivateRouteAndItsChildren(route, context, checks) {
  4251. /** @type {?} */
  4252. const children = nodeChildrenAsMap(route);
  4253. /** @type {?} */
  4254. const r = route.value;
  4255. forEach(children, (/**
  4256. * @param {?} node
  4257. * @param {?} childName
  4258. * @return {?}
  4259. */
  4260. (node, childName) => {
  4261. if (!r.component) {
  4262. deactivateRouteAndItsChildren(node, context, checks);
  4263. }
  4264. else if (context) {
  4265. deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
  4266. }
  4267. else {
  4268. deactivateRouteAndItsChildren(node, null, checks);
  4269. }
  4270. }));
  4271. if (!r.component) {
  4272. checks.canDeactivateChecks.push(new CanDeactivate(null, r));
  4273. }
  4274. else if (context && context.outlet && context.outlet.isActivated) {
  4275. checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
  4276. }
  4277. else {
  4278. checks.canDeactivateChecks.push(new CanDeactivate(null, r));
  4279. }
  4280. }
  4281. /**
  4282. * @fileoverview added by tsickle
  4283. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4284. */
  4285. /** @type {?} */
  4286. const INITIAL_VALUE = Symbol('INITIAL_VALUE');
  4287. /**
  4288. * @return {?}
  4289. */
  4290. function prioritizedGuardValue() {
  4291. return switchMap((/**
  4292. * @param {?} obs
  4293. * @return {?}
  4294. */
  4295. obs => {
  4296. return (/** @type {?} */ (combineLatest(...obs.map((/**
  4297. * @param {?} o
  4298. * @return {?}
  4299. */
  4300. o => o.pipe(take(1), startWith((/** @type {?} */ (INITIAL_VALUE)))))))
  4301. .pipe(scan((/**
  4302. * @param {?} acc
  4303. * @param {?} list
  4304. * @return {?}
  4305. */
  4306. (acc, list) => {
  4307. /** @type {?} */
  4308. let isPending = false;
  4309. return list.reduce((/**
  4310. * @param {?} innerAcc
  4311. * @param {?} val
  4312. * @param {?} i
  4313. * @return {?}
  4314. */
  4315. (innerAcc, val, i) => {
  4316. if (innerAcc !== INITIAL_VALUE)
  4317. return innerAcc;
  4318. // Toggle pending flag if any values haven't been set yet
  4319. if (val === INITIAL_VALUE)
  4320. isPending = true;
  4321. // Any other return values are only valid if we haven't yet hit a pending call.
  4322. // This guarantees that in the case of a guard at the bottom of the tree that
  4323. // returns a redirect, we will wait for the higher priority guard at the top to
  4324. // finish before performing the redirect.
  4325. if (!isPending) {
  4326. // Early return when we hit a `false` value as that should always cancel
  4327. // navigation
  4328. if (val === false)
  4329. return val;
  4330. if (i === list.length - 1 || isUrlTree(val)) {
  4331. return val;
  4332. }
  4333. }
  4334. return innerAcc;
  4335. }), acc);
  4336. }), INITIAL_VALUE), filter((/**
  4337. * @param {?} item
  4338. * @return {?}
  4339. */
  4340. item => item !== INITIAL_VALUE)), map((/**
  4341. * @param {?} item
  4342. * @return {?}
  4343. */
  4344. item => isUrlTree(item) ? item : item === true)), //
  4345. take(1))));
  4346. }));
  4347. }
  4348. /**
  4349. * @fileoverview added by tsickle
  4350. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4351. */
  4352. /**
  4353. * @param {?} moduleInjector
  4354. * @param {?=} forwardEvent
  4355. * @return {?}
  4356. */
  4357. function checkGuards(moduleInjector, forwardEvent) {
  4358. return (/**
  4359. * @param {?} source
  4360. * @return {?}
  4361. */
  4362. function (source) {
  4363. return source.pipe(mergeMap((/**
  4364. * @param {?} t
  4365. * @return {?}
  4366. */
  4367. t => {
  4368. const { targetSnapshot, currentSnapshot, guards: { canActivateChecks, canDeactivateChecks } } = t;
  4369. if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
  4370. return of(Object.assign({}, t, { guardsResult: true }));
  4371. }
  4372. return runCanDeactivateChecks(canDeactivateChecks, (/** @type {?} */ (targetSnapshot)), currentSnapshot, moduleInjector)
  4373. .pipe(mergeMap((/**
  4374. * @param {?} canDeactivate
  4375. * @return {?}
  4376. */
  4377. canDeactivate => {
  4378. return canDeactivate && isBoolean(canDeactivate) ?
  4379. runCanActivateChecks((/** @type {?} */ (targetSnapshot)), canActivateChecks, moduleInjector, forwardEvent) :
  4380. of(canDeactivate);
  4381. })), map((/**
  4382. * @param {?} guardsResult
  4383. * @return {?}
  4384. */
  4385. guardsResult => (Object.assign({}, t, { guardsResult })))));
  4386. })));
  4387. });
  4388. }
  4389. /**
  4390. * @param {?} checks
  4391. * @param {?} futureRSS
  4392. * @param {?} currRSS
  4393. * @param {?} moduleInjector
  4394. * @return {?}
  4395. */
  4396. function runCanDeactivateChecks(checks, futureRSS, currRSS, moduleInjector) {
  4397. return from(checks).pipe(mergeMap((/**
  4398. * @param {?} check
  4399. * @return {?}
  4400. */
  4401. check => runCanDeactivate(check.component, check.route, currRSS, futureRSS, moduleInjector))), first((/**
  4402. * @param {?} result
  4403. * @return {?}
  4404. */
  4405. result => { return result !== true; }), (/** @type {?} */ (true))));
  4406. }
  4407. /**
  4408. * @param {?} futureSnapshot
  4409. * @param {?} checks
  4410. * @param {?} moduleInjector
  4411. * @param {?=} forwardEvent
  4412. * @return {?}
  4413. */
  4414. function runCanActivateChecks(futureSnapshot, checks, moduleInjector, forwardEvent) {
  4415. return from(checks).pipe(concatMap((/**
  4416. * @param {?} check
  4417. * @return {?}
  4418. */
  4419. (check) => {
  4420. return from([
  4421. fireChildActivationStart(check.route.parent, forwardEvent),
  4422. fireActivationStart(check.route, forwardEvent),
  4423. runCanActivateChild(futureSnapshot, check.path, moduleInjector),
  4424. runCanActivate(futureSnapshot, check.route, moduleInjector)
  4425. ])
  4426. .pipe(concatAll(), first((/**
  4427. * @param {?} result
  4428. * @return {?}
  4429. */
  4430. result => {
  4431. return result !== true;
  4432. }), (/** @type {?} */ (true))));
  4433. })), first((/**
  4434. * @param {?} result
  4435. * @return {?}
  4436. */
  4437. result => { return result !== true; }), (/** @type {?} */ (true))));
  4438. }
  4439. /**
  4440. * This should fire off `ActivationStart` events for each route being activated at this
  4441. * level.
  4442. * In other words, if you're activating `a` and `b` below, `path` will contain the
  4443. * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
  4444. * return
  4445. * `true` so checks continue to run.
  4446. * @param {?} snapshot
  4447. * @param {?=} forwardEvent
  4448. * @return {?}
  4449. */
  4450. function fireActivationStart(snapshot, forwardEvent) {
  4451. if (snapshot !== null && forwardEvent) {
  4452. forwardEvent(new ActivationStart(snapshot));
  4453. }
  4454. return of(true);
  4455. }
  4456. /**
  4457. * This should fire off `ChildActivationStart` events for each route being activated at this
  4458. * level.
  4459. * In other words, if you're activating `a` and `b` below, `path` will contain the
  4460. * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
  4461. * return
  4462. * `true` so checks continue to run.
  4463. * @param {?} snapshot
  4464. * @param {?=} forwardEvent
  4465. * @return {?}
  4466. */
  4467. function fireChildActivationStart(snapshot, forwardEvent) {
  4468. if (snapshot !== null && forwardEvent) {
  4469. forwardEvent(new ChildActivationStart(snapshot));
  4470. }
  4471. return of(true);
  4472. }
  4473. /**
  4474. * @param {?} futureRSS
  4475. * @param {?} futureARS
  4476. * @param {?} moduleInjector
  4477. * @return {?}
  4478. */
  4479. function runCanActivate(futureRSS, futureARS, moduleInjector) {
  4480. /** @type {?} */
  4481. const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
  4482. if (!canActivate || canActivate.length === 0)
  4483. return of(true);
  4484. /** @type {?} */
  4485. const canActivateObservables = canActivate.map((/**
  4486. * @param {?} c
  4487. * @return {?}
  4488. */
  4489. (c) => {
  4490. return defer((/**
  4491. * @return {?}
  4492. */
  4493. () => {
  4494. /** @type {?} */
  4495. const guard = getToken(c, futureARS, moduleInjector);
  4496. /** @type {?} */
  4497. let observable;
  4498. if (isCanActivate(guard)) {
  4499. observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
  4500. }
  4501. else if (isFunction(guard)) {
  4502. observable = wrapIntoObservable(guard(futureARS, futureRSS));
  4503. }
  4504. else {
  4505. throw new Error('Invalid CanActivate guard');
  4506. }
  4507. return observable.pipe(first());
  4508. }));
  4509. }));
  4510. return of(canActivateObservables).pipe(prioritizedGuardValue());
  4511. }
  4512. /**
  4513. * @param {?} futureRSS
  4514. * @param {?} path
  4515. * @param {?} moduleInjector
  4516. * @return {?}
  4517. */
  4518. function runCanActivateChild(futureRSS, path, moduleInjector) {
  4519. /** @type {?} */
  4520. const futureARS = path[path.length - 1];
  4521. /** @type {?} */
  4522. const canActivateChildGuards = path.slice(0, path.length - 1)
  4523. .reverse()
  4524. .map((/**
  4525. * @param {?} p
  4526. * @return {?}
  4527. */
  4528. p => getCanActivateChild(p)))
  4529. .filter((/**
  4530. * @param {?} _
  4531. * @return {?}
  4532. */
  4533. _ => _ !== null));
  4534. /** @type {?} */
  4535. const canActivateChildGuardsMapped = canActivateChildGuards.map((/**
  4536. * @param {?} d
  4537. * @return {?}
  4538. */
  4539. (d) => {
  4540. return defer((/**
  4541. * @return {?}
  4542. */
  4543. () => {
  4544. /** @type {?} */
  4545. const guardsMapped = d.guards.map((/**
  4546. * @param {?} c
  4547. * @return {?}
  4548. */
  4549. (c) => {
  4550. /** @type {?} */
  4551. const guard = getToken(c, d.node, moduleInjector);
  4552. /** @type {?} */
  4553. let observable;
  4554. if (isCanActivateChild(guard)) {
  4555. observable = wrapIntoObservable(guard.canActivateChild(futureARS, futureRSS));
  4556. }
  4557. else if (isFunction(guard)) {
  4558. observable = wrapIntoObservable(guard(futureARS, futureRSS));
  4559. }
  4560. else {
  4561. throw new Error('Invalid CanActivateChild guard');
  4562. }
  4563. return observable.pipe(first());
  4564. }));
  4565. return of(guardsMapped).pipe(prioritizedGuardValue());
  4566. }));
  4567. }));
  4568. return of(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
  4569. }
  4570. /**
  4571. * @param {?} component
  4572. * @param {?} currARS
  4573. * @param {?} currRSS
  4574. * @param {?} futureRSS
  4575. * @param {?} moduleInjector
  4576. * @return {?}
  4577. */
  4578. function runCanDeactivate(component, currARS, currRSS, futureRSS, moduleInjector) {
  4579. /** @type {?} */
  4580. const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
  4581. if (!canDeactivate || canDeactivate.length === 0)
  4582. return of(true);
  4583. /** @type {?} */
  4584. const canDeactivateObservables = canDeactivate.map((/**
  4585. * @param {?} c
  4586. * @return {?}
  4587. */
  4588. (c) => {
  4589. /** @type {?} */
  4590. const guard = getToken(c, currARS, moduleInjector);
  4591. /** @type {?} */
  4592. let observable;
  4593. if (isCanDeactivate(guard)) {
  4594. observable =
  4595. wrapIntoObservable(guard.canDeactivate((/** @type {?} */ (component)), currARS, currRSS, futureRSS));
  4596. }
  4597. else if (isFunction(guard)) {
  4598. observable = wrapIntoObservable(guard(component, currARS, currRSS, futureRSS));
  4599. }
  4600. else {
  4601. throw new Error('Invalid CanDeactivate guard');
  4602. }
  4603. return observable.pipe(first());
  4604. }));
  4605. return of(canDeactivateObservables).pipe(prioritizedGuardValue());
  4606. }
  4607. /**
  4608. * @fileoverview added by tsickle
  4609. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4610. */
  4611. class NoMatch$1 {
  4612. }
  4613. /**
  4614. * @param {?} rootComponentType
  4615. * @param {?} config
  4616. * @param {?} urlTree
  4617. * @param {?} url
  4618. * @param {?=} paramsInheritanceStrategy
  4619. * @param {?=} relativeLinkResolution
  4620. * @return {?}
  4621. */
  4622. function recognize(rootComponentType, config, urlTree, url, paramsInheritanceStrategy = 'emptyOnly', relativeLinkResolution = 'legacy') {
  4623. return new Recognizer(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution)
  4624. .recognize();
  4625. }
  4626. class Recognizer {
  4627. /**
  4628. * @param {?} rootComponentType
  4629. * @param {?} config
  4630. * @param {?} urlTree
  4631. * @param {?} url
  4632. * @param {?} paramsInheritanceStrategy
  4633. * @param {?} relativeLinkResolution
  4634. */
  4635. constructor(rootComponentType, config, urlTree, url, paramsInheritanceStrategy, relativeLinkResolution) {
  4636. this.rootComponentType = rootComponentType;
  4637. this.config = config;
  4638. this.urlTree = urlTree;
  4639. this.url = url;
  4640. this.paramsInheritanceStrategy = paramsInheritanceStrategy;
  4641. this.relativeLinkResolution = relativeLinkResolution;
  4642. }
  4643. /**
  4644. * @return {?}
  4645. */
  4646. recognize() {
  4647. try {
  4648. /** @type {?} */
  4649. const rootSegmentGroup = split$1(this.urlTree.root, [], [], this.config, this.relativeLinkResolution).segmentGroup;
  4650. /** @type {?} */
  4651. const children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET);
  4652. /** @type {?} */
  4653. const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(Object.assign({}, this.urlTree.queryParams)), (/** @type {?} */ (this.urlTree.fragment)), {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {});
  4654. /** @type {?} */
  4655. const rootNode = new TreeNode(root, children);
  4656. /** @type {?} */
  4657. const routeState = new RouterStateSnapshot(this.url, rootNode);
  4658. this.inheritParamsAndData(routeState._root);
  4659. return of(routeState);
  4660. }
  4661. catch (e) {
  4662. return new Observable((/**
  4663. * @param {?} obs
  4664. * @return {?}
  4665. */
  4666. (obs) => obs.error(e)));
  4667. }
  4668. }
  4669. /**
  4670. * @param {?} routeNode
  4671. * @return {?}
  4672. */
  4673. inheritParamsAndData(routeNode) {
  4674. /** @type {?} */
  4675. const route = routeNode.value;
  4676. /** @type {?} */
  4677. const i = inheritedParamsDataResolve(route, this.paramsInheritanceStrategy);
  4678. route.params = Object.freeze(i.params);
  4679. route.data = Object.freeze(i.data);
  4680. routeNode.children.forEach((/**
  4681. * @param {?} n
  4682. * @return {?}
  4683. */
  4684. n => this.inheritParamsAndData(n)));
  4685. }
  4686. /**
  4687. * @param {?} config
  4688. * @param {?} segmentGroup
  4689. * @param {?} outlet
  4690. * @return {?}
  4691. */
  4692. processSegmentGroup(config, segmentGroup, outlet) {
  4693. if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
  4694. return this.processChildren(config, segmentGroup);
  4695. }
  4696. return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet);
  4697. }
  4698. /**
  4699. * @param {?} config
  4700. * @param {?} segmentGroup
  4701. * @return {?}
  4702. */
  4703. processChildren(config, segmentGroup) {
  4704. /** @type {?} */
  4705. const children = mapChildrenIntoArray(segmentGroup, (/**
  4706. * @param {?} child
  4707. * @param {?} childOutlet
  4708. * @return {?}
  4709. */
  4710. (child, childOutlet) => this.processSegmentGroup(config, child, childOutlet)));
  4711. checkOutletNameUniqueness(children);
  4712. sortActivatedRouteSnapshots(children);
  4713. return children;
  4714. }
  4715. /**
  4716. * @param {?} config
  4717. * @param {?} segmentGroup
  4718. * @param {?} segments
  4719. * @param {?} outlet
  4720. * @return {?}
  4721. */
  4722. processSegment(config, segmentGroup, segments, outlet) {
  4723. for (const r of config) {
  4724. try {
  4725. return this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet);
  4726. }
  4727. catch (e) {
  4728. if (!(e instanceof NoMatch$1))
  4729. throw e;
  4730. }
  4731. }
  4732. if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) {
  4733. return [];
  4734. }
  4735. throw new NoMatch$1();
  4736. }
  4737. /**
  4738. * @private
  4739. * @param {?} segmentGroup
  4740. * @param {?} segments
  4741. * @param {?} outlet
  4742. * @return {?}
  4743. */
  4744. noLeftoversInUrl(segmentGroup, segments, outlet) {
  4745. return segments.length === 0 && !segmentGroup.children[outlet];
  4746. }
  4747. /**
  4748. * @param {?} route
  4749. * @param {?} rawSegment
  4750. * @param {?} segments
  4751. * @param {?} outlet
  4752. * @return {?}
  4753. */
  4754. processSegmentAgainstRoute(route, rawSegment, segments, outlet) {
  4755. if (route.redirectTo)
  4756. throw new NoMatch$1();
  4757. if ((route.outlet || PRIMARY_OUTLET) !== outlet)
  4758. throw new NoMatch$1();
  4759. /** @type {?} */
  4760. let snapshot;
  4761. /** @type {?} */
  4762. let consumedSegments = [];
  4763. /** @type {?} */
  4764. let rawSlicedSegments = [];
  4765. if (route.path === '**') {
  4766. /** @type {?} */
  4767. const params = segments.length > 0 ? (/** @type {?} */ (last(segments))).parameters : {};
  4768. snapshot = new ActivatedRouteSnapshot(segments, params, Object.freeze(Object.assign({}, this.urlTree.queryParams)), (/** @type {?} */ (this.urlTree.fragment)), getData(route), outlet, (/** @type {?} */ (route.component)), route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + segments.length, getResolve(route));
  4769. }
  4770. else {
  4771. /** @type {?} */
  4772. const result = match$1(rawSegment, route, segments);
  4773. consumedSegments = result.consumedSegments;
  4774. rawSlicedSegments = segments.slice(result.lastChild);
  4775. snapshot = new ActivatedRouteSnapshot(consumedSegments, result.parameters, Object.freeze(Object.assign({}, this.urlTree.queryParams)), (/** @type {?} */ (this.urlTree.fragment)), getData(route), outlet, (/** @type {?} */ (route.component)), route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + consumedSegments.length, getResolve(route));
  4776. }
  4777. /** @type {?} */
  4778. const childConfig = getChildConfig(route);
  4779. const { segmentGroup, slicedSegments } = split$1(rawSegment, consumedSegments, rawSlicedSegments, childConfig, this.relativeLinkResolution);
  4780. if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
  4781. /** @type {?} */
  4782. const children = this.processChildren(childConfig, segmentGroup);
  4783. return [new TreeNode(snapshot, children)];
  4784. }
  4785. if (childConfig.length === 0 && slicedSegments.length === 0) {
  4786. return [new TreeNode(snapshot, [])];
  4787. }
  4788. /** @type {?} */
  4789. const children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET);
  4790. return [new TreeNode(snapshot, children)];
  4791. }
  4792. }
  4793. /**
  4794. * @param {?} nodes
  4795. * @return {?}
  4796. */
  4797. function sortActivatedRouteSnapshots(nodes) {
  4798. nodes.sort((/**
  4799. * @param {?} a
  4800. * @param {?} b
  4801. * @return {?}
  4802. */
  4803. (a, b) => {
  4804. if (a.value.outlet === PRIMARY_OUTLET)
  4805. return -1;
  4806. if (b.value.outlet === PRIMARY_OUTLET)
  4807. return 1;
  4808. return a.value.outlet.localeCompare(b.value.outlet);
  4809. }));
  4810. }
  4811. /**
  4812. * @param {?} route
  4813. * @return {?}
  4814. */
  4815. function getChildConfig(route) {
  4816. if (route.children) {
  4817. return route.children;
  4818. }
  4819. if (route.loadChildren) {
  4820. return (/** @type {?} */ (route._loadedConfig)).routes;
  4821. }
  4822. return [];
  4823. }
  4824. /**
  4825. * @param {?} segmentGroup
  4826. * @param {?} route
  4827. * @param {?} segments
  4828. * @return {?}
  4829. */
  4830. function match$1(segmentGroup, route, segments) {
  4831. if (route.path === '') {
  4832. if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
  4833. throw new NoMatch$1();
  4834. }
  4835. return { consumedSegments: [], lastChild: 0, parameters: {} };
  4836. }
  4837. /** @type {?} */
  4838. const matcher = route.matcher || defaultUrlMatcher;
  4839. /** @type {?} */
  4840. const res = matcher(segments, segmentGroup, route);
  4841. if (!res)
  4842. throw new NoMatch$1();
  4843. /** @type {?} */
  4844. const posParams = {};
  4845. forEach((/** @type {?} */ (res.posParams)), (/**
  4846. * @param {?} v
  4847. * @param {?} k
  4848. * @return {?}
  4849. */
  4850. (v, k) => { posParams[k] = v.path; }));
  4851. /** @type {?} */
  4852. const parameters = res.consumed.length > 0 ? Object.assign({}, posParams, res.consumed[res.consumed.length - 1].parameters) :
  4853. posParams;
  4854. return { consumedSegments: res.consumed, lastChild: res.consumed.length, parameters };
  4855. }
  4856. /**
  4857. * @param {?} nodes
  4858. * @return {?}
  4859. */
  4860. function checkOutletNameUniqueness(nodes) {
  4861. /** @type {?} */
  4862. const names = {};
  4863. nodes.forEach((/**
  4864. * @param {?} n
  4865. * @return {?}
  4866. */
  4867. n => {
  4868. /** @type {?} */
  4869. const routeWithSameOutletName = names[n.value.outlet];
  4870. if (routeWithSameOutletName) {
  4871. /** @type {?} */
  4872. const p = routeWithSameOutletName.url.map((/**
  4873. * @param {?} s
  4874. * @return {?}
  4875. */
  4876. s => s.toString())).join('/');
  4877. /** @type {?} */
  4878. const c = n.value.url.map((/**
  4879. * @param {?} s
  4880. * @return {?}
  4881. */
  4882. s => s.toString())).join('/');
  4883. throw new Error(`Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
  4884. }
  4885. names[n.value.outlet] = n.value;
  4886. }));
  4887. }
  4888. /**
  4889. * @param {?} segmentGroup
  4890. * @return {?}
  4891. */
  4892. function getSourceSegmentGroup(segmentGroup) {
  4893. /** @type {?} */
  4894. let s = segmentGroup;
  4895. while (s._sourceSegment) {
  4896. s = s._sourceSegment;
  4897. }
  4898. return s;
  4899. }
  4900. /**
  4901. * @param {?} segmentGroup
  4902. * @return {?}
  4903. */
  4904. function getPathIndexShift(segmentGroup) {
  4905. /** @type {?} */
  4906. let s = segmentGroup;
  4907. /** @type {?} */
  4908. let res = (s._segmentIndexShift ? s._segmentIndexShift : 0);
  4909. while (s._sourceSegment) {
  4910. s = s._sourceSegment;
  4911. res += (s._segmentIndexShift ? s._segmentIndexShift : 0);
  4912. }
  4913. return res - 1;
  4914. }
  4915. /**
  4916. * @param {?} segmentGroup
  4917. * @param {?} consumedSegments
  4918. * @param {?} slicedSegments
  4919. * @param {?} config
  4920. * @param {?} relativeLinkResolution
  4921. * @return {?}
  4922. */
  4923. function split$1(segmentGroup, consumedSegments, slicedSegments, config, relativeLinkResolution) {
  4924. if (slicedSegments.length > 0 &&
  4925. containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
  4926. /** @type {?} */
  4927. const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
  4928. s._sourceSegment = segmentGroup;
  4929. s._segmentIndexShift = consumedSegments.length;
  4930. return { segmentGroup: s, slicedSegments: [] };
  4931. }
  4932. if (slicedSegments.length === 0 &&
  4933. containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
  4934. /** @type {?} */
  4935. const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, config, segmentGroup.children, relativeLinkResolution));
  4936. s._sourceSegment = segmentGroup;
  4937. s._segmentIndexShift = consumedSegments.length;
  4938. return { segmentGroup: s, slicedSegments };
  4939. }
  4940. /** @type {?} */
  4941. const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
  4942. s._sourceSegment = segmentGroup;
  4943. s._segmentIndexShift = consumedSegments.length;
  4944. return { segmentGroup: s, slicedSegments };
  4945. }
  4946. /**
  4947. * @param {?} segmentGroup
  4948. * @param {?} consumedSegments
  4949. * @param {?} slicedSegments
  4950. * @param {?} routes
  4951. * @param {?} children
  4952. * @param {?} relativeLinkResolution
  4953. * @return {?}
  4954. */
  4955. function addEmptyPathsToChildrenIfNeeded(segmentGroup, consumedSegments, slicedSegments, routes, children, relativeLinkResolution) {
  4956. /** @type {?} */
  4957. const res = {};
  4958. for (const r of routes) {
  4959. if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet$1(r)]) {
  4960. /** @type {?} */
  4961. const s = new UrlSegmentGroup([], {});
  4962. s._sourceSegment = segmentGroup;
  4963. if (relativeLinkResolution === 'legacy') {
  4964. s._segmentIndexShift = segmentGroup.segments.length;
  4965. }
  4966. else {
  4967. s._segmentIndexShift = consumedSegments.length;
  4968. }
  4969. res[getOutlet$1(r)] = s;
  4970. }
  4971. }
  4972. return Object.assign({}, children, res);
  4973. }
  4974. /**
  4975. * @param {?} segmentGroup
  4976. * @param {?} consumedSegments
  4977. * @param {?} routes
  4978. * @param {?} primarySegment
  4979. * @return {?}
  4980. */
  4981. function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) {
  4982. /** @type {?} */
  4983. const res = {};
  4984. res[PRIMARY_OUTLET] = primarySegment;
  4985. primarySegment._sourceSegment = segmentGroup;
  4986. primarySegment._segmentIndexShift = consumedSegments.length;
  4987. for (const r of routes) {
  4988. if (r.path === '' && getOutlet$1(r) !== PRIMARY_OUTLET) {
  4989. /** @type {?} */
  4990. const s = new UrlSegmentGroup([], {});
  4991. s._sourceSegment = segmentGroup;
  4992. s._segmentIndexShift = consumedSegments.length;
  4993. res[getOutlet$1(r)] = s;
  4994. }
  4995. }
  4996. return res;
  4997. }
  4998. /**
  4999. * @param {?} segmentGroup
  5000. * @param {?} slicedSegments
  5001. * @param {?} routes
  5002. * @return {?}
  5003. */
  5004. function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
  5005. return routes.some((/**
  5006. * @param {?} r
  5007. * @return {?}
  5008. */
  5009. r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet$1(r) !== PRIMARY_OUTLET));
  5010. }
  5011. /**
  5012. * @param {?} segmentGroup
  5013. * @param {?} slicedSegments
  5014. * @param {?} routes
  5015. * @return {?}
  5016. */
  5017. function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
  5018. return routes.some((/**
  5019. * @param {?} r
  5020. * @return {?}
  5021. */
  5022. r => emptyPathMatch(segmentGroup, slicedSegments, r)));
  5023. }
  5024. /**
  5025. * @param {?} segmentGroup
  5026. * @param {?} slicedSegments
  5027. * @param {?} r
  5028. * @return {?}
  5029. */
  5030. function emptyPathMatch(segmentGroup, slicedSegments, r) {
  5031. if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
  5032. return false;
  5033. }
  5034. return r.path === '' && r.redirectTo === undefined;
  5035. }
  5036. /**
  5037. * @param {?} route
  5038. * @return {?}
  5039. */
  5040. function getOutlet$1(route) {
  5041. return route.outlet || PRIMARY_OUTLET;
  5042. }
  5043. /**
  5044. * @param {?} route
  5045. * @return {?}
  5046. */
  5047. function getData(route) {
  5048. return route.data || {};
  5049. }
  5050. /**
  5051. * @param {?} route
  5052. * @return {?}
  5053. */
  5054. function getResolve(route) {
  5055. return route.resolve || {};
  5056. }
  5057. /**
  5058. * @fileoverview added by tsickle
  5059. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5060. */
  5061. /**
  5062. * @param {?} rootComponentType
  5063. * @param {?} config
  5064. * @param {?} serializer
  5065. * @param {?} paramsInheritanceStrategy
  5066. * @param {?} relativeLinkResolution
  5067. * @return {?}
  5068. */
  5069. function recognize$1(rootComponentType, config, serializer, paramsInheritanceStrategy, relativeLinkResolution) {
  5070. return (/**
  5071. * @param {?} source
  5072. * @return {?}
  5073. */
  5074. function (source) {
  5075. return source.pipe(mergeMap((/**
  5076. * @param {?} t
  5077. * @return {?}
  5078. */
  5079. t => recognize(rootComponentType, config, t.urlAfterRedirects, serializer(t.urlAfterRedirects), paramsInheritanceStrategy, relativeLinkResolution)
  5080. .pipe(map((/**
  5081. * @param {?} targetSnapshot
  5082. * @return {?}
  5083. */
  5084. targetSnapshot => (Object.assign({}, t, { targetSnapshot }))))))));
  5085. });
  5086. }
  5087. /**
  5088. * @fileoverview added by tsickle
  5089. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5090. */
  5091. /**
  5092. * @param {?} paramsInheritanceStrategy
  5093. * @param {?} moduleInjector
  5094. * @return {?}
  5095. */
  5096. function resolveData(paramsInheritanceStrategy, moduleInjector) {
  5097. return (/**
  5098. * @param {?} source
  5099. * @return {?}
  5100. */
  5101. function (source) {
  5102. return source.pipe(mergeMap((/**
  5103. * @param {?} t
  5104. * @return {?}
  5105. */
  5106. t => {
  5107. const { targetSnapshot, guards: { canActivateChecks } } = t;
  5108. if (!canActivateChecks.length) {
  5109. return of(t);
  5110. }
  5111. return from(canActivateChecks)
  5112. .pipe(concatMap((/**
  5113. * @param {?} check
  5114. * @return {?}
  5115. */
  5116. check => runResolve(check.route, (/** @type {?} */ (targetSnapshot)), paramsInheritanceStrategy, moduleInjector))), reduce((/**
  5117. * @param {?} _
  5118. * @param {?} __
  5119. * @return {?}
  5120. */
  5121. (_, __) => _)), map((/**
  5122. * @param {?} _
  5123. * @return {?}
  5124. */
  5125. _ => t)));
  5126. })));
  5127. });
  5128. }
  5129. /**
  5130. * @param {?} futureARS
  5131. * @param {?} futureRSS
  5132. * @param {?} paramsInheritanceStrategy
  5133. * @param {?} moduleInjector
  5134. * @return {?}
  5135. */
  5136. function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, moduleInjector) {
  5137. /** @type {?} */
  5138. const resolve = futureARS._resolve;
  5139. return resolveNode(resolve, futureARS, futureRSS, moduleInjector)
  5140. .pipe(map((/**
  5141. * @param {?} resolvedData
  5142. * @return {?}
  5143. */
  5144. (resolvedData) => {
  5145. futureARS._resolvedData = resolvedData;
  5146. futureARS.data = Object.assign({}, futureARS.data, inheritedParamsDataResolve(futureARS, paramsInheritanceStrategy).resolve);
  5147. return null;
  5148. })));
  5149. }
  5150. /**
  5151. * @param {?} resolve
  5152. * @param {?} futureARS
  5153. * @param {?} futureRSS
  5154. * @param {?} moduleInjector
  5155. * @return {?}
  5156. */
  5157. function resolveNode(resolve, futureARS, futureRSS, moduleInjector) {
  5158. /** @type {?} */
  5159. const keys = Object.keys(resolve);
  5160. if (keys.length === 0) {
  5161. return of({});
  5162. }
  5163. if (keys.length === 1) {
  5164. /** @type {?} */
  5165. const key = keys[0];
  5166. return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
  5167. .pipe(map((/**
  5168. * @param {?} value
  5169. * @return {?}
  5170. */
  5171. (value) => { return { [key]: value }; })));
  5172. }
  5173. /** @type {?} */
  5174. const data = {};
  5175. /** @type {?} */
  5176. const runningResolvers$ = from(keys).pipe(mergeMap((/**
  5177. * @param {?} key
  5178. * @return {?}
  5179. */
  5180. (key) => {
  5181. return getResolver(resolve[key], futureARS, futureRSS, moduleInjector)
  5182. .pipe(map((/**
  5183. * @param {?} value
  5184. * @return {?}
  5185. */
  5186. (value) => {
  5187. data[key] = value;
  5188. return value;
  5189. })));
  5190. })));
  5191. return runningResolvers$.pipe(last$1(), map((/**
  5192. * @return {?}
  5193. */
  5194. () => data)));
  5195. }
  5196. /**
  5197. * @param {?} injectionToken
  5198. * @param {?} futureARS
  5199. * @param {?} futureRSS
  5200. * @param {?} moduleInjector
  5201. * @return {?}
  5202. */
  5203. function getResolver(injectionToken, futureARS, futureRSS, moduleInjector) {
  5204. /** @type {?} */
  5205. const resolver = getToken(injectionToken, futureARS, moduleInjector);
  5206. return resolver.resolve ? wrapIntoObservable(resolver.resolve(futureARS, futureRSS)) :
  5207. wrapIntoObservable(resolver(futureARS, futureRSS));
  5208. }
  5209. /**
  5210. * @fileoverview added by tsickle
  5211. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5212. */
  5213. /**
  5214. * Perform a side effect through a switchMap for every emission on the source Observable,
  5215. * but return an Observable that is identical to the source. It's essentially the same as
  5216. * the `tap` operator, but if the side effectful `next` function returns an ObservableInput,
  5217. * it will wait before continuing with the original value.
  5218. * @template T
  5219. * @param {?} next
  5220. * @return {?}
  5221. */
  5222. function switchTap(next) {
  5223. return (/**
  5224. * @param {?} source
  5225. * @return {?}
  5226. */
  5227. function (source) {
  5228. return source.pipe(switchMap((/**
  5229. * @param {?} v
  5230. * @return {?}
  5231. */
  5232. v => {
  5233. /** @type {?} */
  5234. const nextResult = next(v);
  5235. if (nextResult) {
  5236. return from(nextResult).pipe(map((/**
  5237. * @return {?}
  5238. */
  5239. () => v)));
  5240. }
  5241. return from([v]);
  5242. })));
  5243. });
  5244. }
  5245. /**
  5246. * @fileoverview added by tsickle
  5247. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5248. */
  5249. /**
  5250. * @license
  5251. * Copyright Google Inc. All Rights Reserved.
  5252. *
  5253. * Use of this source code is governed by an MIT-style license that can be
  5254. * found in the LICENSE file at https://angular.io/license
  5255. */
  5256. /**
  5257. * \@description
  5258. *
  5259. * Provides a way to customize when activated routes get reused.
  5260. *
  5261. * \@publicApi
  5262. * @abstract
  5263. */
  5264. class RouteReuseStrategy {
  5265. }
  5266. /**
  5267. * Does not detach any subtrees. Reuses routes as long as their route config is the same.
  5268. */
  5269. class DefaultRouteReuseStrategy {
  5270. /**
  5271. * @param {?} route
  5272. * @return {?}
  5273. */
  5274. shouldDetach(route) { return false; }
  5275. /**
  5276. * @param {?} route
  5277. * @param {?} detachedTree
  5278. * @return {?}
  5279. */
  5280. store(route, detachedTree) { }
  5281. /**
  5282. * @param {?} route
  5283. * @return {?}
  5284. */
  5285. shouldAttach(route) { return false; }
  5286. /**
  5287. * @param {?} route
  5288. * @return {?}
  5289. */
  5290. retrieve(route) { return null; }
  5291. /**
  5292. * @param {?} future
  5293. * @param {?} curr
  5294. * @return {?}
  5295. */
  5296. shouldReuseRoute(future, curr) {
  5297. return future.routeConfig === curr.routeConfig;
  5298. }
  5299. }
  5300. /**
  5301. * @fileoverview added by tsickle
  5302. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5303. */
  5304. /**
  5305. * \@docsNotRequired
  5306. * \@publicApi
  5307. * @type {?}
  5308. */
  5309. const ROUTES = new InjectionToken('ROUTES');
  5310. class RouterConfigLoader {
  5311. /**
  5312. * @param {?} loader
  5313. * @param {?} compiler
  5314. * @param {?=} onLoadStartListener
  5315. * @param {?=} onLoadEndListener
  5316. */
  5317. constructor(loader, compiler, onLoadStartListener, onLoadEndListener) {
  5318. this.loader = loader;
  5319. this.compiler = compiler;
  5320. this.onLoadStartListener = onLoadStartListener;
  5321. this.onLoadEndListener = onLoadEndListener;
  5322. }
  5323. /**
  5324. * @param {?} parentInjector
  5325. * @param {?} route
  5326. * @return {?}
  5327. */
  5328. load(parentInjector, route) {
  5329. if (this.onLoadStartListener) {
  5330. this.onLoadStartListener(route);
  5331. }
  5332. /** @type {?} */
  5333. const moduleFactory$ = this.loadModuleFactory((/** @type {?} */ (route.loadChildren)));
  5334. return moduleFactory$.pipe(map((/**
  5335. * @param {?} factory
  5336. * @return {?}
  5337. */
  5338. (factory) => {
  5339. if (this.onLoadEndListener) {
  5340. this.onLoadEndListener(route);
  5341. }
  5342. /** @type {?} */
  5343. const module = factory.create(parentInjector);
  5344. return new LoadedRouterConfig(flatten(module.injector.get(ROUTES)).map(standardizeConfig), module);
  5345. })));
  5346. }
  5347. /**
  5348. * @private
  5349. * @param {?} loadChildren
  5350. * @return {?}
  5351. */
  5352. loadModuleFactory(loadChildren) {
  5353. if (typeof loadChildren === 'string') {
  5354. return from(this.loader.load(loadChildren));
  5355. }
  5356. else {
  5357. return wrapIntoObservable(loadChildren()).pipe(mergeMap((/**
  5358. * @param {?} t
  5359. * @return {?}
  5360. */
  5361. (t) => {
  5362. if (t instanceof NgModuleFactory) {
  5363. return of(t);
  5364. }
  5365. else {
  5366. return from(this.compiler.compileModuleAsync(t));
  5367. }
  5368. })));
  5369. }
  5370. }
  5371. }
  5372. /**
  5373. * @fileoverview added by tsickle
  5374. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5375. */
  5376. /**
  5377. * @license
  5378. * Copyright Google Inc. All Rights Reserved.
  5379. *
  5380. * Use of this source code is governed by an MIT-style license that can be
  5381. * found in the LICENSE file at https://angular.io/license
  5382. */
  5383. /**
  5384. * \@description
  5385. *
  5386. * Provides a way to migrate AngularJS applications to Angular.
  5387. *
  5388. * \@publicApi
  5389. * @abstract
  5390. */
  5391. class UrlHandlingStrategy {
  5392. }
  5393. /**
  5394. * \@publicApi
  5395. */
  5396. class DefaultUrlHandlingStrategy {
  5397. /**
  5398. * @param {?} url
  5399. * @return {?}
  5400. */
  5401. shouldProcessUrl(url) { return true; }
  5402. /**
  5403. * @param {?} url
  5404. * @return {?}
  5405. */
  5406. extract(url) { return url; }
  5407. /**
  5408. * @param {?} newUrlPart
  5409. * @param {?} wholeUrl
  5410. * @return {?}
  5411. */
  5412. merge(newUrlPart, wholeUrl) { return newUrlPart; }
  5413. }
  5414. /**
  5415. * @fileoverview added by tsickle
  5416. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5417. */
  5418. /**
  5419. * @param {?} error
  5420. * @return {?}
  5421. */
  5422. function defaultErrorHandler(error) {
  5423. throw error;
  5424. }
  5425. /**
  5426. * @param {?} error
  5427. * @param {?} urlSerializer
  5428. * @param {?} url
  5429. * @return {?}
  5430. */
  5431. function defaultMalformedUriErrorHandler(error, urlSerializer, url) {
  5432. return urlSerializer.parse('/');
  5433. }
  5434. /**
  5435. * \@internal
  5436. * @param {?} snapshot
  5437. * @param {?} runExtras
  5438. * @return {?}
  5439. */
  5440. function defaultRouterHook(snapshot, runExtras) {
  5441. return (/** @type {?} */ (of(null)));
  5442. }
  5443. /**
  5444. * \@description
  5445. *
  5446. * An NgModule that provides navigation and URL manipulation capabilities.
  5447. *
  5448. * @see `Route`.
  5449. * @see [Routing and Navigation Guide](guide/router).
  5450. *
  5451. * \@ngModule RouterModule
  5452. *
  5453. * \@publicApi
  5454. */
  5455. class Router {
  5456. /**
  5457. * Creates the router service.
  5458. * @param {?} rootComponentType
  5459. * @param {?} urlSerializer
  5460. * @param {?} rootContexts
  5461. * @param {?} location
  5462. * @param {?} injector
  5463. * @param {?} loader
  5464. * @param {?} compiler
  5465. * @param {?} config
  5466. */
  5467. // TODO: vsavkin make internal after the final is out.
  5468. constructor(rootComponentType, urlSerializer, rootContexts, location, injector, loader, compiler, config) {
  5469. this.rootComponentType = rootComponentType;
  5470. this.urlSerializer = urlSerializer;
  5471. this.rootContexts = rootContexts;
  5472. this.location = location;
  5473. this.config = config;
  5474. this.lastSuccessfulNavigation = null;
  5475. this.currentNavigation = null;
  5476. this.navigationId = 0;
  5477. this.isNgZoneEnabled = false;
  5478. /**
  5479. * An event stream for routing events in this NgModule.
  5480. */
  5481. this.events = new Subject();
  5482. /**
  5483. * A handler for navigation errors in this NgModule.
  5484. */
  5485. this.errorHandler = defaultErrorHandler;
  5486. /**
  5487. * Malformed uri error handler is invoked when `Router.parseUrl(url)` throws an
  5488. * error due to containing an invalid character. The most common case would be a `%` sign
  5489. * that's not encoded and is not part of a percent encoded sequence.
  5490. */
  5491. this.malformedUriErrorHandler = defaultMalformedUriErrorHandler;
  5492. /**
  5493. * True if at least one navigation event has occurred,
  5494. * false otherwise.
  5495. */
  5496. this.navigated = false;
  5497. this.lastSuccessfulId = -1;
  5498. /**
  5499. * Hooks that enable you to pause navigation,
  5500. * either before or after the preactivation phase.
  5501. * Used by `RouterModule`.
  5502. *
  5503. * \@internal
  5504. */
  5505. this.hooks = {
  5506. beforePreactivation: defaultRouterHook,
  5507. afterPreactivation: defaultRouterHook
  5508. };
  5509. /**
  5510. * Extracts and merges URLs. Used for AngularJS to Angular migrations.
  5511. */
  5512. this.urlHandlingStrategy = new DefaultUrlHandlingStrategy();
  5513. /**
  5514. * The strategy for re-using routes.
  5515. */
  5516. this.routeReuseStrategy = new DefaultRouteReuseStrategy();
  5517. /**
  5518. * How to handle a navigation request to the current URL. One of:
  5519. * - `'ignore'` : The router ignores the request.
  5520. * - `'reload'` : The router reloads the URL. Use to implement a "refresh" feature.
  5521. */
  5522. this.onSameUrlNavigation = 'ignore';
  5523. /**
  5524. * How to merge parameters, data, and resolved data from parent to child
  5525. * routes. One of:
  5526. *
  5527. * - `'emptyOnly'` : Inherit parent parameters, data, and resolved data
  5528. * for path-less or component-less routes.
  5529. * - `'always'` : Inherit parent parameters, data, and resolved data
  5530. * for all child routes.
  5531. */
  5532. this.paramsInheritanceStrategy = 'emptyOnly';
  5533. /**
  5534. * Defines when the router updates the browser URL. The default behavior is to update after
  5535. * successful navigation. However, some applications may prefer a mode where the URL gets
  5536. * updated at the beginning of navigation. The most common use case would be updating the
  5537. * URL early so if navigation fails, you can show an error message with the URL that failed.
  5538. * Available options are:
  5539. *
  5540. * - `'deferred'`, the default, updates the browser URL after navigation has finished.
  5541. * - `'eager'`, updates browser URL at the beginning of navigation.
  5542. */
  5543. this.urlUpdateStrategy = 'deferred';
  5544. /**
  5545. * See {\@link RouterModule} for more information.
  5546. */
  5547. this.relativeLinkResolution = 'legacy';
  5548. /** @type {?} */
  5549. const onLoadStart = (/**
  5550. * @param {?} r
  5551. * @return {?}
  5552. */
  5553. (r) => this.triggerEvent(new RouteConfigLoadStart(r)));
  5554. /** @type {?} */
  5555. const onLoadEnd = (/**
  5556. * @param {?} r
  5557. * @return {?}
  5558. */
  5559. (r) => this.triggerEvent(new RouteConfigLoadEnd(r)));
  5560. this.ngModule = injector.get(NgModuleRef);
  5561. this.console = injector.get(ɵConsole);
  5562. /** @type {?} */
  5563. const ngZone = injector.get(NgZone);
  5564. this.isNgZoneEnabled = ngZone instanceof NgZone;
  5565. this.resetConfig(config);
  5566. this.currentUrlTree = createEmptyUrlTree();
  5567. this.rawUrlTree = this.currentUrlTree;
  5568. this.browserUrlTree = this.currentUrlTree;
  5569. this.configLoader = new RouterConfigLoader(loader, compiler, onLoadStart, onLoadEnd);
  5570. this.routerState = createEmptyState(this.currentUrlTree, this.rootComponentType);
  5571. this.transitions = new BehaviorSubject({
  5572. id: 0,
  5573. currentUrlTree: this.currentUrlTree,
  5574. currentRawUrl: this.currentUrlTree,
  5575. extractedUrl: this.urlHandlingStrategy.extract(this.currentUrlTree),
  5576. urlAfterRedirects: this.urlHandlingStrategy.extract(this.currentUrlTree),
  5577. rawUrl: this.currentUrlTree,
  5578. extras: {},
  5579. resolve: null,
  5580. reject: null,
  5581. promise: Promise.resolve(true),
  5582. source: 'imperative',
  5583. restoredState: null,
  5584. currentSnapshot: this.routerState.snapshot,
  5585. targetSnapshot: null,
  5586. currentRouterState: this.routerState,
  5587. targetRouterState: null,
  5588. guards: { canActivateChecks: [], canDeactivateChecks: [] },
  5589. guardsResult: null,
  5590. });
  5591. this.navigations = this.setupNavigations(this.transitions);
  5592. this.processNavigations();
  5593. }
  5594. /**
  5595. * @private
  5596. * @param {?} transitions
  5597. * @return {?}
  5598. */
  5599. setupNavigations(transitions) {
  5600. /** @type {?} */
  5601. const eventsSubject = ((/** @type {?} */ (this.events)));
  5602. return (/** @type {?} */ ((/** @type {?} */ (transitions.pipe(filter((/**
  5603. * @param {?} t
  5604. * @return {?}
  5605. */
  5606. t => t.id !== 0)),
  5607. // Extract URL
  5608. map((/**
  5609. * @param {?} t
  5610. * @return {?}
  5611. */
  5612. t => ((/** @type {?} */ (Object.assign({}, t, { extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) })))))),
  5613. // Using switchMap so we cancel executing navigations when a new one comes in
  5614. switchMap((/**
  5615. * @param {?} t
  5616. * @return {?}
  5617. */
  5618. t => {
  5619. /** @type {?} */
  5620. let completed = false;
  5621. /** @type {?} */
  5622. let errored = false;
  5623. return of(t).pipe(
  5624. // Store the Navigation object
  5625. tap((/**
  5626. * @param {?} t
  5627. * @return {?}
  5628. */
  5629. t => {
  5630. this.currentNavigation = {
  5631. id: t.id,
  5632. initialUrl: t.currentRawUrl,
  5633. extractedUrl: t.extractedUrl,
  5634. trigger: t.source,
  5635. extras: t.extras,
  5636. previousNavigation: this.lastSuccessfulNavigation ? Object.assign({}, this.lastSuccessfulNavigation, { previousNavigation: null }) :
  5637. null
  5638. };
  5639. })), switchMap((/**
  5640. * @param {?} t
  5641. * @return {?}
  5642. */
  5643. t => {
  5644. /** @type {?} */
  5645. const urlTransition = !this.navigated || t.extractedUrl.toString() !== this.browserUrlTree.toString();
  5646. /** @type {?} */
  5647. const processCurrentUrl = (this.onSameUrlNavigation === 'reload' ? true : urlTransition) &&
  5648. this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl);
  5649. if (processCurrentUrl) {
  5650. return of(t).pipe(
  5651. // Fire NavigationStart event
  5652. switchMap((/**
  5653. * @param {?} t
  5654. * @return {?}
  5655. */
  5656. t => {
  5657. /** @type {?} */
  5658. const transition = this.transitions.getValue();
  5659. eventsSubject.next(new NavigationStart(t.id, this.serializeUrl(t.extractedUrl), t.source, t.restoredState));
  5660. if (transition !== this.transitions.getValue()) {
  5661. return EMPTY;
  5662. }
  5663. return [t];
  5664. })),
  5665. // This delay is required to match old behavior that forced navigation to
  5666. // always be async
  5667. switchMap((/**
  5668. * @param {?} t
  5669. * @return {?}
  5670. */
  5671. t => Promise.resolve(t))),
  5672. // ApplyRedirects
  5673. applyRedirects$1(this.ngModule.injector, this.configLoader, this.urlSerializer, this.config),
  5674. // Update the currentNavigation
  5675. tap((/**
  5676. * @param {?} t
  5677. * @return {?}
  5678. */
  5679. t => {
  5680. this.currentNavigation = Object.assign({}, (/** @type {?} */ (this.currentNavigation)), { finalUrl: t.urlAfterRedirects });
  5681. })),
  5682. // Recognize
  5683. recognize$1(this.rootComponentType, this.config, (/**
  5684. * @param {?} url
  5685. * @return {?}
  5686. */
  5687. (url) => this.serializeUrl(url)), this.paramsInheritanceStrategy, this.relativeLinkResolution),
  5688. // Update URL if in `eager` update mode
  5689. tap((/**
  5690. * @param {?} t
  5691. * @return {?}
  5692. */
  5693. t => {
  5694. if (this.urlUpdateStrategy === 'eager') {
  5695. if (!t.extras.skipLocationChange) {
  5696. this.setBrowserUrl(t.urlAfterRedirects, !!t.extras.replaceUrl, t.id, t.extras.state);
  5697. }
  5698. this.browserUrlTree = t.urlAfterRedirects;
  5699. }
  5700. })),
  5701. // Fire RoutesRecognized
  5702. tap((/**
  5703. * @param {?} t
  5704. * @return {?}
  5705. */
  5706. t => {
  5707. /** @type {?} */
  5708. const routesRecognized = new RoutesRecognized(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
  5709. eventsSubject.next(routesRecognized);
  5710. })));
  5711. }
  5712. else {
  5713. /** @type {?} */
  5714. const processPreviousUrl = urlTransition && this.rawUrlTree &&
  5715. this.urlHandlingStrategy.shouldProcessUrl(this.rawUrlTree);
  5716. /* When the current URL shouldn't be processed, but the previous one was, we
  5717. * handle this "error condition" by navigating to the previously successful URL,
  5718. * but leaving the URL intact.*/
  5719. if (processPreviousUrl) {
  5720. const { id, extractedUrl, source, restoredState, extras } = t;
  5721. /** @type {?} */
  5722. const navStart = new NavigationStart(id, this.serializeUrl(extractedUrl), source, restoredState);
  5723. eventsSubject.next(navStart);
  5724. /** @type {?} */
  5725. const targetSnapshot = createEmptyState(extractedUrl, this.rootComponentType).snapshot;
  5726. return of(Object.assign({}, t, { targetSnapshot, urlAfterRedirects: extractedUrl, extras: Object.assign({}, extras, { skipLocationChange: false, replaceUrl: false }) }));
  5727. }
  5728. else {
  5729. /* When neither the current or previous URL can be processed, do nothing other
  5730. * than update router's internal reference to the current "settled" URL. This
  5731. * way the next navigation will be coming from the current URL in the browser.
  5732. */
  5733. this.rawUrlTree = t.rawUrl;
  5734. this.browserUrlTree = t.urlAfterRedirects;
  5735. t.resolve(null);
  5736. return EMPTY;
  5737. }
  5738. }
  5739. })),
  5740. // Before Preactivation
  5741. switchTap((/**
  5742. * @param {?} t
  5743. * @return {?}
  5744. */
  5745. t => {
  5746. const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
  5747. return this.hooks.beforePreactivation((/** @type {?} */ (targetSnapshot)), {
  5748. navigationId,
  5749. appliedUrlTree,
  5750. rawUrlTree,
  5751. skipLocationChange: !!skipLocationChange,
  5752. replaceUrl: !!replaceUrl,
  5753. });
  5754. })),
  5755. // --- GUARDS ---
  5756. tap((/**
  5757. * @param {?} t
  5758. * @return {?}
  5759. */
  5760. t => {
  5761. /** @type {?} */
  5762. const guardsStart = new GuardsCheckStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
  5763. this.triggerEvent(guardsStart);
  5764. })), map((/**
  5765. * @param {?} t
  5766. * @return {?}
  5767. */
  5768. t => (Object.assign({}, t, { guards: getAllRouteGuards((/** @type {?} */ (t.targetSnapshot)), t.currentSnapshot, this.rootContexts) })))), checkGuards(this.ngModule.injector, (/**
  5769. * @param {?} evt
  5770. * @return {?}
  5771. */
  5772. (evt) => this.triggerEvent(evt))), tap((/**
  5773. * @param {?} t
  5774. * @return {?}
  5775. */
  5776. t => {
  5777. if (isUrlTree(t.guardsResult)) {
  5778. /** @type {?} */
  5779. const error = navigationCancelingError(`Redirecting to "${this.serializeUrl(t.guardsResult)}"`);
  5780. error.url = t.guardsResult;
  5781. throw error;
  5782. }
  5783. })), tap((/**
  5784. * @param {?} t
  5785. * @return {?}
  5786. */
  5787. t => {
  5788. /** @type {?} */
  5789. const guardsEnd = new GuardsCheckEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)), !!t.guardsResult);
  5790. this.triggerEvent(guardsEnd);
  5791. })), filter((/**
  5792. * @param {?} t
  5793. * @return {?}
  5794. */
  5795. t => {
  5796. if (!t.guardsResult) {
  5797. this.resetUrlToCurrentUrlTree();
  5798. /** @type {?} */
  5799. const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), '');
  5800. eventsSubject.next(navCancel);
  5801. t.resolve(false);
  5802. return false;
  5803. }
  5804. return true;
  5805. })),
  5806. // --- RESOLVE ---
  5807. switchTap((/**
  5808. * @param {?} t
  5809. * @return {?}
  5810. */
  5811. t => {
  5812. if (t.guards.canActivateChecks.length) {
  5813. return of(t).pipe(tap((/**
  5814. * @param {?} t
  5815. * @return {?}
  5816. */
  5817. t => {
  5818. /** @type {?} */
  5819. const resolveStart = new ResolveStart(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
  5820. this.triggerEvent(resolveStart);
  5821. })), resolveData(this.paramsInheritanceStrategy, this.ngModule.injector), //
  5822. tap((/**
  5823. * @param {?} t
  5824. * @return {?}
  5825. */
  5826. t => {
  5827. /** @type {?} */
  5828. const resolveEnd = new ResolveEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(t.urlAfterRedirects), (/** @type {?} */ (t.targetSnapshot)));
  5829. this.triggerEvent(resolveEnd);
  5830. })));
  5831. }
  5832. return undefined;
  5833. })),
  5834. // --- AFTER PREACTIVATION ---
  5835. switchTap((/**
  5836. * @param {?} t
  5837. * @return {?}
  5838. */
  5839. (t) => {
  5840. const { targetSnapshot, id: navigationId, extractedUrl: appliedUrlTree, rawUrl: rawUrlTree, extras: { skipLocationChange, replaceUrl } } = t;
  5841. return this.hooks.afterPreactivation((/** @type {?} */ (targetSnapshot)), {
  5842. navigationId,
  5843. appliedUrlTree,
  5844. rawUrlTree,
  5845. skipLocationChange: !!skipLocationChange,
  5846. replaceUrl: !!replaceUrl,
  5847. });
  5848. })), map((/**
  5849. * @param {?} t
  5850. * @return {?}
  5851. */
  5852. (t) => {
  5853. /** @type {?} */
  5854. const targetRouterState = createRouterState(this.routeReuseStrategy, (/** @type {?} */ (t.targetSnapshot)), t.currentRouterState);
  5855. return (Object.assign({}, t, { targetRouterState }));
  5856. })),
  5857. /* Once here, we are about to activate syncronously. The assumption is this will
  5858. succeed, and user code may read from the Router service. Therefore before
  5859. activation, we need to update router properties storing the current URL and the
  5860. RouterState, as well as updated the browser URL. All this should happen *before*
  5861. activating. */
  5862. tap((/**
  5863. * @param {?} t
  5864. * @return {?}
  5865. */
  5866. (t) => {
  5867. this.currentUrlTree = t.urlAfterRedirects;
  5868. this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, t.rawUrl);
  5869. ((/** @type {?} */ (this))).routerState = (/** @type {?} */ (t.targetRouterState));
  5870. if (this.urlUpdateStrategy === 'deferred') {
  5871. if (!t.extras.skipLocationChange) {
  5872. this.setBrowserUrl(this.rawUrlTree, !!t.extras.replaceUrl, t.id, t.extras.state);
  5873. }
  5874. this.browserUrlTree = t.urlAfterRedirects;
  5875. }
  5876. })), activateRoutes(this.rootContexts, this.routeReuseStrategy, (/**
  5877. * @param {?} evt
  5878. * @return {?}
  5879. */
  5880. (evt) => this.triggerEvent(evt))), tap({ /**
  5881. * @return {?}
  5882. */
  5883. next() { completed = true; }, /**
  5884. * @return {?}
  5885. */
  5886. complete() { completed = true; } }), finalize((/**
  5887. * @return {?}
  5888. */
  5889. () => {
  5890. /* When the navigation stream finishes either through error or success, we set the
  5891. * `completed` or `errored` flag. However, there are some situations where we could
  5892. * get here without either of those being set. For instance, a redirect during
  5893. * NavigationStart. Therefore, this is a catch-all to make sure the NavigationCancel
  5894. * event is fired when a navigation gets cancelled but not caught by other means. */
  5895. if (!completed && !errored) {
  5896. // Must reset to current URL tree here to ensure history.state is set. On a fresh
  5897. // page load, if a new navigation comes in before a successful navigation
  5898. // completes, there will be nothing in history.state.navigationId. This can cause
  5899. // sync problems with AngularJS sync code which looks for a value here in order
  5900. // to determine whether or not to handle a given popstate event or to leave it
  5901. // to the Angualr router.
  5902. this.resetUrlToCurrentUrlTree();
  5903. /** @type {?} */
  5904. const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), `Navigation ID ${t.id} is not equal to the current navigation id ${this.navigationId}`);
  5905. eventsSubject.next(navCancel);
  5906. t.resolve(false);
  5907. }
  5908. // currentNavigation should always be reset to null here. If navigation was
  5909. // successful, lastSuccessfulTransition will have already been set. Therefore we
  5910. // can safely set currentNavigation to null here.
  5911. this.currentNavigation = null;
  5912. })), catchError((/**
  5913. * @param {?} e
  5914. * @return {?}
  5915. */
  5916. (e) => {
  5917. errored = true;
  5918. /* This error type is issued during Redirect, and is handled as a cancellation
  5919. * rather than an error. */
  5920. if (isNavigationCancelingError(e)) {
  5921. /** @type {?} */
  5922. const redirecting = isUrlTree(e.url);
  5923. if (!redirecting) {
  5924. // Set property only if we're not redirecting. If we landed on a page and
  5925. // redirect to `/` route, the new navigation is going to see the `/` isn't
  5926. // a change from the default currentUrlTree and won't navigate. This is
  5927. // only applicable with initial navigation, so setting `navigated` only when
  5928. // not redirecting resolves this scenario.
  5929. this.navigated = true;
  5930. this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
  5931. }
  5932. /** @type {?} */
  5933. const navCancel = new NavigationCancel(t.id, this.serializeUrl(t.extractedUrl), e.message);
  5934. eventsSubject.next(navCancel);
  5935. t.resolve(false);
  5936. if (redirecting) {
  5937. this.navigateByUrl(e.url);
  5938. }
  5939. /* All other errors should reset to the router's internal URL reference to the
  5940. * pre-error state. */
  5941. }
  5942. else {
  5943. this.resetStateAndUrl(t.currentRouterState, t.currentUrlTree, t.rawUrl);
  5944. /** @type {?} */
  5945. const navError = new NavigationError(t.id, this.serializeUrl(t.extractedUrl), e);
  5946. eventsSubject.next(navError);
  5947. try {
  5948. t.resolve(this.errorHandler(e));
  5949. }
  5950. catch (ee) {
  5951. t.reject(ee);
  5952. }
  5953. }
  5954. return EMPTY;
  5955. })));
  5956. // TODO(jasonaden): remove cast once g3 is on updated TypeScript
  5957. })))))));
  5958. }
  5959. /**
  5960. * \@internal
  5961. * TODO: this should be removed once the constructor of the router made internal
  5962. * @param {?} rootComponentType
  5963. * @return {?}
  5964. */
  5965. resetRootComponentType(rootComponentType) {
  5966. this.rootComponentType = rootComponentType;
  5967. // TODO: vsavkin router 4.0 should make the root component set to null
  5968. // this will simplify the lifecycle of the router.
  5969. this.routerState.root.component = this.rootComponentType;
  5970. }
  5971. /**
  5972. * @private
  5973. * @return {?}
  5974. */
  5975. getTransition() {
  5976. /** @type {?} */
  5977. const transition = this.transitions.value;
  5978. // This value needs to be set. Other values such as extractedUrl are set on initial navigation
  5979. // but the urlAfterRedirects may not get set if we aren't processing the new URL *and* not
  5980. // processing the previous URL.
  5981. transition.urlAfterRedirects = this.browserUrlTree;
  5982. return transition;
  5983. }
  5984. /**
  5985. * @private
  5986. * @param {?} t
  5987. * @return {?}
  5988. */
  5989. setTransition(t) {
  5990. this.transitions.next(Object.assign({}, this.getTransition(), t));
  5991. }
  5992. /**
  5993. * Sets up the location change listener and performs the initial navigation.
  5994. * @return {?}
  5995. */
  5996. initialNavigation() {
  5997. this.setUpLocationChangeListener();
  5998. if (this.navigationId === 0) {
  5999. this.navigateByUrl(this.location.path(true), { replaceUrl: true });
  6000. }
  6001. }
  6002. /**
  6003. * Sets up the location change listener.
  6004. * @return {?}
  6005. */
  6006. setUpLocationChangeListener() {
  6007. // Don't need to use Zone.wrap any more, because zone.js
  6008. // already patch onPopState, so location change callback will
  6009. // run into ngZone
  6010. if (!this.locationSubscription) {
  6011. this.locationSubscription = (/** @type {?} */ (this.location.subscribe((/**
  6012. * @param {?} change
  6013. * @return {?}
  6014. */
  6015. (change) => {
  6016. /** @type {?} */
  6017. let rawUrlTree = this.parseUrl(change['url']);
  6018. /** @type {?} */
  6019. const source = change['type'] === 'popstate' ? 'popstate' : 'hashchange';
  6020. // Navigations coming from Angular router have a navigationId state property. When this
  6021. // exists, restore the state.
  6022. /** @type {?} */
  6023. const state = change.state && change.state.navigationId ? change.state : null;
  6024. setTimeout((/**
  6025. * @return {?}
  6026. */
  6027. () => { this.scheduleNavigation(rawUrlTree, source, state, { replaceUrl: true }); }), 0);
  6028. }))));
  6029. }
  6030. }
  6031. /**
  6032. * The current URL.
  6033. * @return {?}
  6034. */
  6035. get url() { return this.serializeUrl(this.currentUrlTree); }
  6036. /**
  6037. * The current Navigation object if one exists
  6038. * @return {?}
  6039. */
  6040. getCurrentNavigation() { return this.currentNavigation; }
  6041. /**
  6042. * \@internal
  6043. * @param {?} event
  6044. * @return {?}
  6045. */
  6046. triggerEvent(event) { ((/** @type {?} */ (this.events))).next(event); }
  6047. /**
  6048. * Resets the configuration used for navigation and generating links.
  6049. *
  6050. * \@usageNotes
  6051. *
  6052. * ```
  6053. * router.resetConfig([
  6054. * { path: 'team/:id', component: TeamCmp, children: [
  6055. * { path: 'simple', component: SimpleCmp },
  6056. * { path: 'user/:name', component: UserCmp }
  6057. * ]}
  6058. * ]);
  6059. * ```
  6060. * @param {?} config The route array for the new configuration.
  6061. *
  6062. * @return {?}
  6063. */
  6064. resetConfig(config) {
  6065. validateConfig(config);
  6066. this.config = config.map(standardizeConfig);
  6067. this.navigated = false;
  6068. this.lastSuccessfulId = -1;
  6069. }
  6070. /**
  6071. * \@docsNotRequired
  6072. * @return {?}
  6073. */
  6074. ngOnDestroy() { this.dispose(); }
  6075. /**
  6076. * Disposes of the router.
  6077. * @return {?}
  6078. */
  6079. dispose() {
  6080. if (this.locationSubscription) {
  6081. this.locationSubscription.unsubscribe();
  6082. this.locationSubscription = (/** @type {?} */ (null));
  6083. }
  6084. }
  6085. /**
  6086. * Applies an array of commands to the current URL tree and creates a new URL tree.
  6087. *
  6088. * When given an activate route, applies the given commands starting from the route.
  6089. * When not given a route, applies the given command starting from the root.
  6090. *
  6091. * \@usageNotes
  6092. *
  6093. * ```
  6094. * // create /team/33/user/11
  6095. * router.createUrlTree(['/team', 33, 'user', 11]);
  6096. *
  6097. * // create /team/33;expand=true/user/11
  6098. * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
  6099. *
  6100. * // you can collapse static segments like this (this works only with the first passed-in value):
  6101. * router.createUrlTree(['/team/33/user', userId]);
  6102. *
  6103. * // If the first segment can contain slashes, and you do not want the router to split it, you
  6104. * // can do the following:
  6105. *
  6106. * router.createUrlTree([{segmentPath: '/one/two'}]);
  6107. *
  6108. * // create /team/33/(user/11//right:chat)
  6109. * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
  6110. *
  6111. * // remove the right secondary node
  6112. * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
  6113. *
  6114. * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
  6115. *
  6116. * // navigate to /team/33/user/11/details
  6117. * router.createUrlTree(['details'], {relativeTo: route});
  6118. *
  6119. * // navigate to /team/33/user/22
  6120. * router.createUrlTree(['../22'], {relativeTo: route});
  6121. *
  6122. * // navigate to /team/44/user/22
  6123. * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
  6124. * ```
  6125. * @param {?} commands An array of commands to apply.
  6126. * @param {?=} navigationExtras
  6127. * @return {?} The new URL tree.
  6128. *
  6129. */
  6130. createUrlTree(commands, navigationExtras = {}) {
  6131. const { relativeTo, queryParams, fragment, preserveQueryParams, queryParamsHandling, preserveFragment } = navigationExtras;
  6132. if (isDevMode() && preserveQueryParams && (/** @type {?} */ (console)) && (/** @type {?} */ (console.warn))) {
  6133. console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
  6134. }
  6135. /** @type {?} */
  6136. const a = relativeTo || this.routerState.root;
  6137. /** @type {?} */
  6138. const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
  6139. /** @type {?} */
  6140. let q = null;
  6141. if (queryParamsHandling) {
  6142. switch (queryParamsHandling) {
  6143. case 'merge':
  6144. q = Object.assign({}, this.currentUrlTree.queryParams, queryParams);
  6145. break;
  6146. case 'preserve':
  6147. q = this.currentUrlTree.queryParams;
  6148. break;
  6149. default:
  6150. q = queryParams || null;
  6151. }
  6152. }
  6153. else {
  6154. q = preserveQueryParams ? this.currentUrlTree.queryParams : queryParams || null;
  6155. }
  6156. if (q !== null) {
  6157. q = this.removeEmptyProps(q);
  6158. }
  6159. return createUrlTree(a, this.currentUrlTree, commands, (/** @type {?} */ (q)), (/** @type {?} */ (f)));
  6160. }
  6161. /**
  6162. * Navigate based on the provided URL, which must be absolute.
  6163. *
  6164. * \@usageNotes
  6165. *
  6166. * ### Example
  6167. *
  6168. * ```
  6169. * router.navigateByUrl("/team/33/user/11");
  6170. *
  6171. * // Navigate without updating the URL
  6172. * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
  6173. * ```
  6174. *
  6175. * @param {?} url An absolute URL. The function does not apply any delta to the current URL.
  6176. * @param {?=} extras An object containing properties that modify the navigation strategy.
  6177. * The function ignores any properties in the `NavigationExtras` that would change the
  6178. * provided URL.
  6179. *
  6180. * @return {?} A Promise that resolves to 'true' when navigation succeeds,
  6181. * to 'false' when navigation fails, or is rejected on error.
  6182. *
  6183. */
  6184. navigateByUrl(url, extras = { skipLocationChange: false }) {
  6185. if (isDevMode() && this.isNgZoneEnabled && !NgZone.isInAngularZone()) {
  6186. this.console.warn(`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
  6187. }
  6188. /** @type {?} */
  6189. const urlTree = isUrlTree(url) ? url : this.parseUrl(url);
  6190. /** @type {?} */
  6191. const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
  6192. return this.scheduleNavigation(mergedTree, 'imperative', null, extras);
  6193. }
  6194. /**
  6195. * Navigate based on the provided array of commands and a starting point.
  6196. * If no starting route is provided, the navigation is absolute.
  6197. *
  6198. * Returns a promise that:
  6199. * - resolves to 'true' when navigation succeeds,
  6200. * - resolves to 'false' when navigation fails,
  6201. * - is rejected when an error happens.
  6202. *
  6203. * \@usageNotes
  6204. *
  6205. * ### Example
  6206. *
  6207. * ```
  6208. * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
  6209. *
  6210. * // Navigate without updating the URL
  6211. * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
  6212. * ```
  6213. *
  6214. * The first parameter of `navigate()` is a delta to be applied to the current URL
  6215. * or the one provided in the `relativeTo` property of the second parameter (the
  6216. * `NavigationExtras`).
  6217. *
  6218. * In order to affect this browser's `history.state` entry, the `state`
  6219. * parameter can be passed. This must be an object because the router
  6220. * will add the `navigationId` property to this object before creating
  6221. * the new history item.
  6222. * @param {?} commands
  6223. * @param {?=} extras
  6224. * @return {?}
  6225. */
  6226. navigate(commands, extras = { skipLocationChange: false }) {
  6227. validateCommands(commands);
  6228. return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
  6229. }
  6230. /**
  6231. * Serializes a `UrlTree` into a string
  6232. * @param {?} url
  6233. * @return {?}
  6234. */
  6235. serializeUrl(url) { return this.urlSerializer.serialize(url); }
  6236. /**
  6237. * Parses a string into a `UrlTree`
  6238. * @param {?} url
  6239. * @return {?}
  6240. */
  6241. parseUrl(url) {
  6242. /** @type {?} */
  6243. let urlTree;
  6244. try {
  6245. urlTree = this.urlSerializer.parse(url);
  6246. }
  6247. catch (e) {
  6248. urlTree = this.malformedUriErrorHandler(e, this.urlSerializer, url);
  6249. }
  6250. return urlTree;
  6251. }
  6252. /**
  6253. * Returns whether the url is activated
  6254. * @param {?} url
  6255. * @param {?} exact
  6256. * @return {?}
  6257. */
  6258. isActive(url, exact) {
  6259. if (isUrlTree(url)) {
  6260. return containsTree(this.currentUrlTree, url, exact);
  6261. }
  6262. /** @type {?} */
  6263. const urlTree = this.parseUrl(url);
  6264. return containsTree(this.currentUrlTree, urlTree, exact);
  6265. }
  6266. /**
  6267. * @private
  6268. * @param {?} params
  6269. * @return {?}
  6270. */
  6271. removeEmptyProps(params) {
  6272. return Object.keys(params).reduce((/**
  6273. * @param {?} result
  6274. * @param {?} key
  6275. * @return {?}
  6276. */
  6277. (result, key) => {
  6278. /** @type {?} */
  6279. const value = params[key];
  6280. if (value !== null && value !== undefined) {
  6281. result[key] = value;
  6282. }
  6283. return result;
  6284. }), {});
  6285. }
  6286. /**
  6287. * @private
  6288. * @return {?}
  6289. */
  6290. processNavigations() {
  6291. this.navigations.subscribe((/**
  6292. * @param {?} t
  6293. * @return {?}
  6294. */
  6295. t => {
  6296. this.navigated = true;
  6297. this.lastSuccessfulId = t.id;
  6298. ((/** @type {?} */ (this.events)))
  6299. .next(new NavigationEnd(t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
  6300. this.lastSuccessfulNavigation = this.currentNavigation;
  6301. this.currentNavigation = null;
  6302. t.resolve(true);
  6303. }), (/**
  6304. * @param {?} e
  6305. * @return {?}
  6306. */
  6307. e => { this.console.warn(`Unhandled Navigation Error: `); }));
  6308. }
  6309. /**
  6310. * @private
  6311. * @param {?} rawUrl
  6312. * @param {?} source
  6313. * @param {?} restoredState
  6314. * @param {?} extras
  6315. * @return {?}
  6316. */
  6317. scheduleNavigation(rawUrl, source, restoredState, extras) {
  6318. /** @type {?} */
  6319. const lastNavigation = this.getTransition();
  6320. // If the user triggers a navigation imperatively (e.g., by using navigateByUrl),
  6321. // and that navigation results in 'replaceState' that leads to the same URL,
  6322. // we should skip those.
  6323. if (lastNavigation && source !== 'imperative' && lastNavigation.source === 'imperative' &&
  6324. lastNavigation.rawUrl.toString() === rawUrl.toString()) {
  6325. return Promise.resolve(true); // return value is not used
  6326. }
  6327. // Because of a bug in IE and Edge, the location class fires two events (popstate and
  6328. // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
  6329. // flicker. Handles the case when a popstate was emitted first.
  6330. if (lastNavigation && source == 'hashchange' && lastNavigation.source === 'popstate' &&
  6331. lastNavigation.rawUrl.toString() === rawUrl.toString()) {
  6332. return Promise.resolve(true); // return value is not used
  6333. }
  6334. // Because of a bug in IE and Edge, the location class fires two events (popstate and
  6335. // hashchange) every single time. The second one should be ignored. Otherwise, the URL will
  6336. // flicker. Handles the case when a hashchange was emitted first.
  6337. if (lastNavigation && source == 'popstate' && lastNavigation.source === 'hashchange' &&
  6338. lastNavigation.rawUrl.toString() === rawUrl.toString()) {
  6339. return Promise.resolve(true); // return value is not used
  6340. }
  6341. /** @type {?} */
  6342. let resolve = null;
  6343. /** @type {?} */
  6344. let reject = null;
  6345. /** @type {?} */
  6346. const promise = new Promise((/**
  6347. * @param {?} res
  6348. * @param {?} rej
  6349. * @return {?}
  6350. */
  6351. (res, rej) => {
  6352. resolve = res;
  6353. reject = rej;
  6354. }));
  6355. /** @type {?} */
  6356. const id = ++this.navigationId;
  6357. this.setTransition({
  6358. id,
  6359. source,
  6360. restoredState,
  6361. currentUrlTree: this.currentUrlTree,
  6362. currentRawUrl: this.rawUrlTree, rawUrl, extras, resolve, reject, promise,
  6363. currentSnapshot: this.routerState.snapshot,
  6364. currentRouterState: this.routerState
  6365. });
  6366. // Make sure that the error is propagated even though `processNavigations` catch
  6367. // handler does not rethrow
  6368. return promise.catch((/**
  6369. * @param {?} e
  6370. * @return {?}
  6371. */
  6372. (e) => { return Promise.reject(e); }));
  6373. }
  6374. /**
  6375. * @private
  6376. * @param {?} url
  6377. * @param {?} replaceUrl
  6378. * @param {?} id
  6379. * @param {?=} state
  6380. * @return {?}
  6381. */
  6382. setBrowserUrl(url, replaceUrl, id, state) {
  6383. /** @type {?} */
  6384. const path = this.urlSerializer.serialize(url);
  6385. state = state || {};
  6386. if (this.location.isCurrentPathEqualTo(path) || replaceUrl) {
  6387. // TODO(jasonaden): Remove first `navigationId` and rely on `ng` namespace.
  6388. this.location.replaceState(path, '', Object.assign({}, state, { navigationId: id }));
  6389. }
  6390. else {
  6391. this.location.go(path, '', Object.assign({}, state, { navigationId: id }));
  6392. }
  6393. }
  6394. /**
  6395. * @private
  6396. * @param {?} storedState
  6397. * @param {?} storedUrl
  6398. * @param {?} rawUrl
  6399. * @return {?}
  6400. */
  6401. resetStateAndUrl(storedState, storedUrl, rawUrl) {
  6402. ((/** @type {?} */ (this))).routerState = storedState;
  6403. this.currentUrlTree = storedUrl;
  6404. this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, rawUrl);
  6405. this.resetUrlToCurrentUrlTree();
  6406. }
  6407. /**
  6408. * @private
  6409. * @return {?}
  6410. */
  6411. resetUrlToCurrentUrlTree() {
  6412. this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', { navigationId: this.lastSuccessfulId });
  6413. }
  6414. }
  6415. /**
  6416. * @param {?} commands
  6417. * @return {?}
  6418. */
  6419. function validateCommands(commands) {
  6420. for (let i = 0; i < commands.length; i++) {
  6421. /** @type {?} */
  6422. const cmd = commands[i];
  6423. if (cmd == null) {
  6424. throw new Error(`The requested path contains ${cmd} segment at index ${i}`);
  6425. }
  6426. }
  6427. }
  6428. /**
  6429. * @fileoverview added by tsickle
  6430. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6431. */
  6432. /**
  6433. * \@description
  6434. *
  6435. * Lets you link to specific routes in your app.
  6436. *
  6437. * Consider the following route configuration:
  6438. * `[{ path: 'user/:name', component: UserCmp }]`.
  6439. * When linking to this `user/:name` route, you use the `RouterLink` directive.
  6440. *
  6441. * If the link is static, you can use the directive as follows:
  6442. * `<a routerLink="/user/bob">link to user component</a>`
  6443. *
  6444. * If you use dynamic values to generate the link, you can pass an array of path
  6445. * segments, followed by the params for each segment.
  6446. *
  6447. * For instance `['/team', teamId, 'user', userName, {details: true}]`
  6448. * means that we want to generate a link to `/team/11/user/bob;details=true`.
  6449. *
  6450. * Multiple static segments can be merged into one
  6451. * (e.g., `['/team/11/user', userName, {details: true}]`).
  6452. *
  6453. * The first segment name can be prepended with `/`, `./`, or `../`:
  6454. * * If the first segment begins with `/`, the router will look up the route from the root of the
  6455. * app.
  6456. * * If the first segment begins with `./`, or doesn't begin with a slash, the router will
  6457. * instead look in the children of the current activated route.
  6458. * * And if the first segment begins with `../`, the router will go up one level.
  6459. *
  6460. * You can set query params and fragment as follows:
  6461. *
  6462. * ```
  6463. * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
  6464. * link to user component
  6465. * </a>
  6466. * ```
  6467. * RouterLink will use these to generate this link: `/user/bob#education?debug=true`.
  6468. *
  6469. * (Deprecated in v4.0.0 use `queryParamsHandling` instead) You can also tell the
  6470. * directive to preserve the current query params and fragment:
  6471. *
  6472. * ```
  6473. * <a [routerLink]="['/user/bob']" preserveQueryParams preserveFragment>
  6474. * link to user component
  6475. * </a>
  6476. * ```
  6477. *
  6478. * You can tell the directive how to handle queryParams. Available options are:
  6479. * - `'merge'`: merge the queryParams into the current queryParams
  6480. * - `'preserve'`: preserve the current queryParams
  6481. * - default/`''`: use the queryParams only
  6482. *
  6483. * Same options for {\@link NavigationExtras#queryParamsHandling
  6484. * NavigationExtras#queryParamsHandling}.
  6485. *
  6486. * ```
  6487. * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
  6488. * link to user component
  6489. * </a>
  6490. * ```
  6491. *
  6492. * You can provide a `state` value to be persisted to the browser's History.state
  6493. * property (See https://developer.mozilla.org/en-US/docs/Web/API/History#Properties). It's
  6494. * used as follows:
  6495. *
  6496. * ```
  6497. * <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
  6498. * link to user component
  6499. * </a>
  6500. * ```
  6501. *
  6502. * And later the value can be read from the router through `router.getCurrentNavigation`.
  6503. * For example, to capture the `tracingId` above during the `NavigationStart` event:
  6504. *
  6505. * ```
  6506. * // Get NavigationStart events
  6507. * router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
  6508. * const navigation = router.getCurrentNavigation();
  6509. * tracingService.trace({id: navigation.extras.state.tracingId});
  6510. * });
  6511. * ```
  6512. *
  6513. * The router link directive always treats the provided input as a delta to the current url.
  6514. *
  6515. * For instance, if the current url is `/user/(box//aux:team)`.
  6516. *
  6517. * Then the following link `<a [routerLink]="['/user/jim']">Jim</a>` will generate the link
  6518. * `/user/(jim//aux:team)`.
  6519. *
  6520. * See {\@link Router#createUrlTree createUrlTree} for more information.
  6521. *
  6522. * \@ngModule RouterModule
  6523. *
  6524. * \@publicApi
  6525. */
  6526. class RouterLink {
  6527. /**
  6528. * @param {?} router
  6529. * @param {?} route
  6530. * @param {?} tabIndex
  6531. * @param {?} renderer
  6532. * @param {?} el
  6533. */
  6534. constructor(router, route, tabIndex, renderer, el) {
  6535. this.router = router;
  6536. this.route = route;
  6537. this.commands = [];
  6538. if (tabIndex == null) {
  6539. renderer.setAttribute(el.nativeElement, 'tabindex', '0');
  6540. }
  6541. }
  6542. /**
  6543. * @param {?} commands
  6544. * @return {?}
  6545. */
  6546. set routerLink(commands) {
  6547. if (commands != null) {
  6548. this.commands = Array.isArray(commands) ? commands : [commands];
  6549. }
  6550. else {
  6551. this.commands = [];
  6552. }
  6553. }
  6554. /**
  6555. * @deprecated 4.0.0 use `queryParamsHandling` instead.
  6556. * @param {?} value
  6557. * @return {?}
  6558. */
  6559. set preserveQueryParams(value) {
  6560. if (isDevMode() && (/** @type {?} */ (console)) && (/** @type {?} */ (console.warn))) {
  6561. console.warn('preserveQueryParams is deprecated!, use queryParamsHandling instead.');
  6562. }
  6563. this.preserve = value;
  6564. }
  6565. /**
  6566. * @return {?}
  6567. */
  6568. onClick() {
  6569. /** @type {?} */
  6570. const extras = {
  6571. skipLocationChange: attrBoolValue(this.skipLocationChange),
  6572. replaceUrl: attrBoolValue(this.replaceUrl),
  6573. };
  6574. this.router.navigateByUrl(this.urlTree, extras);
  6575. return true;
  6576. }
  6577. /**
  6578. * @return {?}
  6579. */
  6580. get urlTree() {
  6581. return this.router.createUrlTree(this.commands, {
  6582. relativeTo: this.route,
  6583. queryParams: this.queryParams,
  6584. fragment: this.fragment,
  6585. preserveQueryParams: attrBoolValue(this.preserve),
  6586. queryParamsHandling: this.queryParamsHandling,
  6587. preserveFragment: attrBoolValue(this.preserveFragment),
  6588. });
  6589. }
  6590. }
  6591. RouterLink.decorators = [
  6592. { type: Directive, args: [{ selector: ':not(a):not(area)[routerLink]' },] }
  6593. ];
  6594. /** @nocollapse */
  6595. RouterLink.ctorParameters = () => [
  6596. { type: Router },
  6597. { type: ActivatedRoute },
  6598. { type: String, decorators: [{ type: Attribute, args: ['tabindex',] }] },
  6599. { type: Renderer2 },
  6600. { type: ElementRef }
  6601. ];
  6602. RouterLink.propDecorators = {
  6603. queryParams: [{ type: Input }],
  6604. fragment: [{ type: Input }],
  6605. queryParamsHandling: [{ type: Input }],
  6606. preserveFragment: [{ type: Input }],
  6607. skipLocationChange: [{ type: Input }],
  6608. replaceUrl: [{ type: Input }],
  6609. state: [{ type: Input }],
  6610. routerLink: [{ type: Input }],
  6611. preserveQueryParams: [{ type: Input }],
  6612. onClick: [{ type: HostListener, args: ['click',] }]
  6613. };
  6614. /**
  6615. * \@description
  6616. *
  6617. * Lets you link to specific routes in your app.
  6618. *
  6619. * See `RouterLink` for more information.
  6620. *
  6621. * \@ngModule RouterModule
  6622. *
  6623. * \@publicApi
  6624. */
  6625. class RouterLinkWithHref {
  6626. /**
  6627. * @param {?} router
  6628. * @param {?} route
  6629. * @param {?} locationStrategy
  6630. */
  6631. constructor(router, route, locationStrategy) {
  6632. this.router = router;
  6633. this.route = route;
  6634. this.locationStrategy = locationStrategy;
  6635. this.commands = [];
  6636. this.subscription = router.events.subscribe((/**
  6637. * @param {?} s
  6638. * @return {?}
  6639. */
  6640. (s) => {
  6641. if (s instanceof NavigationEnd) {
  6642. this.updateTargetUrlAndHref();
  6643. }
  6644. }));
  6645. }
  6646. /**
  6647. * @param {?} commands
  6648. * @return {?}
  6649. */
  6650. set routerLink(commands) {
  6651. if (commands != null) {
  6652. this.commands = Array.isArray(commands) ? commands : [commands];
  6653. }
  6654. else {
  6655. this.commands = [];
  6656. }
  6657. }
  6658. /**
  6659. * @param {?} value
  6660. * @return {?}
  6661. */
  6662. set preserveQueryParams(value) {
  6663. if (isDevMode() && (/** @type {?} */ (console)) && (/** @type {?} */ (console.warn))) {
  6664. console.warn('preserveQueryParams is deprecated, use queryParamsHandling instead.');
  6665. }
  6666. this.preserve = value;
  6667. }
  6668. /**
  6669. * @param {?} changes
  6670. * @return {?}
  6671. */
  6672. ngOnChanges(changes) { this.updateTargetUrlAndHref(); }
  6673. /**
  6674. * @return {?}
  6675. */
  6676. ngOnDestroy() { this.subscription.unsubscribe(); }
  6677. /**
  6678. * @param {?} button
  6679. * @param {?} ctrlKey
  6680. * @param {?} metaKey
  6681. * @param {?} shiftKey
  6682. * @return {?}
  6683. */
  6684. onClick(button, ctrlKey, metaKey, shiftKey) {
  6685. if (button !== 0 || ctrlKey || metaKey || shiftKey) {
  6686. return true;
  6687. }
  6688. if (typeof this.target === 'string' && this.target != '_self') {
  6689. return true;
  6690. }
  6691. /** @type {?} */
  6692. const extras = {
  6693. skipLocationChange: attrBoolValue(this.skipLocationChange),
  6694. replaceUrl: attrBoolValue(this.replaceUrl),
  6695. state: this.state
  6696. };
  6697. this.router.navigateByUrl(this.urlTree, extras);
  6698. return false;
  6699. }
  6700. /**
  6701. * @private
  6702. * @return {?}
  6703. */
  6704. updateTargetUrlAndHref() {
  6705. this.href = this.locationStrategy.prepareExternalUrl(this.router.serializeUrl(this.urlTree));
  6706. }
  6707. /**
  6708. * @return {?}
  6709. */
  6710. get urlTree() {
  6711. return this.router.createUrlTree(this.commands, {
  6712. relativeTo: this.route,
  6713. queryParams: this.queryParams,
  6714. fragment: this.fragment,
  6715. preserveQueryParams: attrBoolValue(this.preserve),
  6716. queryParamsHandling: this.queryParamsHandling,
  6717. preserveFragment: attrBoolValue(this.preserveFragment),
  6718. });
  6719. }
  6720. }
  6721. RouterLinkWithHref.decorators = [
  6722. { type: Directive, args: [{ selector: 'a[routerLink],area[routerLink]' },] }
  6723. ];
  6724. /** @nocollapse */
  6725. RouterLinkWithHref.ctorParameters = () => [
  6726. { type: Router },
  6727. { type: ActivatedRoute },
  6728. { type: LocationStrategy }
  6729. ];
  6730. RouterLinkWithHref.propDecorators = {
  6731. target: [{ type: HostBinding, args: ['attr.target',] }, { type: Input }],
  6732. queryParams: [{ type: Input }],
  6733. fragment: [{ type: Input }],
  6734. queryParamsHandling: [{ type: Input }],
  6735. preserveFragment: [{ type: Input }],
  6736. skipLocationChange: [{ type: Input }],
  6737. replaceUrl: [{ type: Input }],
  6738. state: [{ type: Input }],
  6739. href: [{ type: HostBinding }],
  6740. routerLink: [{ type: Input }],
  6741. preserveQueryParams: [{ type: Input }],
  6742. onClick: [{ type: HostListener, args: ['click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey'],] }]
  6743. };
  6744. /**
  6745. * @param {?} s
  6746. * @return {?}
  6747. */
  6748. function attrBoolValue(s) {
  6749. return s === '' || !!s;
  6750. }
  6751. /**
  6752. * @fileoverview added by tsickle
  6753. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6754. */
  6755. /**
  6756. *
  6757. * \@description
  6758. *
  6759. * Lets you add a CSS class to an element when the link's route becomes active.
  6760. *
  6761. * This directive lets you add a CSS class to an element when the link's route
  6762. * becomes active.
  6763. *
  6764. * Consider the following example:
  6765. *
  6766. * ```
  6767. * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
  6768. * ```
  6769. *
  6770. * When the url is either '/user' or '/user/bob', the active-link class will
  6771. * be added to the `a` tag. If the url changes, the class will be removed.
  6772. *
  6773. * You can set more than one class, as follows:
  6774. *
  6775. * ```
  6776. * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
  6777. * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
  6778. * ```
  6779. *
  6780. * You can configure RouterLinkActive by passing `exact: true`. This will add the classes
  6781. * only when the url matches the link exactly.
  6782. *
  6783. * ```
  6784. * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
  6785. * true}">Bob</a>
  6786. * ```
  6787. *
  6788. * You can assign the RouterLinkActive instance to a template variable and directly check
  6789. * the `isActive` status.
  6790. * ```
  6791. * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
  6792. * Bob {{ rla.isActive ? '(already open)' : ''}}
  6793. * </a>
  6794. * ```
  6795. *
  6796. * Finally, you can apply the RouterLinkActive directive to an ancestor of a RouterLink.
  6797. *
  6798. * ```
  6799. * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
  6800. * <a routerLink="/user/jim">Jim</a>
  6801. * <a routerLink="/user/bob">Bob</a>
  6802. * </div>
  6803. * ```
  6804. *
  6805. * This will set the active-link class on the div tag if the url is either '/user/jim' or
  6806. * '/user/bob'.
  6807. *
  6808. * \@ngModule RouterModule
  6809. *
  6810. * \@publicApi
  6811. */
  6812. class RouterLinkActive {
  6813. /**
  6814. * @param {?} router
  6815. * @param {?} element
  6816. * @param {?} renderer
  6817. * @param {?=} link
  6818. * @param {?=} linkWithHref
  6819. */
  6820. constructor(router, element, renderer, link, linkWithHref) {
  6821. this.router = router;
  6822. this.element = element;
  6823. this.renderer = renderer;
  6824. this.link = link;
  6825. this.linkWithHref = linkWithHref;
  6826. this.classes = [];
  6827. this.isActive = false;
  6828. this.routerLinkActiveOptions = { exact: false };
  6829. this.subscription = router.events.subscribe((/**
  6830. * @param {?} s
  6831. * @return {?}
  6832. */
  6833. (s) => {
  6834. if (s instanceof NavigationEnd) {
  6835. this.update();
  6836. }
  6837. }));
  6838. }
  6839. /**
  6840. * @return {?}
  6841. */
  6842. ngAfterContentInit() {
  6843. this.links.changes.subscribe((/**
  6844. * @param {?} _
  6845. * @return {?}
  6846. */
  6847. _ => this.update()));
  6848. this.linksWithHrefs.changes.subscribe((/**
  6849. * @param {?} _
  6850. * @return {?}
  6851. */
  6852. _ => this.update()));
  6853. this.update();
  6854. }
  6855. /**
  6856. * @param {?} data
  6857. * @return {?}
  6858. */
  6859. set routerLinkActive(data) {
  6860. /** @type {?} */
  6861. const classes = Array.isArray(data) ? data : data.split(' ');
  6862. this.classes = classes.filter((/**
  6863. * @param {?} c
  6864. * @return {?}
  6865. */
  6866. c => !!c));
  6867. }
  6868. /**
  6869. * @param {?} changes
  6870. * @return {?}
  6871. */
  6872. ngOnChanges(changes) { this.update(); }
  6873. /**
  6874. * @return {?}
  6875. */
  6876. ngOnDestroy() { this.subscription.unsubscribe(); }
  6877. /**
  6878. * @private
  6879. * @return {?}
  6880. */
  6881. update() {
  6882. if (!this.links || !this.linksWithHrefs || !this.router.navigated)
  6883. return;
  6884. Promise.resolve().then((/**
  6885. * @return {?}
  6886. */
  6887. () => {
  6888. /** @type {?} */
  6889. const hasActiveLinks = this.hasActiveLinks();
  6890. if (this.isActive !== hasActiveLinks) {
  6891. ((/** @type {?} */ (this))).isActive = hasActiveLinks;
  6892. this.classes.forEach((/**
  6893. * @param {?} c
  6894. * @return {?}
  6895. */
  6896. (c) => {
  6897. if (hasActiveLinks) {
  6898. this.renderer.addClass(this.element.nativeElement, c);
  6899. }
  6900. else {
  6901. this.renderer.removeClass(this.element.nativeElement, c);
  6902. }
  6903. }));
  6904. }
  6905. }));
  6906. }
  6907. /**
  6908. * @private
  6909. * @param {?} router
  6910. * @return {?}
  6911. */
  6912. isLinkActive(router) {
  6913. return (/**
  6914. * @param {?} link
  6915. * @return {?}
  6916. */
  6917. (link) => router.isActive(link.urlTree, this.routerLinkActiveOptions.exact));
  6918. }
  6919. /**
  6920. * @private
  6921. * @return {?}
  6922. */
  6923. hasActiveLinks() {
  6924. /** @type {?} */
  6925. const isActiveCheckFn = this.isLinkActive(this.router);
  6926. return this.link && isActiveCheckFn(this.link) ||
  6927. this.linkWithHref && isActiveCheckFn(this.linkWithHref) ||
  6928. this.links.some(isActiveCheckFn) || this.linksWithHrefs.some(isActiveCheckFn);
  6929. }
  6930. }
  6931. RouterLinkActive.decorators = [
  6932. { type: Directive, args: [{
  6933. selector: '[routerLinkActive]',
  6934. exportAs: 'routerLinkActive',
  6935. },] }
  6936. ];
  6937. /** @nocollapse */
  6938. RouterLinkActive.ctorParameters = () => [
  6939. { type: Router },
  6940. { type: ElementRef },
  6941. { type: Renderer2 },
  6942. { type: RouterLink, decorators: [{ type: Optional }] },
  6943. { type: RouterLinkWithHref, decorators: [{ type: Optional }] }
  6944. ];
  6945. RouterLinkActive.propDecorators = {
  6946. links: [{ type: ContentChildren, args: [RouterLink, { descendants: true },] }],
  6947. linksWithHrefs: [{ type: ContentChildren, args: [RouterLinkWithHref, { descendants: true },] }],
  6948. routerLinkActiveOptions: [{ type: Input }],
  6949. routerLinkActive: [{ type: Input }]
  6950. };
  6951. /**
  6952. * @fileoverview added by tsickle
  6953. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6954. */
  6955. /**
  6956. * @license
  6957. * Copyright Google Inc. All Rights Reserved.
  6958. *
  6959. * Use of this source code is governed by an MIT-style license that can be
  6960. * found in the LICENSE file at https://angular.io/license
  6961. */
  6962. /**
  6963. * Store contextual information about a `RouterOutlet`
  6964. *
  6965. * \@publicApi
  6966. */
  6967. class OutletContext {
  6968. constructor() {
  6969. this.outlet = null;
  6970. this.route = null;
  6971. this.resolver = null;
  6972. this.children = new ChildrenOutletContexts();
  6973. this.attachRef = null;
  6974. }
  6975. }
  6976. /**
  6977. * Store contextual information about the children (= nested) `RouterOutlet`
  6978. *
  6979. * \@publicApi
  6980. */
  6981. class ChildrenOutletContexts {
  6982. constructor() {
  6983. // contexts for child outlets, by name.
  6984. this.contexts = new Map();
  6985. }
  6986. /**
  6987. * Called when a `RouterOutlet` directive is instantiated
  6988. * @param {?} childName
  6989. * @param {?} outlet
  6990. * @return {?}
  6991. */
  6992. onChildOutletCreated(childName, outlet) {
  6993. /** @type {?} */
  6994. const context = this.getOrCreateContext(childName);
  6995. context.outlet = outlet;
  6996. this.contexts.set(childName, context);
  6997. }
  6998. /**
  6999. * Called when a `RouterOutlet` directive is destroyed.
  7000. * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
  7001. * re-created later.
  7002. * @param {?} childName
  7003. * @return {?}
  7004. */
  7005. onChildOutletDestroyed(childName) {
  7006. /** @type {?} */
  7007. const context = this.getContext(childName);
  7008. if (context) {
  7009. context.outlet = null;
  7010. }
  7011. }
  7012. /**
  7013. * Called when the corresponding route is deactivated during navigation.
  7014. * Because the component get destroyed, all children outlet are destroyed.
  7015. * @return {?}
  7016. */
  7017. onOutletDeactivated() {
  7018. /** @type {?} */
  7019. const contexts = this.contexts;
  7020. this.contexts = new Map();
  7021. return contexts;
  7022. }
  7023. /**
  7024. * @param {?} contexts
  7025. * @return {?}
  7026. */
  7027. onOutletReAttached(contexts) { this.contexts = contexts; }
  7028. /**
  7029. * @param {?} childName
  7030. * @return {?}
  7031. */
  7032. getOrCreateContext(childName) {
  7033. /** @type {?} */
  7034. let context = this.getContext(childName);
  7035. if (!context) {
  7036. context = new OutletContext();
  7037. this.contexts.set(childName, context);
  7038. }
  7039. return context;
  7040. }
  7041. /**
  7042. * @param {?} childName
  7043. * @return {?}
  7044. */
  7045. getContext(childName) { return this.contexts.get(childName) || null; }
  7046. }
  7047. /**
  7048. * @fileoverview added by tsickle
  7049. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7050. */
  7051. /**
  7052. * \@description
  7053. *
  7054. * Acts as a placeholder that Angular dynamically fills based on the current router state.
  7055. *
  7056. * ```
  7057. * <router-outlet></router-outlet>
  7058. * <router-outlet name='left'></router-outlet>
  7059. * <router-outlet name='right'></router-outlet>
  7060. * ```
  7061. *
  7062. * A router outlet will emit an activate event any time a new component is being instantiated,
  7063. * and a deactivate event when it is being destroyed.
  7064. *
  7065. * ```
  7066. * <router-outlet
  7067. * (activate)='onActivate($event)'
  7068. * (deactivate)='onDeactivate($event)'></router-outlet>
  7069. * ```
  7070. * \@ngModule RouterModule
  7071. *
  7072. * \@publicApi
  7073. */
  7074. class RouterOutlet {
  7075. /**
  7076. * @param {?} parentContexts
  7077. * @param {?} location
  7078. * @param {?} resolver
  7079. * @param {?} name
  7080. * @param {?} changeDetector
  7081. */
  7082. constructor(parentContexts, location, resolver, name, changeDetector) {
  7083. this.parentContexts = parentContexts;
  7084. this.location = location;
  7085. this.resolver = resolver;
  7086. this.changeDetector = changeDetector;
  7087. this.activated = null;
  7088. this._activatedRoute = null;
  7089. this.activateEvents = new EventEmitter();
  7090. this.deactivateEvents = new EventEmitter();
  7091. this.name = name || PRIMARY_OUTLET;
  7092. parentContexts.onChildOutletCreated(this.name, this);
  7093. }
  7094. /**
  7095. * @return {?}
  7096. */
  7097. ngOnDestroy() { this.parentContexts.onChildOutletDestroyed(this.name); }
  7098. /**
  7099. * @return {?}
  7100. */
  7101. ngOnInit() {
  7102. if (!this.activated) {
  7103. // If the outlet was not instantiated at the time the route got activated we need to populate
  7104. // the outlet when it is initialized (ie inside a NgIf)
  7105. /** @type {?} */
  7106. const context = this.parentContexts.getContext(this.name);
  7107. if (context && context.route) {
  7108. if (context.attachRef) {
  7109. // `attachRef` is populated when there is an existing component to mount
  7110. this.attach(context.attachRef, context.route);
  7111. }
  7112. else {
  7113. // otherwise the component defined in the configuration is created
  7114. this.activateWith(context.route, context.resolver || null);
  7115. }
  7116. }
  7117. }
  7118. }
  7119. /**
  7120. * @return {?}
  7121. */
  7122. get isActivated() { return !!this.activated; }
  7123. /**
  7124. * @return {?}
  7125. */
  7126. get component() {
  7127. if (!this.activated)
  7128. throw new Error('Outlet is not activated');
  7129. return this.activated.instance;
  7130. }
  7131. /**
  7132. * @return {?}
  7133. */
  7134. get activatedRoute() {
  7135. if (!this.activated)
  7136. throw new Error('Outlet is not activated');
  7137. return (/** @type {?} */ (this._activatedRoute));
  7138. }
  7139. /**
  7140. * @return {?}
  7141. */
  7142. get activatedRouteData() {
  7143. if (this._activatedRoute) {
  7144. return this._activatedRoute.snapshot.data;
  7145. }
  7146. return {};
  7147. }
  7148. /**
  7149. * Called when the `RouteReuseStrategy` instructs to detach the subtree
  7150. * @return {?}
  7151. */
  7152. detach() {
  7153. if (!this.activated)
  7154. throw new Error('Outlet is not activated');
  7155. this.location.detach();
  7156. /** @type {?} */
  7157. const cmp = this.activated;
  7158. this.activated = null;
  7159. this._activatedRoute = null;
  7160. return cmp;
  7161. }
  7162. /**
  7163. * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
  7164. * @param {?} ref
  7165. * @param {?} activatedRoute
  7166. * @return {?}
  7167. */
  7168. attach(ref, activatedRoute) {
  7169. this.activated = ref;
  7170. this._activatedRoute = activatedRoute;
  7171. this.location.insert(ref.hostView);
  7172. }
  7173. /**
  7174. * @return {?}
  7175. */
  7176. deactivate() {
  7177. if (this.activated) {
  7178. /** @type {?} */
  7179. const c = this.component;
  7180. this.activated.destroy();
  7181. this.activated = null;
  7182. this._activatedRoute = null;
  7183. this.deactivateEvents.emit(c);
  7184. }
  7185. }
  7186. /**
  7187. * @param {?} activatedRoute
  7188. * @param {?} resolver
  7189. * @return {?}
  7190. */
  7191. activateWith(activatedRoute, resolver) {
  7192. if (this.isActivated) {
  7193. throw new Error('Cannot activate an already activated outlet');
  7194. }
  7195. this._activatedRoute = activatedRoute;
  7196. /** @type {?} */
  7197. const snapshot = activatedRoute._futureSnapshot;
  7198. /** @type {?} */
  7199. const component = (/** @type {?} */ ((/** @type {?} */ (snapshot.routeConfig)).component));
  7200. resolver = resolver || this.resolver;
  7201. /** @type {?} */
  7202. const factory = resolver.resolveComponentFactory(component);
  7203. /** @type {?} */
  7204. const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
  7205. /** @type {?} */
  7206. const injector = new OutletInjector(activatedRoute, childContexts, this.location.injector);
  7207. this.activated = this.location.createComponent(factory, this.location.length, injector);
  7208. // Calling `markForCheck` to make sure we will run the change detection when the
  7209. // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
  7210. this.changeDetector.markForCheck();
  7211. this.activateEvents.emit(this.activated.instance);
  7212. }
  7213. }
  7214. RouterOutlet.decorators = [
  7215. { type: Directive, args: [{ selector: 'router-outlet', exportAs: 'outlet' },] }
  7216. ];
  7217. /** @nocollapse */
  7218. RouterOutlet.ctorParameters = () => [
  7219. { type: ChildrenOutletContexts },
  7220. { type: ViewContainerRef },
  7221. { type: ComponentFactoryResolver },
  7222. { type: String, decorators: [{ type: Attribute, args: ['name',] }] },
  7223. { type: ChangeDetectorRef }
  7224. ];
  7225. RouterOutlet.propDecorators = {
  7226. activateEvents: [{ type: Output, args: ['activate',] }],
  7227. deactivateEvents: [{ type: Output, args: ['deactivate',] }]
  7228. };
  7229. class OutletInjector {
  7230. /**
  7231. * @param {?} route
  7232. * @param {?} childContexts
  7233. * @param {?} parent
  7234. */
  7235. constructor(route, childContexts, parent) {
  7236. this.route = route;
  7237. this.childContexts = childContexts;
  7238. this.parent = parent;
  7239. }
  7240. /**
  7241. * @param {?} token
  7242. * @param {?=} notFoundValue
  7243. * @return {?}
  7244. */
  7245. get(token, notFoundValue) {
  7246. if (token === ActivatedRoute) {
  7247. return this.route;
  7248. }
  7249. if (token === ChildrenOutletContexts) {
  7250. return this.childContexts;
  7251. }
  7252. return this.parent.get(token, notFoundValue);
  7253. }
  7254. }
  7255. /**
  7256. * @fileoverview added by tsickle
  7257. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7258. */
  7259. /**
  7260. * \@description
  7261. *
  7262. * Provides a preloading strategy.
  7263. *
  7264. * \@publicApi
  7265. * @abstract
  7266. */
  7267. class PreloadingStrategy {
  7268. }
  7269. /**
  7270. * \@description
  7271. *
  7272. * Provides a preloading strategy that preloads all modules as quickly as possible.
  7273. *
  7274. * ```
  7275. * RouteModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
  7276. * ```
  7277. *
  7278. * \@publicApi
  7279. */
  7280. class PreloadAllModules {
  7281. /**
  7282. * @param {?} route
  7283. * @param {?} fn
  7284. * @return {?}
  7285. */
  7286. preload(route, fn) {
  7287. return fn().pipe(catchError((/**
  7288. * @return {?}
  7289. */
  7290. () => of(null))));
  7291. }
  7292. }
  7293. /**
  7294. * \@description
  7295. *
  7296. * Provides a preloading strategy that does not preload any modules.
  7297. *
  7298. * This strategy is enabled by default.
  7299. *
  7300. * \@publicApi
  7301. */
  7302. class NoPreloading {
  7303. /**
  7304. * @param {?} route
  7305. * @param {?} fn
  7306. * @return {?}
  7307. */
  7308. preload(route, fn) { return of(null); }
  7309. }
  7310. /**
  7311. * The preloader optimistically loads all router configurations to
  7312. * make navigations into lazily-loaded sections of the application faster.
  7313. *
  7314. * The preloader runs in the background. When the router bootstraps, the preloader
  7315. * starts listening to all navigation events. After every such event, the preloader
  7316. * will check if any configurations can be loaded lazily.
  7317. *
  7318. * If a route is protected by `canLoad` guards, the preloaded will not load it.
  7319. *
  7320. * \@publicApi
  7321. */
  7322. class RouterPreloader {
  7323. /**
  7324. * @param {?} router
  7325. * @param {?} moduleLoader
  7326. * @param {?} compiler
  7327. * @param {?} injector
  7328. * @param {?} preloadingStrategy
  7329. */
  7330. constructor(router, moduleLoader, compiler, injector, preloadingStrategy) {
  7331. this.router = router;
  7332. this.injector = injector;
  7333. this.preloadingStrategy = preloadingStrategy;
  7334. /** @type {?} */
  7335. const onStartLoad = (/**
  7336. * @param {?} r
  7337. * @return {?}
  7338. */
  7339. (r) => router.triggerEvent(new RouteConfigLoadStart(r)));
  7340. /** @type {?} */
  7341. const onEndLoad = (/**
  7342. * @param {?} r
  7343. * @return {?}
  7344. */
  7345. (r) => router.triggerEvent(new RouteConfigLoadEnd(r)));
  7346. this.loader = new RouterConfigLoader(moduleLoader, compiler, onStartLoad, onEndLoad);
  7347. }
  7348. /**
  7349. * @return {?}
  7350. */
  7351. setUpPreloading() {
  7352. this.subscription =
  7353. this.router.events
  7354. .pipe(filter((/**
  7355. * @param {?} e
  7356. * @return {?}
  7357. */
  7358. (e) => e instanceof NavigationEnd)), concatMap((/**
  7359. * @return {?}
  7360. */
  7361. () => this.preload())))
  7362. .subscribe((/**
  7363. * @return {?}
  7364. */
  7365. () => { }));
  7366. }
  7367. /**
  7368. * @return {?}
  7369. */
  7370. preload() {
  7371. /** @type {?} */
  7372. const ngModule = this.injector.get(NgModuleRef);
  7373. return this.processRoutes(ngModule, this.router.config);
  7374. }
  7375. // TODO(jasonaden): This class relies on code external to the class to call setUpPreloading. If
  7376. // this hasn't been done, ngOnDestroy will fail as this.subscription will be undefined. This
  7377. // should be refactored.
  7378. /**
  7379. * @return {?}
  7380. */
  7381. ngOnDestroy() { this.subscription.unsubscribe(); }
  7382. /**
  7383. * @private
  7384. * @param {?} ngModule
  7385. * @param {?} routes
  7386. * @return {?}
  7387. */
  7388. processRoutes(ngModule, routes) {
  7389. /** @type {?} */
  7390. const res = [];
  7391. for (const route of routes) {
  7392. // we already have the config loaded, just recurse
  7393. if (route.loadChildren && !route.canLoad && route._loadedConfig) {
  7394. /** @type {?} */
  7395. const childConfig = route._loadedConfig;
  7396. res.push(this.processRoutes(childConfig.module, childConfig.routes));
  7397. // no config loaded, fetch the config
  7398. }
  7399. else if (route.loadChildren && !route.canLoad) {
  7400. res.push(this.preloadConfig(ngModule, route));
  7401. // recurse into children
  7402. }
  7403. else if (route.children) {
  7404. res.push(this.processRoutes(ngModule, route.children));
  7405. }
  7406. }
  7407. return from(res).pipe(mergeAll(), map((/**
  7408. * @param {?} _
  7409. * @return {?}
  7410. */
  7411. (_) => void 0)));
  7412. }
  7413. /**
  7414. * @private
  7415. * @param {?} ngModule
  7416. * @param {?} route
  7417. * @return {?}
  7418. */
  7419. preloadConfig(ngModule, route) {
  7420. return this.preloadingStrategy.preload(route, (/**
  7421. * @return {?}
  7422. */
  7423. () => {
  7424. /** @type {?} */
  7425. const loaded$ = this.loader.load(ngModule.injector, route);
  7426. return loaded$.pipe(mergeMap((/**
  7427. * @param {?} config
  7428. * @return {?}
  7429. */
  7430. (config) => {
  7431. route._loadedConfig = config;
  7432. return this.processRoutes(config.module, config.routes);
  7433. })));
  7434. }));
  7435. }
  7436. }
  7437. RouterPreloader.decorators = [
  7438. { type: Injectable }
  7439. ];
  7440. /** @nocollapse */
  7441. RouterPreloader.ctorParameters = () => [
  7442. { type: Router },
  7443. { type: NgModuleFactoryLoader },
  7444. { type: Compiler },
  7445. { type: Injector },
  7446. { type: PreloadingStrategy }
  7447. ];
  7448. /**
  7449. * @fileoverview added by tsickle
  7450. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7451. */
  7452. class RouterScroller {
  7453. /**
  7454. * @param {?} router
  7455. * @param {?} viewportScroller
  7456. * @param {?=} options
  7457. */
  7458. constructor(router, viewportScroller, options = {}) {
  7459. this.router = router;
  7460. this.viewportScroller = viewportScroller;
  7461. this.options = options;
  7462. this.lastId = 0;
  7463. this.lastSource = 'imperative';
  7464. this.restoredId = 0;
  7465. this.store = {};
  7466. // Default both options to 'disabled'
  7467. options.scrollPositionRestoration = options.scrollPositionRestoration || 'disabled';
  7468. options.anchorScrolling = options.anchorScrolling || 'disabled';
  7469. }
  7470. /**
  7471. * @return {?}
  7472. */
  7473. init() {
  7474. // we want to disable the automatic scrolling because having two places
  7475. // responsible for scrolling results race conditions, especially given
  7476. // that browser don't implement this behavior consistently
  7477. if (this.options.scrollPositionRestoration !== 'disabled') {
  7478. this.viewportScroller.setHistoryScrollRestoration('manual');
  7479. }
  7480. this.routerEventsSubscription = this.createScrollEvents();
  7481. this.scrollEventsSubscription = this.consumeScrollEvents();
  7482. }
  7483. /**
  7484. * @private
  7485. * @return {?}
  7486. */
  7487. createScrollEvents() {
  7488. return this.router.events.subscribe((/**
  7489. * @param {?} e
  7490. * @return {?}
  7491. */
  7492. e => {
  7493. if (e instanceof NavigationStart) {
  7494. // store the scroll position of the current stable navigations.
  7495. this.store[this.lastId] = this.viewportScroller.getScrollPosition();
  7496. this.lastSource = e.navigationTrigger;
  7497. this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
  7498. }
  7499. else if (e instanceof NavigationEnd) {
  7500. this.lastId = e.id;
  7501. this.scheduleScrollEvent(e, this.router.parseUrl(e.urlAfterRedirects).fragment);
  7502. }
  7503. }));
  7504. }
  7505. /**
  7506. * @private
  7507. * @return {?}
  7508. */
  7509. consumeScrollEvents() {
  7510. return this.router.events.subscribe((/**
  7511. * @param {?} e
  7512. * @return {?}
  7513. */
  7514. e => {
  7515. if (!(e instanceof Scroll))
  7516. return;
  7517. // a popstate event. The pop state event will always ignore anchor scrolling.
  7518. if (e.position) {
  7519. if (this.options.scrollPositionRestoration === 'top') {
  7520. this.viewportScroller.scrollToPosition([0, 0]);
  7521. }
  7522. else if (this.options.scrollPositionRestoration === 'enabled') {
  7523. this.viewportScroller.scrollToPosition(e.position);
  7524. }
  7525. // imperative navigation "forward"
  7526. }
  7527. else {
  7528. if (e.anchor && this.options.anchorScrolling === 'enabled') {
  7529. this.viewportScroller.scrollToAnchor(e.anchor);
  7530. }
  7531. else if (this.options.scrollPositionRestoration !== 'disabled') {
  7532. this.viewportScroller.scrollToPosition([0, 0]);
  7533. }
  7534. }
  7535. }));
  7536. }
  7537. /**
  7538. * @private
  7539. * @param {?} routerEvent
  7540. * @param {?} anchor
  7541. * @return {?}
  7542. */
  7543. scheduleScrollEvent(routerEvent, anchor) {
  7544. this.router.triggerEvent(new Scroll(routerEvent, this.lastSource === 'popstate' ? this.store[this.restoredId] : null, anchor));
  7545. }
  7546. /**
  7547. * @return {?}
  7548. */
  7549. ngOnDestroy() {
  7550. if (this.routerEventsSubscription) {
  7551. this.routerEventsSubscription.unsubscribe();
  7552. }
  7553. if (this.scrollEventsSubscription) {
  7554. this.scrollEventsSubscription.unsubscribe();
  7555. }
  7556. }
  7557. }
  7558. /**
  7559. * @fileoverview added by tsickle
  7560. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7561. */
  7562. /**
  7563. * \@description
  7564. *
  7565. * Contains a list of directives
  7566. *
  7567. *
  7568. * @type {?}
  7569. */
  7570. const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkWithHref, RouterLinkActive, ɵEmptyOutletComponent];
  7571. /**
  7572. * \@description
  7573. *
  7574. * Is used in DI to configure the router.
  7575. *
  7576. * \@publicApi
  7577. * @type {?}
  7578. */
  7579. const ROUTER_CONFIGURATION = new InjectionToken('ROUTER_CONFIGURATION');
  7580. /**
  7581. * \@docsNotRequired
  7582. * @type {?}
  7583. */
  7584. const ROUTER_FORROOT_GUARD = new InjectionToken('ROUTER_FORROOT_GUARD');
  7585. const ɵ0 = { enableTracing: false };
  7586. /** @type {?} */
  7587. const ROUTER_PROVIDERS = [
  7588. Location,
  7589. { provide: UrlSerializer, useClass: DefaultUrlSerializer },
  7590. {
  7591. provide: Router,
  7592. useFactory: setupRouter,
  7593. deps: [
  7594. ApplicationRef, UrlSerializer, ChildrenOutletContexts, Location, Injector,
  7595. NgModuleFactoryLoader, Compiler, ROUTES, ROUTER_CONFIGURATION,
  7596. [UrlHandlingStrategy, new Optional()], [RouteReuseStrategy, new Optional()]
  7597. ]
  7598. },
  7599. ChildrenOutletContexts,
  7600. { provide: ActivatedRoute, useFactory: rootRoute, deps: [Router] },
  7601. { provide: NgModuleFactoryLoader, useClass: SystemJsNgModuleLoader },
  7602. RouterPreloader,
  7603. NoPreloading,
  7604. PreloadAllModules,
  7605. { provide: ROUTER_CONFIGURATION, useValue: ɵ0 },
  7606. ];
  7607. /**
  7608. * @return {?}
  7609. */
  7610. function routerNgProbeToken() {
  7611. return new NgProbeToken('Router', Router);
  7612. }
  7613. /**
  7614. * \@usageNotes
  7615. *
  7616. * RouterModule can be imported multiple times: once per lazily-loaded bundle.
  7617. * Since the router deals with a global shared resource--location, we cannot have
  7618. * more than one router service active.
  7619. *
  7620. * That is why there are two ways to create the module: `RouterModule.forRoot` and
  7621. * `RouterModule.forChild`.
  7622. *
  7623. * * `forRoot` creates a module that contains all the directives, the given routes, and the router
  7624. * service itself.
  7625. * * `forChild` creates a module that contains all the directives and the given routes, but does not
  7626. * include the router service.
  7627. *
  7628. * When registered at the root, the module should be used as follows
  7629. *
  7630. * ```
  7631. * \@NgModule({
  7632. * imports: [RouterModule.forRoot(ROUTES)]
  7633. * })
  7634. * class MyNgModule {}
  7635. * ```
  7636. *
  7637. * For submodules and lazy loaded submodules the module should be used as follows:
  7638. *
  7639. * ```
  7640. * \@NgModule({
  7641. * imports: [RouterModule.forChild(ROUTES)]
  7642. * })
  7643. * class MyNgModule {}
  7644. * ```
  7645. *
  7646. * \@description
  7647. *
  7648. * Adds router directives and providers.
  7649. *
  7650. * Managing state transitions is one of the hardest parts of building applications. This is
  7651. * especially true on the web, where you also need to ensure that the state is reflected in the URL.
  7652. * In addition, we often want to split applications into multiple bundles and load them on demand.
  7653. * Doing this transparently is not trivial.
  7654. *
  7655. * The Angular router solves these problems. Using the router, you can declaratively specify
  7656. * application states, manage state transitions while taking care of the URL, and load bundles on
  7657. * demand.
  7658. *
  7659. * [Read this developer guide](https://angular.io/docs/ts/latest/guide/router.html) to get an
  7660. * overview of how the router should be used.
  7661. *
  7662. * \@publicApi
  7663. */
  7664. class RouterModule {
  7665. // Note: We are injecting the Router so it gets created eagerly...
  7666. /**
  7667. * @param {?} guard
  7668. * @param {?} router
  7669. */
  7670. constructor(guard, router) { }
  7671. /**
  7672. * Creates a module with all the router providers and directives. It also optionally sets up an
  7673. * application listener to perform an initial navigation.
  7674. *
  7675. * Configuration Options:
  7676. *
  7677. * * `enableTracing` Toggles whether the router should log all navigation events to the console.
  7678. * * `useHash` Enables the location strategy that uses the URL fragment instead of the history
  7679. * API.
  7680. * * `initialNavigation` Disables the initial navigation.
  7681. * * `errorHandler` Defines a custom error handler for failed navigations.
  7682. * * `preloadingStrategy` Configures a preloading strategy. See `PreloadAllModules`.
  7683. * * `onSameUrlNavigation` Define what the router should do if it receives a navigation request to
  7684. * the current URL.
  7685. * * `scrollPositionRestoration` Configures if the scroll position needs to be restored when
  7686. * navigating back.
  7687. * * `anchorScrolling` Configures if the router should scroll to the element when the url has a
  7688. * fragment.
  7689. * * `scrollOffset` Configures the scroll offset the router will use when scrolling to an element.
  7690. * * `paramsInheritanceStrategy` Defines how the router merges params, data and resolved data from
  7691. * parent to child routes.
  7692. * * `malformedUriErrorHandler` Defines a custom malformed uri error handler function. This
  7693. * handler is invoked when encodedURI contains invalid character sequences.
  7694. * * `urlUpdateStrategy` Defines when the router updates the browser URL. The default behavior is
  7695. * to update after successful navigation.
  7696. * * `relativeLinkResolution` Enables the correct relative link resolution in components with
  7697. * empty paths.
  7698. *
  7699. * See `ExtraOptions` for more details about the above options.
  7700. * @param {?} routes
  7701. * @param {?=} config
  7702. * @return {?}
  7703. */
  7704. static forRoot(routes, config) {
  7705. return {
  7706. ngModule: RouterModule,
  7707. providers: [
  7708. ROUTER_PROVIDERS,
  7709. provideRoutes(routes),
  7710. {
  7711. provide: ROUTER_FORROOT_GUARD,
  7712. useFactory: provideForRootGuard,
  7713. deps: [[Router, new Optional(), new SkipSelf()]]
  7714. },
  7715. { provide: ROUTER_CONFIGURATION, useValue: config ? config : {} },
  7716. {
  7717. provide: LocationStrategy,
  7718. useFactory: provideLocationStrategy,
  7719. deps: [
  7720. PlatformLocation, [new Inject(APP_BASE_HREF), new Optional()], ROUTER_CONFIGURATION
  7721. ]
  7722. },
  7723. {
  7724. provide: RouterScroller,
  7725. useFactory: createRouterScroller,
  7726. deps: [Router, ViewportScroller, ROUTER_CONFIGURATION]
  7727. },
  7728. {
  7729. provide: PreloadingStrategy,
  7730. useExisting: config && config.preloadingStrategy ? config.preloadingStrategy :
  7731. NoPreloading
  7732. },
  7733. { provide: NgProbeToken, multi: true, useFactory: routerNgProbeToken },
  7734. provideRouterInitializer(),
  7735. ],
  7736. };
  7737. }
  7738. /**
  7739. * Creates a module with all the router directives and a provider registering routes.
  7740. * @param {?} routes
  7741. * @return {?}
  7742. */
  7743. static forChild(routes) {
  7744. return { ngModule: RouterModule, providers: [provideRoutes(routes)] };
  7745. }
  7746. }
  7747. RouterModule.decorators = [
  7748. { type: NgModule, args: [{
  7749. declarations: ROUTER_DIRECTIVES,
  7750. exports: ROUTER_DIRECTIVES,
  7751. entryComponents: [ɵEmptyOutletComponent]
  7752. },] }
  7753. ];
  7754. /** @nocollapse */
  7755. RouterModule.ctorParameters = () => [
  7756. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [ROUTER_FORROOT_GUARD,] }] },
  7757. { type: Router, decorators: [{ type: Optional }] }
  7758. ];
  7759. /**
  7760. * @param {?} router
  7761. * @param {?} viewportScroller
  7762. * @param {?} config
  7763. * @return {?}
  7764. */
  7765. function createRouterScroller(router, viewportScroller, config) {
  7766. if (config.scrollOffset) {
  7767. viewportScroller.setOffset(config.scrollOffset);
  7768. }
  7769. return new RouterScroller(router, viewportScroller, config);
  7770. }
  7771. /**
  7772. * @param {?} platformLocationStrategy
  7773. * @param {?} baseHref
  7774. * @param {?=} options
  7775. * @return {?}
  7776. */
  7777. function provideLocationStrategy(platformLocationStrategy, baseHref, options = {}) {
  7778. return options.useHash ? new HashLocationStrategy(platformLocationStrategy, baseHref) :
  7779. new PathLocationStrategy(platformLocationStrategy, baseHref);
  7780. }
  7781. /**
  7782. * @param {?} router
  7783. * @return {?}
  7784. */
  7785. function provideForRootGuard(router) {
  7786. if (router) {
  7787. throw new Error(`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
  7788. }
  7789. return 'guarded';
  7790. }
  7791. /**
  7792. * \@description
  7793. *
  7794. * Registers routes.
  7795. *
  7796. * \@usageNotes
  7797. * ### Example
  7798. *
  7799. * ```
  7800. * \@NgModule({
  7801. * imports: [RouterModule.forChild(ROUTES)],
  7802. * providers: [provideRoutes(EXTRA_ROUTES)]
  7803. * })
  7804. * class MyNgModule {}
  7805. * ```
  7806. *
  7807. * \@publicApi
  7808. * @param {?} routes
  7809. * @return {?}
  7810. */
  7811. function provideRoutes(routes) {
  7812. return [
  7813. { provide: ANALYZE_FOR_ENTRY_COMPONENTS, multi: true, useValue: routes },
  7814. { provide: ROUTES, multi: true, useValue: routes },
  7815. ];
  7816. }
  7817. /**
  7818. * @param {?} ref
  7819. * @param {?} urlSerializer
  7820. * @param {?} contexts
  7821. * @param {?} location
  7822. * @param {?} injector
  7823. * @param {?} loader
  7824. * @param {?} compiler
  7825. * @param {?} config
  7826. * @param {?=} opts
  7827. * @param {?=} urlHandlingStrategy
  7828. * @param {?=} routeReuseStrategy
  7829. * @return {?}
  7830. */
  7831. function setupRouter(ref, urlSerializer, contexts, location, injector, loader, compiler, config, opts = {}, urlHandlingStrategy, routeReuseStrategy) {
  7832. /** @type {?} */
  7833. const router = new Router(null, urlSerializer, contexts, location, injector, loader, compiler, flatten(config));
  7834. if (urlHandlingStrategy) {
  7835. router.urlHandlingStrategy = urlHandlingStrategy;
  7836. }
  7837. if (routeReuseStrategy) {
  7838. router.routeReuseStrategy = routeReuseStrategy;
  7839. }
  7840. if (opts.errorHandler) {
  7841. router.errorHandler = opts.errorHandler;
  7842. }
  7843. if (opts.malformedUriErrorHandler) {
  7844. router.malformedUriErrorHandler = opts.malformedUriErrorHandler;
  7845. }
  7846. if (opts.enableTracing) {
  7847. /** @type {?} */
  7848. const dom = ɵgetDOM();
  7849. router.events.subscribe((/**
  7850. * @param {?} e
  7851. * @return {?}
  7852. */
  7853. (e) => {
  7854. dom.logGroup(`Router Event: ${((/** @type {?} */ (e.constructor))).name}`);
  7855. dom.log(e.toString());
  7856. dom.log(e);
  7857. dom.logGroupEnd();
  7858. }));
  7859. }
  7860. if (opts.onSameUrlNavigation) {
  7861. router.onSameUrlNavigation = opts.onSameUrlNavigation;
  7862. }
  7863. if (opts.paramsInheritanceStrategy) {
  7864. router.paramsInheritanceStrategy = opts.paramsInheritanceStrategy;
  7865. }
  7866. if (opts.urlUpdateStrategy) {
  7867. router.urlUpdateStrategy = opts.urlUpdateStrategy;
  7868. }
  7869. if (opts.relativeLinkResolution) {
  7870. router.relativeLinkResolution = opts.relativeLinkResolution;
  7871. }
  7872. return router;
  7873. }
  7874. /**
  7875. * @param {?} router
  7876. * @return {?}
  7877. */
  7878. function rootRoute(router) {
  7879. return router.routerState.root;
  7880. }
  7881. /**
  7882. * To initialize the router properly we need to do in two steps:
  7883. *
  7884. * We need to start the navigation in a APP_INITIALIZER to block the bootstrap if
  7885. * a resolver or a guards executes asynchronously. Second, we need to actually run
  7886. * activation in a BOOTSTRAP_LISTENER. We utilize the afterPreactivation
  7887. * hook provided by the router to do that.
  7888. *
  7889. * The router navigation starts, reaches the point when preactivation is done, and then
  7890. * pauses. It waits for the hook to be resolved. We then resolve it only in a bootstrap listener.
  7891. */
  7892. class RouterInitializer {
  7893. /**
  7894. * @param {?} injector
  7895. */
  7896. constructor(injector) {
  7897. this.injector = injector;
  7898. this.initNavigation = false;
  7899. this.resultOfPreactivationDone = new Subject();
  7900. }
  7901. /**
  7902. * @return {?}
  7903. */
  7904. appInitializer() {
  7905. /** @type {?} */
  7906. const p = this.injector.get(LOCATION_INITIALIZED, Promise.resolve(null));
  7907. return p.then((/**
  7908. * @return {?}
  7909. */
  7910. () => {
  7911. /** @type {?} */
  7912. let resolve = (/** @type {?} */ (null));
  7913. /** @type {?} */
  7914. const res = new Promise((/**
  7915. * @param {?} r
  7916. * @return {?}
  7917. */
  7918. r => resolve = r));
  7919. /** @type {?} */
  7920. const router = this.injector.get(Router);
  7921. /** @type {?} */
  7922. const opts = this.injector.get(ROUTER_CONFIGURATION);
  7923. if (this.isLegacyDisabled(opts) || this.isLegacyEnabled(opts)) {
  7924. resolve(true);
  7925. }
  7926. else if (opts.initialNavigation === 'disabled') {
  7927. router.setUpLocationChangeListener();
  7928. resolve(true);
  7929. }
  7930. else if (opts.initialNavigation === 'enabled') {
  7931. router.hooks.afterPreactivation = (/**
  7932. * @return {?}
  7933. */
  7934. () => {
  7935. // only the initial navigation should be delayed
  7936. if (!this.initNavigation) {
  7937. this.initNavigation = true;
  7938. resolve(true);
  7939. return this.resultOfPreactivationDone;
  7940. // subsequent navigations should not be delayed
  7941. }
  7942. else {
  7943. return (/** @type {?} */ (of(null)));
  7944. }
  7945. });
  7946. router.initialNavigation();
  7947. }
  7948. else {
  7949. throw new Error(`Invalid initialNavigation options: '${opts.initialNavigation}'`);
  7950. }
  7951. return res;
  7952. }));
  7953. }
  7954. /**
  7955. * @param {?} bootstrappedComponentRef
  7956. * @return {?}
  7957. */
  7958. bootstrapListener(bootstrappedComponentRef) {
  7959. /** @type {?} */
  7960. const opts = this.injector.get(ROUTER_CONFIGURATION);
  7961. /** @type {?} */
  7962. const preloader = this.injector.get(RouterPreloader);
  7963. /** @type {?} */
  7964. const routerScroller = this.injector.get(RouterScroller);
  7965. /** @type {?} */
  7966. const router = this.injector.get(Router);
  7967. /** @type {?} */
  7968. const ref = this.injector.get(ApplicationRef);
  7969. if (bootstrappedComponentRef !== ref.components[0]) {
  7970. return;
  7971. }
  7972. if (this.isLegacyEnabled(opts)) {
  7973. router.initialNavigation();
  7974. }
  7975. else if (this.isLegacyDisabled(opts)) {
  7976. router.setUpLocationChangeListener();
  7977. }
  7978. preloader.setUpPreloading();
  7979. routerScroller.init();
  7980. router.resetRootComponentType(ref.componentTypes[0]);
  7981. this.resultOfPreactivationDone.next((/** @type {?} */ (null)));
  7982. this.resultOfPreactivationDone.complete();
  7983. }
  7984. /**
  7985. * @private
  7986. * @param {?} opts
  7987. * @return {?}
  7988. */
  7989. isLegacyEnabled(opts) {
  7990. return opts.initialNavigation === 'legacy_enabled' || opts.initialNavigation === true ||
  7991. opts.initialNavigation === undefined;
  7992. }
  7993. /**
  7994. * @private
  7995. * @param {?} opts
  7996. * @return {?}
  7997. */
  7998. isLegacyDisabled(opts) {
  7999. return opts.initialNavigation === 'legacy_disabled' || opts.initialNavigation === false;
  8000. }
  8001. }
  8002. RouterInitializer.decorators = [
  8003. { type: Injectable }
  8004. ];
  8005. /** @nocollapse */
  8006. RouterInitializer.ctorParameters = () => [
  8007. { type: Injector }
  8008. ];
  8009. /**
  8010. * @param {?} r
  8011. * @return {?}
  8012. */
  8013. function getAppInitializer(r) {
  8014. return r.appInitializer.bind(r);
  8015. }
  8016. /**
  8017. * @param {?} r
  8018. * @return {?}
  8019. */
  8020. function getBootstrapListener(r) {
  8021. return r.bootstrapListener.bind(r);
  8022. }
  8023. /**
  8024. * A token for the router initializer that will be called after the app is bootstrapped.
  8025. *
  8026. * \@publicApi
  8027. * @type {?}
  8028. */
  8029. const ROUTER_INITIALIZER = new InjectionToken('Router Initializer');
  8030. /**
  8031. * @return {?}
  8032. */
  8033. function provideRouterInitializer() {
  8034. return [
  8035. RouterInitializer,
  8036. {
  8037. provide: APP_INITIALIZER,
  8038. multi: true,
  8039. useFactory: getAppInitializer,
  8040. deps: [RouterInitializer]
  8041. },
  8042. { provide: ROUTER_INITIALIZER, useFactory: getBootstrapListener, deps: [RouterInitializer] },
  8043. { provide: APP_BOOTSTRAP_LISTENER, multi: true, useExisting: ROUTER_INITIALIZER },
  8044. ];
  8045. }
  8046. /**
  8047. * @fileoverview added by tsickle
  8048. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  8049. */
  8050. /**
  8051. * \@publicApi
  8052. * @type {?}
  8053. */
  8054. const VERSION = new Version('8.1.0');
  8055. /**
  8056. * @fileoverview added by tsickle
  8057. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  8058. */
  8059. /**
  8060. * @fileoverview added by tsickle
  8061. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  8062. */
  8063. /**
  8064. * @fileoverview added by tsickle
  8065. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  8066. */
  8067. /**
  8068. * @fileoverview added by tsickle
  8069. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  8070. */
  8071. /**
  8072. * Generated bundle index. Do not edit.
  8073. */
  8074. export { ɵEmptyOutletComponent as ɵangular_packages_router_router_l, ɵEmptyOutletComponent, ROUTER_FORROOT_GUARD as ɵangular_packages_router_router_a, RouterInitializer as ɵangular_packages_router_router_h, createRouterScroller as ɵangular_packages_router_router_c, getAppInitializer as ɵangular_packages_router_router_i, getBootstrapListener as ɵangular_packages_router_router_j, provideForRootGuard as ɵangular_packages_router_router_e, provideLocationStrategy as ɵangular_packages_router_router_d, provideRouterInitializer as ɵangular_packages_router_router_k, rootRoute as ɵangular_packages_router_router_g, routerNgProbeToken as ɵangular_packages_router_router_b, setupRouter as ɵangular_packages_router_router_f, RouterScroller as ɵangular_packages_router_router_o, Tree as ɵangular_packages_router_router_m, TreeNode as ɵangular_packages_router_router_n, RouterLink, RouterLinkWithHref, RouterLinkActive, RouterOutlet, ActivationEnd, ActivationStart, ChildActivationEnd, ChildActivationStart, GuardsCheckEnd, GuardsCheckStart, NavigationCancel, NavigationEnd, NavigationError, NavigationStart, ResolveEnd, ResolveStart, RouteConfigLoadEnd, RouteConfigLoadStart, RouterEvent, RoutesRecognized, Scroll, RouteReuseStrategy, Router, ROUTES, ROUTER_CONFIGURATION, ROUTER_INITIALIZER, RouterModule, provideRoutes, ChildrenOutletContexts, OutletContext, NoPreloading, PreloadAllModules, PreloadingStrategy, RouterPreloader, ActivatedRoute, ActivatedRouteSnapshot, RouterState, RouterStateSnapshot, PRIMARY_OUTLET, convertToParamMap, UrlHandlingStrategy, DefaultUrlSerializer, UrlSegment, UrlSegmentGroup, UrlSerializer, UrlTree, VERSION, ROUTER_PROVIDERS as ɵROUTER_PROVIDERS, flatten as ɵflatten };
  8075. //# sourceMappingURL=router.js.map