lessc 430 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376
  1. #!/usr/bin/env node
  2. // AUTO-GENERATED BY ROLLUP
  3. 'use strict';
  4. var path = require('path');
  5. var os = require('os');
  6. var CloneHelper = require('clone');
  7. var tslib = require('tslib');
  8. var url = require('url');
  9. var fs;
  10. try {
  11. fs = require('graceful-fs');
  12. }
  13. catch (e) {
  14. fs = require('fs');
  15. }
  16. var fs$1 = fs;
  17. var Math$1 = {
  18. ALWAYS: 0,
  19. PARENS_DIVISION: 1,
  20. PARENS: 2,
  21. STRICT_LEGACY: 3
  22. };
  23. var RewriteUrls = {
  24. OFF: 0,
  25. LOCAL: 1,
  26. ALL: 2
  27. };
  28. /* jshint proto: true */
  29. function getLocation(index, inputStream) {
  30. var n = index + 1;
  31. var line = null;
  32. var column = -1;
  33. while (--n >= 0 && inputStream.charAt(n) !== '\n') {
  34. column++;
  35. }
  36. if (typeof index === 'number') {
  37. line = (inputStream.slice(0, index).match(/\n/g) || '').length;
  38. }
  39. return {
  40. line: line,
  41. column: column
  42. };
  43. }
  44. function copyArray(arr) {
  45. var i;
  46. var length = arr.length;
  47. var copy = new Array(length);
  48. for (i = 0; i < length; i++) {
  49. copy[i] = arr[i];
  50. }
  51. return copy;
  52. }
  53. function clone(obj) {
  54. var cloned = {};
  55. for (var prop in obj) {
  56. if (obj.hasOwnProperty(prop)) {
  57. cloned[prop] = obj[prop];
  58. }
  59. }
  60. return cloned;
  61. }
  62. function defaults(obj1, obj2) {
  63. var newObj = obj2 || {};
  64. if (!obj2._defaults) {
  65. newObj = {};
  66. var defaults_1 = CloneHelper(obj1);
  67. newObj._defaults = defaults_1;
  68. var cloned = obj2 ? CloneHelper(obj2) : {};
  69. Object.assign(newObj, defaults_1, cloned);
  70. }
  71. return newObj;
  72. }
  73. function copyOptions(obj1, obj2) {
  74. if (obj2 && obj2._defaults) {
  75. return obj2;
  76. }
  77. var opts = defaults(obj1, obj2);
  78. if (opts.strictMath) {
  79. opts.math = Math$1.STRICT_LEGACY;
  80. }
  81. // Back compat with changed relativeUrls option
  82. if (opts.relativeUrls) {
  83. opts.rewriteUrls = RewriteUrls.ALL;
  84. }
  85. if (typeof opts.math === 'string') {
  86. switch (opts.math.toLowerCase()) {
  87. case 'always':
  88. opts.math = Math$1.ALWAYS;
  89. break;
  90. case 'parens-division':
  91. opts.math = Math$1.PARENS_DIVISION;
  92. break;
  93. case 'strict':
  94. case 'parens':
  95. opts.math = Math$1.PARENS;
  96. break;
  97. case 'strict-legacy':
  98. opts.math = Math$1.STRICT_LEGACY;
  99. }
  100. }
  101. if (typeof opts.rewriteUrls === 'string') {
  102. switch (opts.rewriteUrls.toLowerCase()) {
  103. case 'off':
  104. opts.rewriteUrls = RewriteUrls.OFF;
  105. break;
  106. case 'local':
  107. opts.rewriteUrls = RewriteUrls.LOCAL;
  108. break;
  109. case 'all':
  110. opts.rewriteUrls = RewriteUrls.ALL;
  111. break;
  112. }
  113. }
  114. return opts;
  115. }
  116. function merge(obj1, obj2) {
  117. for (var prop in obj2) {
  118. if (obj2.hasOwnProperty(prop)) {
  119. obj1[prop] = obj2[prop];
  120. }
  121. }
  122. return obj1;
  123. }
  124. function flattenArray(arr, result) {
  125. if (result === void 0) { result = []; }
  126. for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) {
  127. var value = arr[i_1];
  128. if (Array.isArray(value)) {
  129. flattenArray(value, result);
  130. }
  131. else {
  132. if (value !== undefined) {
  133. result.push(value);
  134. }
  135. }
  136. }
  137. return result;
  138. }
  139. var utils = /*#__PURE__*/Object.freeze({
  140. __proto__: null,
  141. getLocation: getLocation,
  142. copyArray: copyArray,
  143. clone: clone,
  144. defaults: defaults,
  145. copyOptions: copyOptions,
  146. merge: merge,
  147. flattenArray: flattenArray
  148. });
  149. var environment = {
  150. encodeBase64: function encodeBase64(str) {
  151. // Avoid Buffer constructor on newer versions of Node.js.
  152. var buffer = (Buffer.from ? Buffer.from(str) : (new Buffer(str)));
  153. return buffer.toString('base64');
  154. },
  155. mimeLookup: function (filename) {
  156. return require('mime').lookup(filename);
  157. },
  158. charsetLookup: function (mime) {
  159. return require('mime').charsets.lookup(mime);
  160. },
  161. getSourceMapGenerator: function getSourceMapGenerator() {
  162. return require('source-map').SourceMapGenerator;
  163. }
  164. };
  165. var AbstractFileManager = /** @class */ (function () {
  166. function AbstractFileManager() {
  167. }
  168. AbstractFileManager.prototype.getPath = function (filename) {
  169. var j = filename.lastIndexOf('?');
  170. if (j > 0) {
  171. filename = filename.slice(0, j);
  172. }
  173. j = filename.lastIndexOf('/');
  174. if (j < 0) {
  175. j = filename.lastIndexOf('\\');
  176. }
  177. if (j < 0) {
  178. return '';
  179. }
  180. return filename.slice(0, j + 1);
  181. };
  182. AbstractFileManager.prototype.tryAppendExtension = function (path, ext) {
  183. return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext;
  184. };
  185. AbstractFileManager.prototype.tryAppendLessExtension = function (path) {
  186. return this.tryAppendExtension(path, '.less');
  187. };
  188. AbstractFileManager.prototype.supportsSync = function () { return false; };
  189. AbstractFileManager.prototype.alwaysMakePathsAbsolute = function () { return false; };
  190. AbstractFileManager.prototype.isPathAbsolute = function (filename) {
  191. return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename);
  192. };
  193. // TODO: pull out / replace?
  194. AbstractFileManager.prototype.join = function (basePath, laterPath) {
  195. if (!basePath) {
  196. return laterPath;
  197. }
  198. return basePath + laterPath;
  199. };
  200. AbstractFileManager.prototype.pathDiff = function (url, baseUrl) {
  201. // diff between two paths to create a relative path
  202. var urlParts = this.extractUrlParts(url);
  203. var baseUrlParts = this.extractUrlParts(baseUrl);
  204. var i;
  205. var max;
  206. var urlDirectories;
  207. var baseUrlDirectories;
  208. var diff = '';
  209. if (urlParts.hostPart !== baseUrlParts.hostPart) {
  210. return '';
  211. }
  212. max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
  213. for (i = 0; i < max; i++) {
  214. if (baseUrlParts.directories[i] !== urlParts.directories[i]) {
  215. break;
  216. }
  217. }
  218. baseUrlDirectories = baseUrlParts.directories.slice(i);
  219. urlDirectories = urlParts.directories.slice(i);
  220. for (i = 0; i < baseUrlDirectories.length - 1; i++) {
  221. diff += '../';
  222. }
  223. for (i = 0; i < urlDirectories.length - 1; i++) {
  224. diff += urlDirectories[i] + "/";
  225. }
  226. return diff;
  227. };
  228. // helper function, not part of API
  229. AbstractFileManager.prototype.extractUrlParts = function (url, baseUrl) {
  230. // urlParts[1] = protocol://hostname/ OR /
  231. // urlParts[2] = / if path relative to host base
  232. // urlParts[3] = directories
  233. // urlParts[4] = filename
  234. // urlParts[5] = parameters
  235. var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i;
  236. var urlParts = url.match(urlPartsRegex);
  237. var returner = {};
  238. var rawDirectories = [];
  239. var directories = [];
  240. var i;
  241. var baseUrlParts;
  242. if (!urlParts) {
  243. throw new Error("Could not parse sheet href - '" + url + "'");
  244. }
  245. // Stylesheets in IE don't always return the full path
  246. if (baseUrl && (!urlParts[1] || urlParts[2])) {
  247. baseUrlParts = baseUrl.match(urlPartsRegex);
  248. if (!baseUrlParts) {
  249. throw new Error("Could not parse page url - '" + baseUrl + "'");
  250. }
  251. urlParts[1] = urlParts[1] || baseUrlParts[1] || '';
  252. if (!urlParts[2]) {
  253. urlParts[3] = baseUrlParts[3] + urlParts[3];
  254. }
  255. }
  256. if (urlParts[3]) {
  257. rawDirectories = urlParts[3].replace(/\\/g, '/').split('/');
  258. // collapse '..' and skip '.'
  259. for (i = 0; i < rawDirectories.length; i++) {
  260. if (rawDirectories[i] === '..') {
  261. directories.pop();
  262. }
  263. else if (rawDirectories[i] !== '.') {
  264. directories.push(rawDirectories[i]);
  265. }
  266. }
  267. }
  268. returner.hostPart = urlParts[1];
  269. returner.directories = directories;
  270. returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/');
  271. returner.path = (urlParts[1] || '') + directories.join('/');
  272. returner.filename = urlParts[4];
  273. returner.fileUrl = returner.path + (urlParts[4] || '');
  274. returner.url = returner.fileUrl + (urlParts[5] || '');
  275. return returner;
  276. };
  277. return AbstractFileManager;
  278. }());
  279. var FileManager = /** @class */ (function (_super) {
  280. tslib.__extends(FileManager, _super);
  281. function FileManager() {
  282. return _super !== null && _super.apply(this, arguments) || this;
  283. }
  284. FileManager.prototype.supports = function () {
  285. return true;
  286. };
  287. FileManager.prototype.supportsSync = function () {
  288. return true;
  289. };
  290. FileManager.prototype.loadFile = function (filename, currentDirectory, options, environment, callback) {
  291. var fullFilename;
  292. var isAbsoluteFilename = this.isPathAbsolute(filename);
  293. var filenamesTried = [];
  294. var self = this;
  295. var prefix = filename.slice(0, 1);
  296. var explicit = prefix === '.' || prefix === '/';
  297. var result = null;
  298. var isNodeModule = false;
  299. var npmPrefix = 'npm://';
  300. options = options || {};
  301. var paths = isAbsoluteFilename ? [''] : [currentDirectory];
  302. if (options.paths) {
  303. paths.push.apply(paths, options.paths);
  304. }
  305. if (!isAbsoluteFilename && paths.indexOf('.') === -1) {
  306. paths.push('.');
  307. }
  308. var prefixes = options.prefixes || [''];
  309. var fileParts = this.extractUrlParts(filename);
  310. if (options.syncImport) {
  311. getFileData(returnData, returnData);
  312. if (callback) {
  313. callback(result.error, result);
  314. }
  315. else {
  316. return result;
  317. }
  318. }
  319. else {
  320. // promise is guaranteed to be asyncronous
  321. // which helps as it allows the file handle
  322. // to be closed before it continues with the next file
  323. return new Promise(getFileData);
  324. }
  325. function returnData(data) {
  326. if (!data.filename) {
  327. result = { error: data };
  328. }
  329. else {
  330. result = data;
  331. }
  332. }
  333. function getFileData(fulfill, reject) {
  334. (function tryPathIndex(i) {
  335. if (i < paths.length) {
  336. (function tryPrefix(j) {
  337. if (j < prefixes.length) {
  338. isNodeModule = false;
  339. fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename;
  340. if (paths[i]) {
  341. fullFilename = path.join(paths[i], fullFilename);
  342. }
  343. if (!explicit && paths[i] === '.') {
  344. try {
  345. fullFilename = require.resolve(fullFilename);
  346. isNodeModule = true;
  347. }
  348. catch (e) {
  349. filenamesTried.push(npmPrefix + fullFilename);
  350. tryWithExtension();
  351. }
  352. }
  353. else {
  354. tryWithExtension();
  355. }
  356. function tryWithExtension() {
  357. var extFilename = options.ext ? self.tryAppendExtension(fullFilename, options.ext) : fullFilename;
  358. if (extFilename !== fullFilename && !explicit && paths[i] === '.') {
  359. try {
  360. fullFilename = require.resolve(extFilename);
  361. isNodeModule = true;
  362. }
  363. catch (e) {
  364. filenamesTried.push(npmPrefix + extFilename);
  365. fullFilename = extFilename;
  366. }
  367. }
  368. else {
  369. fullFilename = extFilename;
  370. }
  371. }
  372. var readFileArgs = [fullFilename];
  373. if (!options.rawBuffer) {
  374. readFileArgs.push('utf-8');
  375. }
  376. if (options.syncImport) {
  377. try {
  378. var data = fs$1.readFileSync.apply(this, readFileArgs);
  379. fulfill({ contents: data, filename: fullFilename });
  380. }
  381. catch (e) {
  382. filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename);
  383. return tryPrefix(j + 1);
  384. }
  385. }
  386. else {
  387. readFileArgs.push(function (e, data) {
  388. if (e) {
  389. filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename);
  390. return tryPrefix(j + 1);
  391. }
  392. fulfill({ contents: data, filename: fullFilename });
  393. });
  394. fs$1.readFile.apply(this, readFileArgs);
  395. }
  396. }
  397. else {
  398. tryPathIndex(i + 1);
  399. }
  400. })(0);
  401. }
  402. else {
  403. reject({ type: 'File', message: "'" + filename + "' wasn't found. Tried - " + filenamesTried.join(',') });
  404. }
  405. }(0));
  406. }
  407. };
  408. FileManager.prototype.loadFileSync = function (filename, currentDirectory, options, environment) {
  409. options.syncImport = true;
  410. return this.loadFile(filename, currentDirectory, options, environment);
  411. };
  412. return FileManager;
  413. }(AbstractFileManager));
  414. var logger = {
  415. error: function (msg) {
  416. this._fireEvent('error', msg);
  417. },
  418. warn: function (msg) {
  419. this._fireEvent('warn', msg);
  420. },
  421. info: function (msg) {
  422. this._fireEvent('info', msg);
  423. },
  424. debug: function (msg) {
  425. this._fireEvent('debug', msg);
  426. },
  427. addListener: function (listener) {
  428. this._listeners.push(listener);
  429. },
  430. removeListener: function (listener) {
  431. for (var i_1 = 0; i_1 < this._listeners.length; i_1++) {
  432. if (this._listeners[i_1] === listener) {
  433. this._listeners.splice(i_1, 1);
  434. return;
  435. }
  436. }
  437. },
  438. _fireEvent: function (type, msg) {
  439. for (var i_2 = 0; i_2 < this._listeners.length; i_2++) {
  440. var logFunction = this._listeners[i_2][type];
  441. if (logFunction) {
  442. logFunction(msg);
  443. }
  444. }
  445. },
  446. _listeners: []
  447. };
  448. var isUrlRe = /^(?:https?:)?\/\//i;
  449. var request;
  450. var UrlFileManager = /** @class */ (function (_super) {
  451. tslib.__extends(UrlFileManager, _super);
  452. function UrlFileManager() {
  453. return _super !== null && _super.apply(this, arguments) || this;
  454. }
  455. UrlFileManager.prototype.supports = function (filename, currentDirectory, options, environment) {
  456. return isUrlRe.test(filename) || isUrlRe.test(currentDirectory);
  457. };
  458. UrlFileManager.prototype.loadFile = function (filename, currentDirectory, options, environment) {
  459. return new Promise(function (fulfill, reject) {
  460. if (request === undefined) {
  461. try {
  462. request = require('request');
  463. }
  464. catch (e) {
  465. request = null;
  466. }
  467. }
  468. if (!request) {
  469. reject({ type: 'File', message: 'optional dependency \'request\' required to import over http(s)\n' });
  470. return;
  471. }
  472. var urlStr = isUrlRe.test(filename) ? filename : url.resolve(currentDirectory, filename);
  473. var urlObj = url.parse(urlStr);
  474. if (!urlObj.protocol) {
  475. urlObj.protocol = 'http';
  476. urlStr = urlObj.format();
  477. }
  478. request.get({ uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) {
  479. if (error) {
  480. reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n " + error + "\n" });
  481. return;
  482. }
  483. if (res && res.statusCode === 404) {
  484. reject({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
  485. return;
  486. }
  487. if (!body) {
  488. logger.warn("Warning: Empty body (HTTP " + res.statusCode + ") returned by \"" + urlStr + "\"");
  489. }
  490. fulfill({ contents: body, filename: urlStr });
  491. });
  492. });
  493. };
  494. return UrlFileManager;
  495. }(AbstractFileManager));
  496. var colors = {
  497. 'aliceblue': '#f0f8ff',
  498. 'antiquewhite': '#faebd7',
  499. 'aqua': '#00ffff',
  500. 'aquamarine': '#7fffd4',
  501. 'azure': '#f0ffff',
  502. 'beige': '#f5f5dc',
  503. 'bisque': '#ffe4c4',
  504. 'black': '#000000',
  505. 'blanchedalmond': '#ffebcd',
  506. 'blue': '#0000ff',
  507. 'blueviolet': '#8a2be2',
  508. 'brown': '#a52a2a',
  509. 'burlywood': '#deb887',
  510. 'cadetblue': '#5f9ea0',
  511. 'chartreuse': '#7fff00',
  512. 'chocolate': '#d2691e',
  513. 'coral': '#ff7f50',
  514. 'cornflowerblue': '#6495ed',
  515. 'cornsilk': '#fff8dc',
  516. 'crimson': '#dc143c',
  517. 'cyan': '#00ffff',
  518. 'darkblue': '#00008b',
  519. 'darkcyan': '#008b8b',
  520. 'darkgoldenrod': '#b8860b',
  521. 'darkgray': '#a9a9a9',
  522. 'darkgrey': '#a9a9a9',
  523. 'darkgreen': '#006400',
  524. 'darkkhaki': '#bdb76b',
  525. 'darkmagenta': '#8b008b',
  526. 'darkolivegreen': '#556b2f',
  527. 'darkorange': '#ff8c00',
  528. 'darkorchid': '#9932cc',
  529. 'darkred': '#8b0000',
  530. 'darksalmon': '#e9967a',
  531. 'darkseagreen': '#8fbc8f',
  532. 'darkslateblue': '#483d8b',
  533. 'darkslategray': '#2f4f4f',
  534. 'darkslategrey': '#2f4f4f',
  535. 'darkturquoise': '#00ced1',
  536. 'darkviolet': '#9400d3',
  537. 'deeppink': '#ff1493',
  538. 'deepskyblue': '#00bfff',
  539. 'dimgray': '#696969',
  540. 'dimgrey': '#696969',
  541. 'dodgerblue': '#1e90ff',
  542. 'firebrick': '#b22222',
  543. 'floralwhite': '#fffaf0',
  544. 'forestgreen': '#228b22',
  545. 'fuchsia': '#ff00ff',
  546. 'gainsboro': '#dcdcdc',
  547. 'ghostwhite': '#f8f8ff',
  548. 'gold': '#ffd700',
  549. 'goldenrod': '#daa520',
  550. 'gray': '#808080',
  551. 'grey': '#808080',
  552. 'green': '#008000',
  553. 'greenyellow': '#adff2f',
  554. 'honeydew': '#f0fff0',
  555. 'hotpink': '#ff69b4',
  556. 'indianred': '#cd5c5c',
  557. 'indigo': '#4b0082',
  558. 'ivory': '#fffff0',
  559. 'khaki': '#f0e68c',
  560. 'lavender': '#e6e6fa',
  561. 'lavenderblush': '#fff0f5',
  562. 'lawngreen': '#7cfc00',
  563. 'lemonchiffon': '#fffacd',
  564. 'lightblue': '#add8e6',
  565. 'lightcoral': '#f08080',
  566. 'lightcyan': '#e0ffff',
  567. 'lightgoldenrodyellow': '#fafad2',
  568. 'lightgray': '#d3d3d3',
  569. 'lightgrey': '#d3d3d3',
  570. 'lightgreen': '#90ee90',
  571. 'lightpink': '#ffb6c1',
  572. 'lightsalmon': '#ffa07a',
  573. 'lightseagreen': '#20b2aa',
  574. 'lightskyblue': '#87cefa',
  575. 'lightslategray': '#778899',
  576. 'lightslategrey': '#778899',
  577. 'lightsteelblue': '#b0c4de',
  578. 'lightyellow': '#ffffe0',
  579. 'lime': '#00ff00',
  580. 'limegreen': '#32cd32',
  581. 'linen': '#faf0e6',
  582. 'magenta': '#ff00ff',
  583. 'maroon': '#800000',
  584. 'mediumaquamarine': '#66cdaa',
  585. 'mediumblue': '#0000cd',
  586. 'mediumorchid': '#ba55d3',
  587. 'mediumpurple': '#9370d8',
  588. 'mediumseagreen': '#3cb371',
  589. 'mediumslateblue': '#7b68ee',
  590. 'mediumspringgreen': '#00fa9a',
  591. 'mediumturquoise': '#48d1cc',
  592. 'mediumvioletred': '#c71585',
  593. 'midnightblue': '#191970',
  594. 'mintcream': '#f5fffa',
  595. 'mistyrose': '#ffe4e1',
  596. 'moccasin': '#ffe4b5',
  597. 'navajowhite': '#ffdead',
  598. 'navy': '#000080',
  599. 'oldlace': '#fdf5e6',
  600. 'olive': '#808000',
  601. 'olivedrab': '#6b8e23',
  602. 'orange': '#ffa500',
  603. 'orangered': '#ff4500',
  604. 'orchid': '#da70d6',
  605. 'palegoldenrod': '#eee8aa',
  606. 'palegreen': '#98fb98',
  607. 'paleturquoise': '#afeeee',
  608. 'palevioletred': '#d87093',
  609. 'papayawhip': '#ffefd5',
  610. 'peachpuff': '#ffdab9',
  611. 'peru': '#cd853f',
  612. 'pink': '#ffc0cb',
  613. 'plum': '#dda0dd',
  614. 'powderblue': '#b0e0e6',
  615. 'purple': '#800080',
  616. 'rebeccapurple': '#663399',
  617. 'red': '#ff0000',
  618. 'rosybrown': '#bc8f8f',
  619. 'royalblue': '#4169e1',
  620. 'saddlebrown': '#8b4513',
  621. 'salmon': '#fa8072',
  622. 'sandybrown': '#f4a460',
  623. 'seagreen': '#2e8b57',
  624. 'seashell': '#fff5ee',
  625. 'sienna': '#a0522d',
  626. 'silver': '#c0c0c0',
  627. 'skyblue': '#87ceeb',
  628. 'slateblue': '#6a5acd',
  629. 'slategray': '#708090',
  630. 'slategrey': '#708090',
  631. 'snow': '#fffafa',
  632. 'springgreen': '#00ff7f',
  633. 'steelblue': '#4682b4',
  634. 'tan': '#d2b48c',
  635. 'teal': '#008080',
  636. 'thistle': '#d8bfd8',
  637. 'tomato': '#ff6347',
  638. 'turquoise': '#40e0d0',
  639. 'violet': '#ee82ee',
  640. 'wheat': '#f5deb3',
  641. 'white': '#ffffff',
  642. 'whitesmoke': '#f5f5f5',
  643. 'yellow': '#ffff00',
  644. 'yellowgreen': '#9acd32'
  645. };
  646. var unitConversions = {
  647. length: {
  648. 'm': 1,
  649. 'cm': 0.01,
  650. 'mm': 0.001,
  651. 'in': 0.0254,
  652. 'px': 0.0254 / 96,
  653. 'pt': 0.0254 / 72,
  654. 'pc': 0.0254 / 72 * 12
  655. },
  656. duration: {
  657. 's': 1,
  658. 'ms': 0.001
  659. },
  660. angle: {
  661. 'rad': 1 / (2 * Math.PI),
  662. 'deg': 1 / 360,
  663. 'grad': 1 / 400,
  664. 'turn': 1
  665. }
  666. };
  667. var data = { colors: colors, unitConversions: unitConversions };
  668. var Node = /** @class */ (function () {
  669. function Node() {
  670. this.parent = null;
  671. this.visibilityBlocks = undefined;
  672. this.nodeVisible = undefined;
  673. this.rootNode = null;
  674. this.parsed = null;
  675. var self = this;
  676. Object.defineProperty(this, 'currentFileInfo', {
  677. get: function () { return self.fileInfo(); }
  678. });
  679. Object.defineProperty(this, 'index', {
  680. get: function () { return self.getIndex(); }
  681. });
  682. }
  683. Node.prototype.setParent = function (nodes, parent) {
  684. function set(node) {
  685. if (node && node instanceof Node) {
  686. node.parent = parent;
  687. }
  688. }
  689. if (Array.isArray(nodes)) {
  690. nodes.forEach(set);
  691. }
  692. else {
  693. set(nodes);
  694. }
  695. };
  696. Node.prototype.getIndex = function () {
  697. return this._index || (this.parent && this.parent.getIndex()) || 0;
  698. };
  699. Node.prototype.fileInfo = function () {
  700. return this._fileInfo || (this.parent && this.parent.fileInfo()) || {};
  701. };
  702. Node.prototype.isRulesetLike = function () {
  703. return false;
  704. };
  705. Node.prototype.toCSS = function (context) {
  706. var strs = [];
  707. this.genCSS(context, {
  708. add: function (chunk, fileInfo, index) {
  709. strs.push(chunk);
  710. },
  711. isEmpty: function () {
  712. return strs.length === 0;
  713. }
  714. });
  715. return strs.join('');
  716. };
  717. Node.prototype.genCSS = function (context, output) {
  718. output.add(this.value);
  719. };
  720. Node.prototype.accept = function (visitor) {
  721. this.value = visitor.visit(this.value);
  722. };
  723. Node.prototype.eval = function () { return this; };
  724. Node.prototype._operate = function (context, op, a, b) {
  725. switch (op) {
  726. case '+': return a + b;
  727. case '-': return a - b;
  728. case '*': return a * b;
  729. case '/': return a / b;
  730. }
  731. };
  732. Node.prototype.fround = function (context, value) {
  733. var precision = context && context.numPrecision;
  734. // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded:
  735. return (precision) ? Number((value + 2e-16).toFixed(precision)) : value;
  736. };
  737. // Returns true if this node represents root of ast imported by reference
  738. Node.prototype.blocksVisibility = function () {
  739. if (this.visibilityBlocks == null) {
  740. this.visibilityBlocks = 0;
  741. }
  742. return this.visibilityBlocks !== 0;
  743. };
  744. Node.prototype.addVisibilityBlock = function () {
  745. if (this.visibilityBlocks == null) {
  746. this.visibilityBlocks = 0;
  747. }
  748. this.visibilityBlocks = this.visibilityBlocks + 1;
  749. };
  750. Node.prototype.removeVisibilityBlock = function () {
  751. if (this.visibilityBlocks == null) {
  752. this.visibilityBlocks = 0;
  753. }
  754. this.visibilityBlocks = this.visibilityBlocks - 1;
  755. };
  756. // Turns on node visibility - if called node will be shown in output regardless
  757. // of whether it comes from import by reference or not
  758. Node.prototype.ensureVisibility = function () {
  759. this.nodeVisible = true;
  760. };
  761. // Turns off node visibility - if called node will NOT be shown in output regardless
  762. // of whether it comes from import by reference or not
  763. Node.prototype.ensureInvisibility = function () {
  764. this.nodeVisible = false;
  765. };
  766. // return values:
  767. // false - the node must not be visible
  768. // true - the node must be visible
  769. // undefined or null - the node has the same visibility as its parent
  770. Node.prototype.isVisible = function () {
  771. return this.nodeVisible;
  772. };
  773. Node.prototype.visibilityInfo = function () {
  774. return {
  775. visibilityBlocks: this.visibilityBlocks,
  776. nodeVisible: this.nodeVisible
  777. };
  778. };
  779. Node.prototype.copyVisibilityInfo = function (info) {
  780. if (!info) {
  781. return;
  782. }
  783. this.visibilityBlocks = info.visibilityBlocks;
  784. this.nodeVisible = info.nodeVisible;
  785. };
  786. return Node;
  787. }());
  788. Node.compare = function (a, b) {
  789. /* returns:
  790. -1: a < b
  791. 0: a = b
  792. 1: a > b
  793. and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */
  794. if ((a.compare) &&
  795. // for "symmetric results" force toCSS-based comparison
  796. // of Quoted or Anonymous if either value is one of those
  797. !(b.type === 'Quoted' || b.type === 'Anonymous')) {
  798. return a.compare(b);
  799. }
  800. else if (b.compare) {
  801. return -b.compare(a);
  802. }
  803. else if (a.type !== b.type) {
  804. return undefined;
  805. }
  806. a = a.value;
  807. b = b.value;
  808. if (!Array.isArray(a)) {
  809. return a === b ? 0 : undefined;
  810. }
  811. if (a.length !== b.length) {
  812. return undefined;
  813. }
  814. for (var i_1 = 0; i_1 < a.length; i_1++) {
  815. if (Node.compare(a[i_1], b[i_1]) !== 0) {
  816. return undefined;
  817. }
  818. }
  819. return 0;
  820. };
  821. Node.numericCompare = function (a, b) { return a < b ? -1
  822. : a === b ? 0
  823. : a > b ? 1 : undefined; };
  824. //
  825. // RGB Colors - #ff0014, #eee
  826. //
  827. var Color = /** @class */ (function (_super) {
  828. tslib.__extends(Color, _super);
  829. function Color(rgb, a, originalForm) {
  830. var _this = _super.call(this) || this;
  831. var self = _this;
  832. //
  833. // The end goal here, is to parse the arguments
  834. // into an integer triplet, such as `128, 255, 0`
  835. //
  836. // This facilitates operations and conversions.
  837. //
  838. if (Array.isArray(rgb)) {
  839. _this.rgb = rgb;
  840. }
  841. else if (rgb.length >= 6) {
  842. _this.rgb = [];
  843. rgb.match(/.{2}/g).map(function (c, i) {
  844. if (i < 3) {
  845. self.rgb.push(parseInt(c, 16));
  846. }
  847. else {
  848. self.alpha = (parseInt(c, 16)) / 255;
  849. }
  850. });
  851. }
  852. else {
  853. _this.rgb = [];
  854. rgb.split('').map(function (c, i) {
  855. if (i < 3) {
  856. self.rgb.push(parseInt(c + c, 16));
  857. }
  858. else {
  859. self.alpha = (parseInt(c + c, 16)) / 255;
  860. }
  861. });
  862. }
  863. _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1);
  864. if (typeof originalForm !== 'undefined') {
  865. _this.value = originalForm;
  866. }
  867. return _this;
  868. }
  869. Color.prototype.luma = function () {
  870. var r = this.rgb[0] / 255;
  871. var g = this.rgb[1] / 255;
  872. var b = this.rgb[2] / 255;
  873. r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
  874. g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
  875. b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
  876. return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  877. };
  878. Color.prototype.genCSS = function (context, output) {
  879. output.add(this.toCSS(context));
  880. };
  881. Color.prototype.toCSS = function (context, doNotCompress) {
  882. var compress = context && context.compress && !doNotCompress;
  883. var color;
  884. var alpha;
  885. var colorFunction;
  886. var args = [];
  887. // `value` is set if this color was originally
  888. // converted from a named color string so we need
  889. // to respect this and try to output named color too.
  890. alpha = this.fround(context, this.alpha);
  891. if (this.value) {
  892. if (this.value.indexOf('rgb') === 0) {
  893. if (alpha < 1) {
  894. colorFunction = 'rgba';
  895. }
  896. }
  897. else if (this.value.indexOf('hsl') === 0) {
  898. if (alpha < 1) {
  899. colorFunction = 'hsla';
  900. }
  901. else {
  902. colorFunction = 'hsl';
  903. }
  904. }
  905. else {
  906. return this.value;
  907. }
  908. }
  909. else {
  910. if (alpha < 1) {
  911. colorFunction = 'rgba';
  912. }
  913. }
  914. switch (colorFunction) {
  915. case 'rgba':
  916. args = this.rgb.map(function (c) { return clamp(Math.round(c), 255); }).concat(clamp(alpha, 1));
  917. break;
  918. case 'hsla':
  919. args.push(clamp(alpha, 1));
  920. case 'hsl':
  921. color = this.toHSL();
  922. args = [
  923. this.fround(context, color.h),
  924. this.fround(context, color.s * 100) + "%",
  925. this.fround(context, color.l * 100) + "%"
  926. ].concat(args);
  927. }
  928. if (colorFunction) {
  929. // Values are capped between `0` and `255`, rounded and zero-padded.
  930. return colorFunction + "(" + args.join("," + (compress ? '' : ' ')) + ")";
  931. }
  932. color = this.toRGB();
  933. if (compress) {
  934. var splitcolor = color.split('');
  935. // Convert color to short format
  936. if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {
  937. color = "#" + splitcolor[1] + splitcolor[3] + splitcolor[5];
  938. }
  939. }
  940. return color;
  941. };
  942. //
  943. // Operations have to be done per-channel, if not,
  944. // channels will spill onto each other. Once we have
  945. // our result, in the form of an integer triplet,
  946. // we create a new Color node to hold the result.
  947. //
  948. Color.prototype.operate = function (context, op, other) {
  949. var rgb = new Array(3);
  950. var alpha = this.alpha * (1 - other.alpha) + other.alpha;
  951. for (var c = 0; c < 3; c++) {
  952. rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);
  953. }
  954. return new Color(rgb, alpha);
  955. };
  956. Color.prototype.toRGB = function () {
  957. return toHex(this.rgb);
  958. };
  959. Color.prototype.toHSL = function () {
  960. var r = this.rgb[0] / 255;
  961. var g = this.rgb[1] / 255;
  962. var b = this.rgb[2] / 255;
  963. var a = this.alpha;
  964. var max = Math.max(r, g, b);
  965. var min = Math.min(r, g, b);
  966. var h;
  967. var s;
  968. var l = (max + min) / 2;
  969. var d = max - min;
  970. if (max === min) {
  971. h = s = 0;
  972. }
  973. else {
  974. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  975. switch (max) {
  976. case r:
  977. h = (g - b) / d + (g < b ? 6 : 0);
  978. break;
  979. case g:
  980. h = (b - r) / d + 2;
  981. break;
  982. case b:
  983. h = (r - g) / d + 4;
  984. break;
  985. }
  986. h /= 6;
  987. }
  988. return { h: h * 360, s: s, l: l, a: a };
  989. };
  990. // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
  991. Color.prototype.toHSV = function () {
  992. var r = this.rgb[0] / 255;
  993. var g = this.rgb[1] / 255;
  994. var b = this.rgb[2] / 255;
  995. var a = this.alpha;
  996. var max = Math.max(r, g, b);
  997. var min = Math.min(r, g, b);
  998. var h;
  999. var s;
  1000. var v = max;
  1001. var d = max - min;
  1002. if (max === 0) {
  1003. s = 0;
  1004. }
  1005. else {
  1006. s = d / max;
  1007. }
  1008. if (max === min) {
  1009. h = 0;
  1010. }
  1011. else {
  1012. switch (max) {
  1013. case r:
  1014. h = (g - b) / d + (g < b ? 6 : 0);
  1015. break;
  1016. case g:
  1017. h = (b - r) / d + 2;
  1018. break;
  1019. case b:
  1020. h = (r - g) / d + 4;
  1021. break;
  1022. }
  1023. h /= 6;
  1024. }
  1025. return { h: h * 360, s: s, v: v, a: a };
  1026. };
  1027. Color.prototype.toARGB = function () {
  1028. return toHex([this.alpha * 255].concat(this.rgb));
  1029. };
  1030. Color.prototype.compare = function (x) {
  1031. return (x.rgb &&
  1032. x.rgb[0] === this.rgb[0] &&
  1033. x.rgb[1] === this.rgb[1] &&
  1034. x.rgb[2] === this.rgb[2] &&
  1035. x.alpha === this.alpha) ? 0 : undefined;
  1036. };
  1037. return Color;
  1038. }(Node));
  1039. Color.prototype.type = 'Color';
  1040. function clamp(v, max) {
  1041. return Math.min(Math.max(v, 0), max);
  1042. }
  1043. function toHex(v) {
  1044. return "#" + v.map(function (c) {
  1045. c = clamp(Math.round(c), 255);
  1046. return (c < 16 ? '0' : '') + c.toString(16);
  1047. }).join('');
  1048. }
  1049. Color.fromKeyword = function (keyword) {
  1050. var c;
  1051. var key = keyword.toLowerCase();
  1052. if (colors.hasOwnProperty(key)) {
  1053. c = new Color(colors[key].slice(1));
  1054. }
  1055. else if (key === 'transparent') {
  1056. c = new Color([0, 0, 0], 0);
  1057. }
  1058. if (c) {
  1059. c.value = keyword;
  1060. return c;
  1061. }
  1062. };
  1063. var Paren = /** @class */ (function (_super) {
  1064. tslib.__extends(Paren, _super);
  1065. function Paren(node) {
  1066. var _this = _super.call(this) || this;
  1067. _this.value = node;
  1068. return _this;
  1069. }
  1070. Paren.prototype.genCSS = function (context, output) {
  1071. output.add('(');
  1072. this.value.genCSS(context, output);
  1073. output.add(')');
  1074. };
  1075. Paren.prototype.eval = function (context) {
  1076. return new Paren(this.value.eval(context));
  1077. };
  1078. return Paren;
  1079. }(Node));
  1080. Paren.prototype.type = 'Paren';
  1081. var _noSpaceCombinators = {
  1082. '': true,
  1083. ' ': true,
  1084. '|': true
  1085. };
  1086. var Combinator = /** @class */ (function (_super) {
  1087. tslib.__extends(Combinator, _super);
  1088. function Combinator(value) {
  1089. var _this = _super.call(this) || this;
  1090. if (value === ' ') {
  1091. _this.value = ' ';
  1092. _this.emptyOrWhitespace = true;
  1093. }
  1094. else {
  1095. _this.value = value ? value.trim() : '';
  1096. _this.emptyOrWhitespace = _this.value === '';
  1097. }
  1098. return _this;
  1099. }
  1100. Combinator.prototype.genCSS = function (context, output) {
  1101. var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';
  1102. output.add(spaceOrEmpty + this.value + spaceOrEmpty);
  1103. };
  1104. return Combinator;
  1105. }(Node));
  1106. Combinator.prototype.type = 'Combinator';
  1107. var Element = /** @class */ (function (_super) {
  1108. tslib.__extends(Element, _super);
  1109. function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
  1110. var _this = _super.call(this) || this;
  1111. _this.combinator = combinator instanceof Combinator ?
  1112. combinator : new Combinator(combinator);
  1113. if (typeof value === 'string') {
  1114. _this.value = value.trim();
  1115. }
  1116. else if (value) {
  1117. _this.value = value;
  1118. }
  1119. else {
  1120. _this.value = '';
  1121. }
  1122. _this.isVariable = isVariable;
  1123. _this._index = index;
  1124. _this._fileInfo = currentFileInfo;
  1125. _this.copyVisibilityInfo(visibilityInfo);
  1126. _this.setParent(_this.combinator, _this);
  1127. return _this;
  1128. }
  1129. Element.prototype.accept = function (visitor) {
  1130. var value = this.value;
  1131. this.combinator = visitor.visit(this.combinator);
  1132. if (typeof value === 'object') {
  1133. this.value = visitor.visit(value);
  1134. }
  1135. };
  1136. Element.prototype.eval = function (context) {
  1137. return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  1138. };
  1139. Element.prototype.clone = function () {
  1140. return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  1141. };
  1142. Element.prototype.genCSS = function (context, output) {
  1143. output.add(this.toCSS(context), this.fileInfo(), this.getIndex());
  1144. };
  1145. Element.prototype.toCSS = function (context) {
  1146. if (context === void 0) { context = {}; }
  1147. var value = this.value;
  1148. var firstSelector = context.firstSelector;
  1149. if (value instanceof Paren) {
  1150. // selector in parens should not be affected by outer selector
  1151. // flags (breaks only interpolated selectors - see #1973)
  1152. context.firstSelector = true;
  1153. }
  1154. value = value.toCSS ? value.toCSS(context) : value;
  1155. context.firstSelector = firstSelector;
  1156. if (value === '' && this.combinator.value.charAt(0) === '&') {
  1157. return '';
  1158. }
  1159. else {
  1160. return this.combinator.toCSS(context) + value;
  1161. }
  1162. };
  1163. return Element;
  1164. }(Node));
  1165. Element.prototype.type = 'Element';
  1166. var anonymousFunc = /(<anonymous>|Function):(\d+):(\d+)/;
  1167. /**
  1168. * This is a centralized class of any error that could be thrown internally (mostly by the parser).
  1169. * Besides standard .message it keeps some additional data like a path to the file where the error
  1170. * occurred along with line and column numbers.
  1171. *
  1172. * @class
  1173. * @extends Error
  1174. * @type {module.LessError}
  1175. *
  1176. * @prop {string} type
  1177. * @prop {string} filename
  1178. * @prop {number} index
  1179. * @prop {number} line
  1180. * @prop {number} column
  1181. * @prop {number} callLine
  1182. * @prop {number} callExtract
  1183. * @prop {string[]} extract
  1184. *
  1185. * @param {Object} e - An error object to wrap around or just a descriptive object
  1186. * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?
  1187. * @param {string} [currentFilename]
  1188. */
  1189. var LessError = function LessError(e, fileContentMap, currentFilename) {
  1190. Error.call(this);
  1191. var filename = e.filename || currentFilename;
  1192. this.message = e.message;
  1193. this.stack = e.stack;
  1194. if (fileContentMap && filename) {
  1195. var input = fileContentMap.contents[filename];
  1196. var loc = getLocation(e.index, input);
  1197. var line = loc.line;
  1198. var col = loc.column;
  1199. var callLine = e.call && getLocation(e.call, input).line;
  1200. var lines = input ? input.split('\n') : '';
  1201. this.type = e.type || 'Syntax';
  1202. this.filename = filename;
  1203. this.index = e.index;
  1204. this.line = typeof line === 'number' ? line + 1 : null;
  1205. this.column = col;
  1206. if (!this.line && this.stack) {
  1207. var found = this.stack.match(anonymousFunc);
  1208. /**
  1209. * We have to figure out how this environment stringifies anonymous functions
  1210. * so we can correctly map plugin errors.
  1211. *
  1212. * Note, in Node 8, the output of anonymous funcs varied based on parameters
  1213. * being present or not, so we inject dummy params.
  1214. */
  1215. var func = new Function('a', 'throw new Error()');
  1216. var lineAdjust = 0;
  1217. try {
  1218. func();
  1219. }
  1220. catch (e) {
  1221. var match = e.stack.match(anonymousFunc);
  1222. var line_1 = parseInt(match[2]);
  1223. lineAdjust = 1 - line_1;
  1224. }
  1225. if (found) {
  1226. if (found[2]) {
  1227. this.line = parseInt(found[2]) + lineAdjust;
  1228. }
  1229. if (found[3]) {
  1230. this.column = parseInt(found[3]);
  1231. }
  1232. }
  1233. }
  1234. this.callLine = callLine + 1;
  1235. this.callExtract = lines[callLine];
  1236. this.extract = [
  1237. lines[this.line - 2],
  1238. lines[this.line - 1],
  1239. lines[this.line]
  1240. ];
  1241. }
  1242. };
  1243. if (typeof Object.create === 'undefined') {
  1244. var F = function () { };
  1245. F.prototype = Error.prototype;
  1246. LessError.prototype = new F();
  1247. }
  1248. else {
  1249. LessError.prototype = Object.create(Error.prototype);
  1250. }
  1251. LessError.prototype.constructor = LessError;
  1252. /**
  1253. * An overridden version of the default Object.prototype.toString
  1254. * which uses additional information to create a helpful message.
  1255. *
  1256. * @param {Object} options
  1257. * @returns {string}
  1258. */
  1259. LessError.prototype.toString = function (options) {
  1260. if (options === void 0) { options = {}; }
  1261. var message = '';
  1262. var extract = this.extract || [];
  1263. var error = [];
  1264. var stylize = function (str) { return str; };
  1265. if (options.stylize) {
  1266. var type = typeof options.stylize;
  1267. if (type !== 'function') {
  1268. throw Error("options.stylize should be a function, got a " + type + "!");
  1269. }
  1270. stylize = options.stylize;
  1271. }
  1272. if (this.line !== null) {
  1273. if (typeof extract[0] === 'string') {
  1274. error.push(stylize(this.line - 1 + " " + extract[0], 'grey'));
  1275. }
  1276. if (typeof extract[1] === 'string') {
  1277. var errorTxt = this.line + " ";
  1278. if (extract[1]) {
  1279. errorTxt += extract[1].slice(0, this.column) +
  1280. stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') +
  1281. extract[1].slice(this.column + 1), 'red'), 'inverse');
  1282. }
  1283. error.push(errorTxt);
  1284. }
  1285. if (typeof extract[2] === 'string') {
  1286. error.push(stylize(this.line + 1 + " " + extract[2], 'grey'));
  1287. }
  1288. error = error.join('\n') + stylize('', 'reset') + "\n";
  1289. }
  1290. message += stylize(this.type + "Error: " + this.message, 'red');
  1291. if (this.filename) {
  1292. message += stylize(' in ', 'red') + this.filename;
  1293. }
  1294. if (this.line) {
  1295. message += stylize(" on line " + this.line + ", column " + (this.column + 1) + ":", 'grey');
  1296. }
  1297. message += "\n" + error;
  1298. if (this.callLine) {
  1299. message += stylize('from ', 'red') + (this.filename || '') + "/n";
  1300. message += stylize(this.callLine, 'grey') + " " + this.callExtract + "/n";
  1301. }
  1302. return message;
  1303. };
  1304. var Selector = /** @class */ (function (_super) {
  1305. tslib.__extends(Selector, _super);
  1306. function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) {
  1307. var _this = _super.call(this) || this;
  1308. _this.extendList = extendList;
  1309. _this.condition = condition;
  1310. _this.evaldCondition = !condition;
  1311. _this._index = index;
  1312. _this._fileInfo = currentFileInfo;
  1313. _this.elements = _this.getElements(elements);
  1314. _this.mixinElements_ = undefined;
  1315. _this.copyVisibilityInfo(visibilityInfo);
  1316. _this.setParent(_this.elements, _this);
  1317. return _this;
  1318. }
  1319. Selector.prototype.accept = function (visitor) {
  1320. if (this.elements) {
  1321. this.elements = visitor.visitArray(this.elements);
  1322. }
  1323. if (this.extendList) {
  1324. this.extendList = visitor.visitArray(this.extendList);
  1325. }
  1326. if (this.condition) {
  1327. this.condition = visitor.visit(this.condition);
  1328. }
  1329. };
  1330. Selector.prototype.createDerived = function (elements, extendList, evaldCondition) {
  1331. elements = this.getElements(elements);
  1332. var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  1333. newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;
  1334. newSelector.mediaEmpty = this.mediaEmpty;
  1335. return newSelector;
  1336. };
  1337. Selector.prototype.getElements = function (els) {
  1338. if (!els) {
  1339. return [new Element('', '&', false, this._index, this._fileInfo)];
  1340. }
  1341. if (typeof els === 'string') {
  1342. this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) {
  1343. if (err) {
  1344. throw new LessError({
  1345. index: err.index,
  1346. message: err.message
  1347. }, this.parse.imports, this._fileInfo.filename);
  1348. }
  1349. els = result[0].elements;
  1350. });
  1351. }
  1352. return els;
  1353. };
  1354. Selector.prototype.createEmptySelectors = function () {
  1355. var el = new Element('', '&', false, this._index, this._fileInfo);
  1356. var sels = [new Selector([el], null, null, this._index, this._fileInfo)];
  1357. sels[0].mediaEmpty = true;
  1358. return sels;
  1359. };
  1360. Selector.prototype.match = function (other) {
  1361. var elements = this.elements;
  1362. var len = elements.length;
  1363. var olen;
  1364. var i;
  1365. other = other.mixinElements();
  1366. olen = other.length;
  1367. if (olen === 0 || len < olen) {
  1368. return 0;
  1369. }
  1370. else {
  1371. for (i = 0; i < olen; i++) {
  1372. if (elements[i].value !== other[i]) {
  1373. return 0;
  1374. }
  1375. }
  1376. }
  1377. return olen; // return number of matched elements
  1378. };
  1379. Selector.prototype.mixinElements = function () {
  1380. if (this.mixinElements_) {
  1381. return this.mixinElements_;
  1382. }
  1383. var elements = this.elements.map(function (v) { return v.combinator.value + (v.value.value || v.value); }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g);
  1384. if (elements) {
  1385. if (elements[0] === '&') {
  1386. elements.shift();
  1387. }
  1388. }
  1389. else {
  1390. elements = [];
  1391. }
  1392. return (this.mixinElements_ = elements);
  1393. };
  1394. Selector.prototype.isJustParentSelector = function () {
  1395. return !this.mediaEmpty &&
  1396. this.elements.length === 1 &&
  1397. this.elements[0].value === '&' &&
  1398. (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');
  1399. };
  1400. Selector.prototype.eval = function (context) {
  1401. var evaldCondition = this.condition && this.condition.eval(context);
  1402. var elements = this.elements;
  1403. var extendList = this.extendList;
  1404. elements = elements && elements.map(function (e) { return e.eval(context); });
  1405. extendList = extendList && extendList.map(function (extend) { return extend.eval(context); });
  1406. return this.createDerived(elements, extendList, evaldCondition);
  1407. };
  1408. Selector.prototype.genCSS = function (context, output) {
  1409. var i;
  1410. var element;
  1411. if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') {
  1412. output.add(' ', this.fileInfo(), this.getIndex());
  1413. }
  1414. for (i = 0; i < this.elements.length; i++) {
  1415. element = this.elements[i];
  1416. element.genCSS(context, output);
  1417. }
  1418. };
  1419. Selector.prototype.getIsOutput = function () {
  1420. return this.evaldCondition;
  1421. };
  1422. return Selector;
  1423. }(Node));
  1424. Selector.prototype.type = 'Selector';
  1425. var Value = /** @class */ (function (_super) {
  1426. tslib.__extends(Value, _super);
  1427. function Value(value) {
  1428. var _this = _super.call(this) || this;
  1429. if (!value) {
  1430. throw new Error('Value requires an array argument');
  1431. }
  1432. if (!Array.isArray(value)) {
  1433. _this.value = [value];
  1434. }
  1435. else {
  1436. _this.value = value;
  1437. }
  1438. return _this;
  1439. }
  1440. Value.prototype.accept = function (visitor) {
  1441. if (this.value) {
  1442. this.value = visitor.visitArray(this.value);
  1443. }
  1444. };
  1445. Value.prototype.eval = function (context) {
  1446. if (this.value.length === 1) {
  1447. return this.value[0].eval(context);
  1448. }
  1449. else {
  1450. return new Value(this.value.map(function (v) { return v.eval(context); }));
  1451. }
  1452. };
  1453. Value.prototype.genCSS = function (context, output) {
  1454. var i;
  1455. for (i = 0; i < this.value.length; i++) {
  1456. this.value[i].genCSS(context, output);
  1457. if (i + 1 < this.value.length) {
  1458. output.add((context && context.compress) ? ',' : ', ');
  1459. }
  1460. }
  1461. };
  1462. return Value;
  1463. }(Node));
  1464. Value.prototype.type = 'Value';
  1465. var Keyword = /** @class */ (function (_super) {
  1466. tslib.__extends(Keyword, _super);
  1467. function Keyword(value) {
  1468. var _this = _super.call(this) || this;
  1469. _this.value = value;
  1470. return _this;
  1471. }
  1472. Keyword.prototype.genCSS = function (context, output) {
  1473. if (this.value === '%') {
  1474. throw { type: 'Syntax', message: 'Invalid % without number' };
  1475. }
  1476. output.add(this.value);
  1477. };
  1478. return Keyword;
  1479. }(Node));
  1480. Keyword.prototype.type = 'Keyword';
  1481. Keyword.True = new Keyword('true');
  1482. Keyword.False = new Keyword('false');
  1483. var Anonymous = /** @class */ (function (_super) {
  1484. tslib.__extends(Anonymous, _super);
  1485. function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
  1486. var _this = _super.call(this) || this;
  1487. _this.value = value;
  1488. _this._index = index;
  1489. _this._fileInfo = currentFileInfo;
  1490. _this.mapLines = mapLines;
  1491. _this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
  1492. _this.allowRoot = true;
  1493. _this.copyVisibilityInfo(visibilityInfo);
  1494. return _this;
  1495. }
  1496. Anonymous.prototype.eval = function () {
  1497. return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
  1498. };
  1499. Anonymous.prototype.compare = function (other) {
  1500. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  1501. };
  1502. Anonymous.prototype.isRulesetLike = function () {
  1503. return this.rulesetLike;
  1504. };
  1505. Anonymous.prototype.genCSS = function (context, output) {
  1506. this.nodeVisible = Boolean(this.value);
  1507. if (this.nodeVisible) {
  1508. output.add(this.value, this._fileInfo, this._index, this.mapLines);
  1509. }
  1510. };
  1511. return Anonymous;
  1512. }(Node));
  1513. Anonymous.prototype.type = 'Anonymous';
  1514. var MATH = Math$1;
  1515. var Declaration = /** @class */ (function (_super) {
  1516. tslib.__extends(Declaration, _super);
  1517. function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) {
  1518. var _this = _super.call(this) || this;
  1519. _this.name = name;
  1520. _this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);
  1521. _this.important = important ? " " + important.trim() : '';
  1522. _this.merge = merge;
  1523. _this._index = index;
  1524. _this._fileInfo = currentFileInfo;
  1525. _this.inline = inline || false;
  1526. _this.variable = (variable !== undefined) ? variable
  1527. : (name.charAt && (name.charAt(0) === '@'));
  1528. _this.allowRoot = true;
  1529. _this.setParent(_this.value, _this);
  1530. return _this;
  1531. }
  1532. Declaration.prototype.genCSS = function (context, output) {
  1533. output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());
  1534. try {
  1535. this.value.genCSS(context, output);
  1536. }
  1537. catch (e) {
  1538. e.index = this._index;
  1539. e.filename = this._fileInfo.filename;
  1540. throw e;
  1541. }
  1542. output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);
  1543. };
  1544. Declaration.prototype.eval = function (context) {
  1545. var mathBypass = false;
  1546. var prevMath;
  1547. var name = this.name;
  1548. var evaldValue;
  1549. var variable = this.variable;
  1550. if (typeof name !== 'string') {
  1551. // expand 'primitive' name directly to get
  1552. // things faster (~10% for benchmark.less):
  1553. name = (name.length === 1) && (name[0] instanceof Keyword) ?
  1554. name[0].value : evalName(context, name);
  1555. variable = false; // never treat expanded interpolation as new variable name
  1556. }
  1557. // @todo remove when parens-division is default
  1558. if (name === 'font' && context.math === MATH.ALWAYS) {
  1559. mathBypass = true;
  1560. prevMath = context.math;
  1561. context.math = MATH.PARENS_DIVISION;
  1562. }
  1563. try {
  1564. context.importantScope.push({});
  1565. evaldValue = this.value.eval(context);
  1566. if (!this.variable && evaldValue.type === 'DetachedRuleset') {
  1567. throw { message: 'Rulesets cannot be evaluated on a property.',
  1568. index: this.getIndex(), filename: this.fileInfo().filename };
  1569. }
  1570. var important = this.important;
  1571. var importantResult = context.importantScope.pop();
  1572. if (!important && importantResult.important) {
  1573. important = importantResult.important;
  1574. }
  1575. return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable);
  1576. }
  1577. catch (e) {
  1578. if (typeof e.index !== 'number') {
  1579. e.index = this.getIndex();
  1580. e.filename = this.fileInfo().filename;
  1581. }
  1582. throw e;
  1583. }
  1584. finally {
  1585. if (mathBypass) {
  1586. context.math = prevMath;
  1587. }
  1588. }
  1589. };
  1590. Declaration.prototype.makeImportant = function () {
  1591. return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline);
  1592. };
  1593. return Declaration;
  1594. }(Node));
  1595. function evalName(context, name) {
  1596. var value = '';
  1597. var i;
  1598. var n = name.length;
  1599. var output = { add: function (s) { value += s; } };
  1600. for (i = 0; i < n; i++) {
  1601. name[i].eval(context).genCSS(context, output);
  1602. }
  1603. return value;
  1604. }
  1605. Declaration.prototype.type = 'Declaration';
  1606. var debugInfo = function (context, ctx, lineSeparator) {
  1607. var result = '';
  1608. if (context.dumpLineNumbers && !context.compress) {
  1609. switch (context.dumpLineNumbers) {
  1610. case 'comments':
  1611. result = debugInfo.asComment(ctx);
  1612. break;
  1613. case 'mediaquery':
  1614. result = debugInfo.asMediaQuery(ctx);
  1615. break;
  1616. case 'all':
  1617. result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx);
  1618. break;
  1619. }
  1620. }
  1621. return result;
  1622. };
  1623. debugInfo.asComment = function (ctx) { return "/* line " + ctx.debugInfo.lineNumber + ", " + ctx.debugInfo.fileName + " */\n"; };
  1624. debugInfo.asMediaQuery = function (ctx) {
  1625. var filenameWithProtocol = ctx.debugInfo.fileName;
  1626. if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) {
  1627. filenameWithProtocol = "file://" + filenameWithProtocol;
  1628. }
  1629. return "@media -sass-debug-info{filename{font-family:" + filenameWithProtocol.replace(/([.:\/\\])/g, function (a) {
  1630. if (a == '\\') {
  1631. a = '\/';
  1632. }
  1633. return "\\" + a;
  1634. }) + "}line{font-family:\\00003" + ctx.debugInfo.lineNumber + "}}\n";
  1635. };
  1636. var Comment = /** @class */ (function (_super) {
  1637. tslib.__extends(Comment, _super);
  1638. function Comment(value, isLineComment, index, currentFileInfo) {
  1639. var _this = _super.call(this) || this;
  1640. _this.value = value;
  1641. _this.isLineComment = isLineComment;
  1642. _this._index = index;
  1643. _this._fileInfo = currentFileInfo;
  1644. _this.allowRoot = true;
  1645. return _this;
  1646. }
  1647. Comment.prototype.genCSS = function (context, output) {
  1648. if (this.debugInfo) {
  1649. output.add(debugInfo(context, this), this.fileInfo(), this.getIndex());
  1650. }
  1651. output.add(this.value);
  1652. };
  1653. Comment.prototype.isSilent = function (context) {
  1654. var isCompressed = context.compress && this.value[2] !== '!';
  1655. return this.isLineComment || isCompressed;
  1656. };
  1657. return Comment;
  1658. }(Node));
  1659. Comment.prototype.type = 'Comment';
  1660. var contexts = {};
  1661. var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {
  1662. if (!original) {
  1663. return;
  1664. }
  1665. for (var i_1 = 0; i_1 < propertiesToCopy.length; i_1++) {
  1666. if (original.hasOwnProperty(propertiesToCopy[i_1])) {
  1667. destination[propertiesToCopy[i_1]] = original[propertiesToCopy[i_1]];
  1668. }
  1669. }
  1670. };
  1671. /*
  1672. parse is used whilst parsing
  1673. */
  1674. var parseCopyProperties = [
  1675. // options
  1676. 'paths',
  1677. 'rewriteUrls',
  1678. 'rootpath',
  1679. 'strictImports',
  1680. 'insecure',
  1681. 'dumpLineNumbers',
  1682. 'compress',
  1683. 'syncImport',
  1684. 'chunkInput',
  1685. 'mime',
  1686. 'useFileCache',
  1687. // context
  1688. 'processImports',
  1689. // Used by the import manager to stop multiple import visitors being created.
  1690. 'pluginManager' // Used as the plugin manager for the session
  1691. ];
  1692. contexts.Parse = function (options) {
  1693. copyFromOriginal(options, this, parseCopyProperties);
  1694. if (typeof this.paths === 'string') {
  1695. this.paths = [this.paths];
  1696. }
  1697. };
  1698. var evalCopyProperties = [
  1699. 'paths',
  1700. 'compress',
  1701. 'math',
  1702. 'strictUnits',
  1703. 'sourceMap',
  1704. 'importMultiple',
  1705. 'urlArgs',
  1706. 'javascriptEnabled',
  1707. 'pluginManager',
  1708. 'importantScope',
  1709. 'rewriteUrls' // option - whether to adjust URL's to be relative
  1710. ];
  1711. function isPathRelative(path) {
  1712. return !/^(?:[a-z-]+:|\/|#)/i.test(path);
  1713. }
  1714. function isPathLocalRelative(path) {
  1715. return path.charAt(0) === '.';
  1716. }
  1717. contexts.Eval = /** @class */ (function () {
  1718. function Eval(options, frames) {
  1719. copyFromOriginal(options, this, evalCopyProperties);
  1720. if (typeof this.paths === 'string') {
  1721. this.paths = [this.paths];
  1722. }
  1723. this.frames = frames || [];
  1724. this.importantScope = this.importantScope || [];
  1725. this.inCalc = false;
  1726. this.mathOn = true;
  1727. }
  1728. Eval.prototype.enterCalc = function () {
  1729. if (!this.calcStack) {
  1730. this.calcStack = [];
  1731. }
  1732. this.calcStack.push(true);
  1733. this.inCalc = true;
  1734. };
  1735. Eval.prototype.exitCalc = function () {
  1736. this.calcStack.pop();
  1737. if (!this.calcStack) {
  1738. this.inCalc = false;
  1739. }
  1740. };
  1741. Eval.prototype.inParenthesis = function () {
  1742. if (!this.parensStack) {
  1743. this.parensStack = [];
  1744. }
  1745. this.parensStack.push(true);
  1746. };
  1747. Eval.prototype.outOfParenthesis = function () {
  1748. this.parensStack.pop();
  1749. };
  1750. Eval.prototype.isMathOn = function (op) {
  1751. if (!this.mathOn) {
  1752. return false;
  1753. }
  1754. if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) {
  1755. return false;
  1756. }
  1757. if (this.math > Math$1.PARENS_DIVISION) {
  1758. return this.parensStack && this.parensStack.length;
  1759. }
  1760. return true;
  1761. };
  1762. Eval.prototype.pathRequiresRewrite = function (path) {
  1763. var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative;
  1764. return isRelative(path);
  1765. };
  1766. Eval.prototype.rewritePath = function (path, rootpath) {
  1767. var newPath;
  1768. rootpath = rootpath || '';
  1769. newPath = this.normalizePath(rootpath + path);
  1770. // If a path was explicit relative and the rootpath was not an absolute path
  1771. // we must ensure that the new path is also explicit relative.
  1772. if (isPathLocalRelative(path) &&
  1773. isPathRelative(rootpath) &&
  1774. isPathLocalRelative(newPath) === false) {
  1775. newPath = "./" + newPath;
  1776. }
  1777. return newPath;
  1778. };
  1779. Eval.prototype.normalizePath = function (path) {
  1780. var segments = path.split('/').reverse();
  1781. var segment;
  1782. path = [];
  1783. while (segments.length !== 0) {
  1784. segment = segments.pop();
  1785. switch (segment) {
  1786. case '.':
  1787. break;
  1788. case '..':
  1789. if ((path.length === 0) || (path[path.length - 1] === '..')) {
  1790. path.push(segment);
  1791. }
  1792. else {
  1793. path.pop();
  1794. }
  1795. break;
  1796. default:
  1797. path.push(segment);
  1798. break;
  1799. }
  1800. }
  1801. return path.join('/');
  1802. };
  1803. return Eval;
  1804. }());
  1805. function makeRegistry(base) {
  1806. return {
  1807. _data: {},
  1808. add: function (name, func) {
  1809. // precautionary case conversion, as later querying of
  1810. // the registry by function-caller uses lower case as well.
  1811. name = name.toLowerCase();
  1812. if (this._data.hasOwnProperty(name)) ;
  1813. this._data[name] = func;
  1814. },
  1815. addMultiple: function (functions) {
  1816. var _this = this;
  1817. Object.keys(functions).forEach(function (name) {
  1818. _this.add(name, functions[name]);
  1819. });
  1820. },
  1821. get: function (name) {
  1822. return this._data[name] || (base && base.get(name));
  1823. },
  1824. getLocalFunctions: function () {
  1825. return this._data;
  1826. },
  1827. inherit: function () {
  1828. return makeRegistry(this);
  1829. },
  1830. create: function (base) {
  1831. return makeRegistry(base);
  1832. }
  1833. };
  1834. }
  1835. var functionRegistry = makeRegistry(null);
  1836. var defaultFunc = {
  1837. eval: function () {
  1838. var v = this.value_;
  1839. var e = this.error_;
  1840. if (e) {
  1841. throw e;
  1842. }
  1843. if (v != null) {
  1844. return v ? Keyword.True : Keyword.False;
  1845. }
  1846. },
  1847. value: function (v) {
  1848. this.value_ = v;
  1849. },
  1850. error: function (e) {
  1851. this.error_ = e;
  1852. },
  1853. reset: function () {
  1854. this.value_ = this.error_ = null;
  1855. }
  1856. };
  1857. var Ruleset = /** @class */ (function (_super) {
  1858. tslib.__extends(Ruleset, _super);
  1859. function Ruleset(selectors, rules, strictImports, visibilityInfo) {
  1860. var _this = _super.call(this) || this;
  1861. _this.selectors = selectors;
  1862. _this.rules = rules;
  1863. _this._lookups = {};
  1864. _this._variables = null;
  1865. _this._properties = null;
  1866. _this.strictImports = strictImports;
  1867. _this.copyVisibilityInfo(visibilityInfo);
  1868. _this.allowRoot = true;
  1869. _this.setParent(_this.selectors, _this);
  1870. _this.setParent(_this.rules, _this);
  1871. return _this;
  1872. }
  1873. Ruleset.prototype.isRulesetLike = function () {
  1874. return true;
  1875. };
  1876. Ruleset.prototype.accept = function (visitor) {
  1877. if (this.paths) {
  1878. this.paths = visitor.visitArray(this.paths, true);
  1879. }
  1880. else if (this.selectors) {
  1881. this.selectors = visitor.visitArray(this.selectors);
  1882. }
  1883. if (this.rules && this.rules.length) {
  1884. this.rules = visitor.visitArray(this.rules);
  1885. }
  1886. };
  1887. Ruleset.prototype.eval = function (context) {
  1888. var selectors;
  1889. var selCnt;
  1890. var selector;
  1891. var i;
  1892. var hasVariable;
  1893. var hasOnePassingSelector = false;
  1894. if (this.selectors && (selCnt = this.selectors.length)) {
  1895. selectors = new Array(selCnt);
  1896. defaultFunc.error({
  1897. type: 'Syntax',
  1898. message: 'it is currently only allowed in parametric mixin guards,'
  1899. });
  1900. for (i = 0; i < selCnt; i++) {
  1901. selector = this.selectors[i].eval(context);
  1902. for (var j = 0; j < selector.elements.length; j++) {
  1903. if (selector.elements[j].isVariable) {
  1904. hasVariable = true;
  1905. break;
  1906. }
  1907. }
  1908. selectors[i] = selector;
  1909. if (selector.evaldCondition) {
  1910. hasOnePassingSelector = true;
  1911. }
  1912. }
  1913. if (hasVariable) {
  1914. var toParseSelectors = new Array(selCnt);
  1915. for (i = 0; i < selCnt; i++) {
  1916. selector = selectors[i];
  1917. toParseSelectors[i] = selector.toCSS(context);
  1918. }
  1919. this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) {
  1920. if (result) {
  1921. selectors = flattenArray(result);
  1922. }
  1923. });
  1924. }
  1925. defaultFunc.reset();
  1926. }
  1927. else {
  1928. hasOnePassingSelector = true;
  1929. }
  1930. var rules = this.rules ? copyArray(this.rules) : null;
  1931. var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo());
  1932. var rule;
  1933. var subRule;
  1934. ruleset.originalRuleset = this;
  1935. ruleset.root = this.root;
  1936. ruleset.firstRoot = this.firstRoot;
  1937. ruleset.allowImports = this.allowImports;
  1938. if (this.debugInfo) {
  1939. ruleset.debugInfo = this.debugInfo;
  1940. }
  1941. if (!hasOnePassingSelector) {
  1942. rules.length = 0;
  1943. }
  1944. // inherit a function registry from the frames stack when possible;
  1945. // otherwise from the global registry
  1946. ruleset.functionRegistry = (function (frames) {
  1947. var i = 0;
  1948. var n = frames.length;
  1949. var found;
  1950. for (; i !== n; ++i) {
  1951. found = frames[i].functionRegistry;
  1952. if (found) {
  1953. return found;
  1954. }
  1955. }
  1956. return functionRegistry;
  1957. })(context.frames).inherit();
  1958. // push the current ruleset to the frames stack
  1959. var ctxFrames = context.frames;
  1960. ctxFrames.unshift(ruleset);
  1961. // currrent selectors
  1962. var ctxSelectors = context.selectors;
  1963. if (!ctxSelectors) {
  1964. context.selectors = ctxSelectors = [];
  1965. }
  1966. ctxSelectors.unshift(this.selectors);
  1967. // Evaluate imports
  1968. if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
  1969. ruleset.evalImports(context);
  1970. }
  1971. // Store the frames around mixin definitions,
  1972. // so they can be evaluated like closures when the time comes.
  1973. var rsRules = ruleset.rules;
  1974. for (i = 0; (rule = rsRules[i]); i++) {
  1975. if (rule.evalFirst) {
  1976. rsRules[i] = rule.eval(context);
  1977. }
  1978. }
  1979. var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;
  1980. // Evaluate mixin calls.
  1981. for (i = 0; (rule = rsRules[i]); i++) {
  1982. if (rule.type === 'MixinCall') {
  1983. /* jshint loopfunc:true */
  1984. rules = rule.eval(context).filter(function (r) {
  1985. if ((r instanceof Declaration) && r.variable) {
  1986. // do not pollute the scope if the variable is
  1987. // already there. consider returning false here
  1988. // but we need a way to "return" variable from mixins
  1989. return !(ruleset.variable(r.name));
  1990. }
  1991. return true;
  1992. });
  1993. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  1994. i += rules.length - 1;
  1995. ruleset.resetCache();
  1996. }
  1997. else if (rule.type === 'VariableCall') {
  1998. /* jshint loopfunc:true */
  1999. rules = rule.eval(context).rules.filter(function (r) {
  2000. if ((r instanceof Declaration) && r.variable) {
  2001. // do not pollute the scope at all
  2002. return false;
  2003. }
  2004. return true;
  2005. });
  2006. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  2007. i += rules.length - 1;
  2008. ruleset.resetCache();
  2009. }
  2010. }
  2011. // Evaluate everything else
  2012. for (i = 0; (rule = rsRules[i]); i++) {
  2013. if (!rule.evalFirst) {
  2014. rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;
  2015. }
  2016. }
  2017. // Evaluate everything else
  2018. for (i = 0; (rule = rsRules[i]); i++) {
  2019. // for rulesets, check if it is a css guard and can be removed
  2020. if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
  2021. // check if it can be folded in (e.g. & where)
  2022. if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) {
  2023. rsRules.splice(i--, 1);
  2024. for (var j = 0; (subRule = rule.rules[j]); j++) {
  2025. if (subRule instanceof Node) {
  2026. subRule.copyVisibilityInfo(rule.visibilityInfo());
  2027. if (!(subRule instanceof Declaration) || !subRule.variable) {
  2028. rsRules.splice(++i, 0, subRule);
  2029. }
  2030. }
  2031. }
  2032. }
  2033. }
  2034. }
  2035. // Pop the stack
  2036. ctxFrames.shift();
  2037. ctxSelectors.shift();
  2038. if (context.mediaBlocks) {
  2039. for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {
  2040. context.mediaBlocks[i].bubbleSelectors(selectors);
  2041. }
  2042. }
  2043. return ruleset;
  2044. };
  2045. Ruleset.prototype.evalImports = function (context) {
  2046. var rules = this.rules;
  2047. var i;
  2048. var importRules;
  2049. if (!rules) {
  2050. return;
  2051. }
  2052. for (i = 0; i < rules.length; i++) {
  2053. if (rules[i].type === 'Import') {
  2054. importRules = rules[i].eval(context);
  2055. if (importRules && (importRules.length || importRules.length === 0)) {
  2056. rules.splice.apply(rules, [i, 1].concat(importRules));
  2057. i += importRules.length - 1;
  2058. }
  2059. else {
  2060. rules.splice(i, 1, importRules);
  2061. }
  2062. this.resetCache();
  2063. }
  2064. }
  2065. };
  2066. Ruleset.prototype.makeImportant = function () {
  2067. var result = new Ruleset(this.selectors, this.rules.map(function (r) {
  2068. if (r.makeImportant) {
  2069. return r.makeImportant();
  2070. }
  2071. else {
  2072. return r;
  2073. }
  2074. }), this.strictImports, this.visibilityInfo());
  2075. return result;
  2076. };
  2077. Ruleset.prototype.matchArgs = function (args) {
  2078. return !args || args.length === 0;
  2079. };
  2080. // lets you call a css selector with a guard
  2081. Ruleset.prototype.matchCondition = function (args, context) {
  2082. var lastSelector = this.selectors[this.selectors.length - 1];
  2083. if (!lastSelector.evaldCondition) {
  2084. return false;
  2085. }
  2086. if (lastSelector.condition &&
  2087. !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) {
  2088. return false;
  2089. }
  2090. return true;
  2091. };
  2092. Ruleset.prototype.resetCache = function () {
  2093. this._rulesets = null;
  2094. this._variables = null;
  2095. this._properties = null;
  2096. this._lookups = {};
  2097. };
  2098. Ruleset.prototype.variables = function () {
  2099. if (!this._variables) {
  2100. this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  2101. if (r instanceof Declaration && r.variable === true) {
  2102. hash[r.name] = r;
  2103. }
  2104. // when evaluating variables in an import statement, imports have not been eval'd
  2105. // so we need to go inside import statements.
  2106. // guard against root being a string (in the case of inlined less)
  2107. if (r.type === 'Import' && r.root && r.root.variables) {
  2108. var vars = r.root.variables();
  2109. for (var name_1 in vars) {
  2110. if (vars.hasOwnProperty(name_1)) {
  2111. hash[name_1] = r.root.variable(name_1);
  2112. }
  2113. }
  2114. }
  2115. return hash;
  2116. }, {});
  2117. }
  2118. return this._variables;
  2119. };
  2120. Ruleset.prototype.properties = function () {
  2121. if (!this._properties) {
  2122. this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  2123. if (r instanceof Declaration && r.variable !== true) {
  2124. var name_2 = (r.name.length === 1) && (r.name[0] instanceof Keyword) ?
  2125. r.name[0].value : r.name;
  2126. // Properties don't overwrite as they can merge
  2127. if (!hash["$" + name_2]) {
  2128. hash["$" + name_2] = [r];
  2129. }
  2130. else {
  2131. hash["$" + name_2].push(r);
  2132. }
  2133. }
  2134. return hash;
  2135. }, {});
  2136. }
  2137. return this._properties;
  2138. };
  2139. Ruleset.prototype.variable = function (name) {
  2140. var decl = this.variables()[name];
  2141. if (decl) {
  2142. return this.parseValue(decl);
  2143. }
  2144. };
  2145. Ruleset.prototype.property = function (name) {
  2146. var decl = this.properties()[name];
  2147. if (decl) {
  2148. return this.parseValue(decl);
  2149. }
  2150. };
  2151. Ruleset.prototype.lastDeclaration = function () {
  2152. for (var i_1 = this.rules.length; i_1 > 0; i_1--) {
  2153. var decl = this.rules[i_1 - 1];
  2154. if (decl instanceof Declaration) {
  2155. return this.parseValue(decl);
  2156. }
  2157. }
  2158. };
  2159. Ruleset.prototype.parseValue = function (toParse) {
  2160. var self = this;
  2161. function transformDeclaration(decl) {
  2162. if (decl.value instanceof Anonymous && !decl.parsed) {
  2163. if (typeof decl.value.value === 'string') {
  2164. this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) {
  2165. if (err) {
  2166. decl.parsed = true;
  2167. }
  2168. if (result) {
  2169. decl.value = result[0];
  2170. decl.important = result[1] || '';
  2171. decl.parsed = true;
  2172. }
  2173. });
  2174. }
  2175. else {
  2176. decl.parsed = true;
  2177. }
  2178. return decl;
  2179. }
  2180. else {
  2181. return decl;
  2182. }
  2183. }
  2184. if (!Array.isArray(toParse)) {
  2185. return transformDeclaration.call(self, toParse);
  2186. }
  2187. else {
  2188. var nodes_1 = [];
  2189. toParse.forEach(function (n) {
  2190. nodes_1.push(transformDeclaration.call(self, n));
  2191. });
  2192. return nodes_1;
  2193. }
  2194. };
  2195. Ruleset.prototype.rulesets = function () {
  2196. if (!this.rules) {
  2197. return [];
  2198. }
  2199. var filtRules = [];
  2200. var rules = this.rules;
  2201. var i;
  2202. var rule;
  2203. for (i = 0; (rule = rules[i]); i++) {
  2204. if (rule.isRuleset) {
  2205. filtRules.push(rule);
  2206. }
  2207. }
  2208. return filtRules;
  2209. };
  2210. Ruleset.prototype.prependRule = function (rule) {
  2211. var rules = this.rules;
  2212. if (rules) {
  2213. rules.unshift(rule);
  2214. }
  2215. else {
  2216. this.rules = [rule];
  2217. }
  2218. this.setParent(rule, this);
  2219. };
  2220. Ruleset.prototype.find = function (selector, self, filter) {
  2221. if (self === void 0) { self = this; }
  2222. var rules = [];
  2223. var match;
  2224. var foundMixins;
  2225. var key = selector.toCSS();
  2226. if (key in this._lookups) {
  2227. return this._lookups[key];
  2228. }
  2229. this.rulesets().forEach(function (rule) {
  2230. if (rule !== self) {
  2231. for (var j = 0; j < rule.selectors.length; j++) {
  2232. match = selector.match(rule.selectors[j]);
  2233. if (match) {
  2234. if (selector.elements.length > match) {
  2235. if (!filter || filter(rule)) {
  2236. foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);
  2237. for (var i_2 = 0; i_2 < foundMixins.length; ++i_2) {
  2238. foundMixins[i_2].path.push(rule);
  2239. }
  2240. Array.prototype.push.apply(rules, foundMixins);
  2241. }
  2242. }
  2243. else {
  2244. rules.push({ rule: rule, path: [] });
  2245. }
  2246. break;
  2247. }
  2248. }
  2249. }
  2250. });
  2251. this._lookups[key] = rules;
  2252. return rules;
  2253. };
  2254. Ruleset.prototype.genCSS = function (context, output) {
  2255. var i;
  2256. var j;
  2257. var charsetRuleNodes = [];
  2258. var ruleNodes = [];
  2259. var // Line number debugging
  2260. debugInfo$1;
  2261. var rule;
  2262. var path;
  2263. context.tabLevel = (context.tabLevel || 0);
  2264. if (!this.root) {
  2265. context.tabLevel++;
  2266. }
  2267. var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' ');
  2268. var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' ');
  2269. var sep;
  2270. var charsetNodeIndex = 0;
  2271. var importNodeIndex = 0;
  2272. for (i = 0; (rule = this.rules[i]); i++) {
  2273. if (rule instanceof Comment) {
  2274. if (importNodeIndex === i) {
  2275. importNodeIndex++;
  2276. }
  2277. ruleNodes.push(rule);
  2278. }
  2279. else if (rule.isCharset && rule.isCharset()) {
  2280. ruleNodes.splice(charsetNodeIndex, 0, rule);
  2281. charsetNodeIndex++;
  2282. importNodeIndex++;
  2283. }
  2284. else if (rule.type === 'Import') {
  2285. ruleNodes.splice(importNodeIndex, 0, rule);
  2286. importNodeIndex++;
  2287. }
  2288. else {
  2289. ruleNodes.push(rule);
  2290. }
  2291. }
  2292. ruleNodes = charsetRuleNodes.concat(ruleNodes);
  2293. // If this is the root node, we don't render
  2294. // a selector, or {}.
  2295. if (!this.root) {
  2296. debugInfo$1 = debugInfo(context, this, tabSetStr);
  2297. if (debugInfo$1) {
  2298. output.add(debugInfo$1);
  2299. output.add(tabSetStr);
  2300. }
  2301. var paths = this.paths;
  2302. var pathCnt = paths.length;
  2303. var pathSubCnt = void 0;
  2304. sep = context.compress ? ',' : (",\n" + tabSetStr);
  2305. for (i = 0; i < pathCnt; i++) {
  2306. path = paths[i];
  2307. if (!(pathSubCnt = path.length)) {
  2308. continue;
  2309. }
  2310. if (i > 0) {
  2311. output.add(sep);
  2312. }
  2313. context.firstSelector = true;
  2314. path[0].genCSS(context, output);
  2315. context.firstSelector = false;
  2316. for (j = 1; j < pathSubCnt; j++) {
  2317. path[j].genCSS(context, output);
  2318. }
  2319. }
  2320. output.add((context.compress ? '{' : ' {\n') + tabRuleStr);
  2321. }
  2322. // Compile rules and rulesets
  2323. for (i = 0; (rule = ruleNodes[i]); i++) {
  2324. if (i + 1 === ruleNodes.length) {
  2325. context.lastRule = true;
  2326. }
  2327. var currentLastRule = context.lastRule;
  2328. if (rule.isRulesetLike(rule)) {
  2329. context.lastRule = false;
  2330. }
  2331. if (rule.genCSS) {
  2332. rule.genCSS(context, output);
  2333. }
  2334. else if (rule.value) {
  2335. output.add(rule.value.toString());
  2336. }
  2337. context.lastRule = currentLastRule;
  2338. if (!context.lastRule && rule.isVisible()) {
  2339. output.add(context.compress ? '' : ("\n" + tabRuleStr));
  2340. }
  2341. else {
  2342. context.lastRule = false;
  2343. }
  2344. }
  2345. if (!this.root) {
  2346. output.add((context.compress ? '}' : "\n" + tabSetStr + "}"));
  2347. context.tabLevel--;
  2348. }
  2349. if (!output.isEmpty() && !context.compress && this.firstRoot) {
  2350. output.add('\n');
  2351. }
  2352. };
  2353. Ruleset.prototype.joinSelectors = function (paths, context, selectors) {
  2354. for (var s = 0; s < selectors.length; s++) {
  2355. this.joinSelector(paths, context, selectors[s]);
  2356. }
  2357. };
  2358. Ruleset.prototype.joinSelector = function (paths, context, selector) {
  2359. function createParenthesis(elementsToPak, originalElement) {
  2360. var replacementParen;
  2361. var j;
  2362. if (elementsToPak.length === 0) {
  2363. replacementParen = new Paren(elementsToPak[0]);
  2364. }
  2365. else {
  2366. var insideParent = new Array(elementsToPak.length);
  2367. for (j = 0; j < elementsToPak.length; j++) {
  2368. insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo);
  2369. }
  2370. replacementParen = new Paren(new Selector(insideParent));
  2371. }
  2372. return replacementParen;
  2373. }
  2374. function createSelector(containedElement, originalElement) {
  2375. var element;
  2376. var selector;
  2377. element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo);
  2378. selector = new Selector([element]);
  2379. return selector;
  2380. }
  2381. // joins selector path from `beginningPath` with selector path in `addPath`
  2382. // `replacedElement` contains element that is being replaced by `addPath`
  2383. // returns concatenated path
  2384. function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
  2385. var newSelectorPath;
  2386. var lastSelector;
  2387. var newJoinedSelector;
  2388. // our new selector path
  2389. newSelectorPath = [];
  2390. // construct the joined selector - if & is the first thing this will be empty,
  2391. // if not newJoinedSelector will be the last set of elements in the selector
  2392. if (beginningPath.length > 0) {
  2393. newSelectorPath = copyArray(beginningPath);
  2394. lastSelector = newSelectorPath.pop();
  2395. newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements));
  2396. }
  2397. else {
  2398. newJoinedSelector = originalSelector.createDerived([]);
  2399. }
  2400. if (addPath.length > 0) {
  2401. // /deep/ is a CSS4 selector - (removed, so should deprecate)
  2402. // that is valid without anything in front of it
  2403. // so if the & does not have a combinator that is "" or " " then
  2404. // and there is a combinator on the parent, then grab that.
  2405. // this also allows + a { & .b { .a & { ... though not sure why you would want to do that
  2406. var combinator = replacedElement.combinator;
  2407. var parentEl = addPath[0].elements[0];
  2408. if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
  2409. combinator = parentEl.combinator;
  2410. }
  2411. // join the elements so far with the first part of the parent
  2412. newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo));
  2413. newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
  2414. }
  2415. // now add the joined selector - but only if it is not empty
  2416. if (newJoinedSelector.elements.length !== 0) {
  2417. newSelectorPath.push(newJoinedSelector);
  2418. }
  2419. // put together the parent selectors after the join (e.g. the rest of the parent)
  2420. if (addPath.length > 1) {
  2421. var restOfPath = addPath.slice(1);
  2422. restOfPath = restOfPath.map(function (selector) { return selector.createDerived(selector.elements, []); });
  2423. newSelectorPath = newSelectorPath.concat(restOfPath);
  2424. }
  2425. return newSelectorPath;
  2426. }
  2427. // joins selector path from `beginningPath` with every selector path in `addPaths` array
  2428. // `replacedElement` contains element that is being replaced by `addPath`
  2429. // returns array with all concatenated paths
  2430. function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) {
  2431. var j;
  2432. for (j = 0; j < beginningPath.length; j++) {
  2433. var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
  2434. result.push(newSelectorPath);
  2435. }
  2436. return result;
  2437. }
  2438. function mergeElementsOnToSelectors(elements, selectors) {
  2439. var i;
  2440. var sel;
  2441. if (elements.length === 0) {
  2442. return;
  2443. }
  2444. if (selectors.length === 0) {
  2445. selectors.push([new Selector(elements)]);
  2446. return;
  2447. }
  2448. for (i = 0; (sel = selectors[i]); i++) {
  2449. // if the previous thing in sel is a parent this needs to join on to it
  2450. if (sel.length > 0) {
  2451. sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
  2452. }
  2453. else {
  2454. sel.push(new Selector(elements));
  2455. }
  2456. }
  2457. }
  2458. // replace all parent selectors inside `inSelector` by content of `context` array
  2459. // resulting selectors are returned inside `paths` array
  2460. // returns true if `inSelector` contained at least one parent selector
  2461. function replaceParentSelector(paths, context, inSelector) {
  2462. // The paths are [[Selector]]
  2463. // The first list is a list of comma separated selectors
  2464. // The inner list is a list of inheritance separated selectors
  2465. // e.g.
  2466. // .a, .b {
  2467. // .c {
  2468. // }
  2469. // }
  2470. // == [[.a] [.c]] [[.b] [.c]]
  2471. //
  2472. var i;
  2473. var j;
  2474. var k;
  2475. var currentElements;
  2476. var newSelectors;
  2477. var selectorsMultiplied;
  2478. var sel;
  2479. var el;
  2480. var hadParentSelector = false;
  2481. var length;
  2482. var lastSelector;
  2483. function findNestedSelector(element) {
  2484. var maybeSelector;
  2485. if (!(element.value instanceof Paren)) {
  2486. return null;
  2487. }
  2488. maybeSelector = element.value.value;
  2489. if (!(maybeSelector instanceof Selector)) {
  2490. return null;
  2491. }
  2492. return maybeSelector;
  2493. }
  2494. // the elements from the current selector so far
  2495. currentElements = [];
  2496. // the current list of new selectors to add to the path.
  2497. // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
  2498. // by the parents
  2499. newSelectors = [
  2500. []
  2501. ];
  2502. for (i = 0; (el = inSelector.elements[i]); i++) {
  2503. // non parent reference elements just get added
  2504. if (el.value !== '&') {
  2505. var nestedSelector = findNestedSelector(el);
  2506. if (nestedSelector != null) {
  2507. // merge the current list of non parent selector elements
  2508. // on to the current list of selectors to add
  2509. mergeElementsOnToSelectors(currentElements, newSelectors);
  2510. var nestedPaths = [];
  2511. var replaced = void 0;
  2512. var replacedNewSelectors = [];
  2513. replaced = replaceParentSelector(nestedPaths, context, nestedSelector);
  2514. hadParentSelector = hadParentSelector || replaced;
  2515. // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
  2516. for (k = 0; k < nestedPaths.length; k++) {
  2517. var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);
  2518. addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);
  2519. }
  2520. newSelectors = replacedNewSelectors;
  2521. currentElements = [];
  2522. }
  2523. else {
  2524. currentElements.push(el);
  2525. }
  2526. }
  2527. else {
  2528. hadParentSelector = true;
  2529. // the new list of selectors to add
  2530. selectorsMultiplied = [];
  2531. // merge the current list of non parent selector elements
  2532. // on to the current list of selectors to add
  2533. mergeElementsOnToSelectors(currentElements, newSelectors);
  2534. // loop through our current selectors
  2535. for (j = 0; j < newSelectors.length; j++) {
  2536. sel = newSelectors[j];
  2537. // if we don't have any parent paths, the & might be in a mixin so that it can be used
  2538. // whether there are parents or not
  2539. if (context.length === 0) {
  2540. // the combinator used on el should now be applied to the next element instead so that
  2541. // it is not lost
  2542. if (sel.length > 0) {
  2543. sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo));
  2544. }
  2545. selectorsMultiplied.push(sel);
  2546. }
  2547. else {
  2548. // and the parent selectors
  2549. for (k = 0; k < context.length; k++) {
  2550. // We need to put the current selectors
  2551. // then join the last selector's elements on to the parents selectors
  2552. var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);
  2553. // add that to our new set of selectors
  2554. selectorsMultiplied.push(newSelectorPath);
  2555. }
  2556. }
  2557. }
  2558. // our new selectors has been multiplied, so reset the state
  2559. newSelectors = selectorsMultiplied;
  2560. currentElements = [];
  2561. }
  2562. }
  2563. // if we have any elements left over (e.g. .a& .b == .b)
  2564. // add them on to all the current selectors
  2565. mergeElementsOnToSelectors(currentElements, newSelectors);
  2566. for (i = 0; i < newSelectors.length; i++) {
  2567. length = newSelectors[i].length;
  2568. if (length > 0) {
  2569. paths.push(newSelectors[i]);
  2570. lastSelector = newSelectors[i][length - 1];
  2571. newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);
  2572. }
  2573. }
  2574. return hadParentSelector;
  2575. }
  2576. function deriveSelector(visibilityInfo, deriveFrom) {
  2577. var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);
  2578. newSelector.copyVisibilityInfo(visibilityInfo);
  2579. return newSelector;
  2580. }
  2581. // joinSelector code follows
  2582. var i;
  2583. var newPaths;
  2584. var hadParentSelector;
  2585. newPaths = [];
  2586. hadParentSelector = replaceParentSelector(newPaths, context, selector);
  2587. if (!hadParentSelector) {
  2588. if (context.length > 0) {
  2589. newPaths = [];
  2590. for (i = 0; i < context.length; i++) {
  2591. var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));
  2592. concatenated.push(selector);
  2593. newPaths.push(concatenated);
  2594. }
  2595. }
  2596. else {
  2597. newPaths = [[selector]];
  2598. }
  2599. }
  2600. for (i = 0; i < newPaths.length; i++) {
  2601. paths.push(newPaths[i]);
  2602. }
  2603. };
  2604. return Ruleset;
  2605. }(Node));
  2606. Ruleset.prototype.type = 'Ruleset';
  2607. Ruleset.prototype.isRuleset = true;
  2608. var AtRule = /** @class */ (function (_super) {
  2609. tslib.__extends(AtRule, _super);
  2610. function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {
  2611. var _this = _super.call(this) || this;
  2612. var i;
  2613. _this.name = name;
  2614. _this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value);
  2615. if (rules) {
  2616. if (Array.isArray(rules)) {
  2617. _this.rules = rules;
  2618. }
  2619. else {
  2620. _this.rules = [rules];
  2621. _this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();
  2622. }
  2623. for (i = 0; i < _this.rules.length; i++) {
  2624. _this.rules[i].allowImports = true;
  2625. }
  2626. _this.setParent(_this.rules, _this);
  2627. }
  2628. _this._index = index;
  2629. _this._fileInfo = currentFileInfo;
  2630. _this.debugInfo = debugInfo;
  2631. _this.isRooted = isRooted || false;
  2632. _this.copyVisibilityInfo(visibilityInfo);
  2633. _this.allowRoot = true;
  2634. return _this;
  2635. }
  2636. AtRule.prototype.accept = function (visitor) {
  2637. var value = this.value;
  2638. var rules = this.rules;
  2639. if (rules) {
  2640. this.rules = visitor.visitArray(rules);
  2641. }
  2642. if (value) {
  2643. this.value = visitor.visit(value);
  2644. }
  2645. };
  2646. AtRule.prototype.isRulesetLike = function () {
  2647. return this.rules || !this.isCharset();
  2648. };
  2649. AtRule.prototype.isCharset = function () {
  2650. return '@charset' === this.name;
  2651. };
  2652. AtRule.prototype.genCSS = function (context, output) {
  2653. var value = this.value;
  2654. var rules = this.rules;
  2655. output.add(this.name, this.fileInfo(), this.getIndex());
  2656. if (value) {
  2657. output.add(' ');
  2658. value.genCSS(context, output);
  2659. }
  2660. if (rules) {
  2661. this.outputRuleset(context, output, rules);
  2662. }
  2663. else {
  2664. output.add(';');
  2665. }
  2666. };
  2667. AtRule.prototype.eval = function (context) {
  2668. var mediaPathBackup;
  2669. var mediaBlocksBackup;
  2670. var value = this.value;
  2671. var rules = this.rules;
  2672. // media stored inside other atrule should not bubble over it
  2673. // backpup media bubbling information
  2674. mediaPathBackup = context.mediaPath;
  2675. mediaBlocksBackup = context.mediaBlocks;
  2676. // deleted media bubbling information
  2677. context.mediaPath = [];
  2678. context.mediaBlocks = [];
  2679. if (value) {
  2680. value = value.eval(context);
  2681. }
  2682. if (rules) {
  2683. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2684. rules = [rules[0].eval(context)];
  2685. rules[0].root = true;
  2686. }
  2687. // restore media bubbling information
  2688. context.mediaPath = mediaPathBackup;
  2689. context.mediaBlocks = mediaBlocksBackup;
  2690. return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo());
  2691. };
  2692. AtRule.prototype.variable = function (name) {
  2693. if (this.rules) {
  2694. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2695. return Ruleset.prototype.variable.call(this.rules[0], name);
  2696. }
  2697. };
  2698. AtRule.prototype.find = function () {
  2699. var args = [];
  2700. for (var _i = 0; _i < arguments.length; _i++) {
  2701. args[_i] = arguments[_i];
  2702. }
  2703. if (this.rules) {
  2704. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2705. return Ruleset.prototype.find.apply(this.rules[0], args);
  2706. }
  2707. };
  2708. AtRule.prototype.rulesets = function () {
  2709. if (this.rules) {
  2710. // assuming that there is only one rule at this point - that is how parser constructs the rule
  2711. return Ruleset.prototype.rulesets.apply(this.rules[0]);
  2712. }
  2713. };
  2714. AtRule.prototype.outputRuleset = function (context, output, rules) {
  2715. var ruleCnt = rules.length;
  2716. var i;
  2717. context.tabLevel = (context.tabLevel | 0) + 1;
  2718. // Compressed
  2719. if (context.compress) {
  2720. output.add('{');
  2721. for (i = 0; i < ruleCnt; i++) {
  2722. rules[i].genCSS(context, output);
  2723. }
  2724. output.add('}');
  2725. context.tabLevel--;
  2726. return;
  2727. }
  2728. // Non-compressed
  2729. var tabSetStr = "\n" + Array(context.tabLevel).join(' ');
  2730. var tabRuleStr = tabSetStr + " ";
  2731. if (!ruleCnt) {
  2732. output.add(" {" + tabSetStr + "}");
  2733. }
  2734. else {
  2735. output.add(" {" + tabRuleStr);
  2736. rules[0].genCSS(context, output);
  2737. for (i = 1; i < ruleCnt; i++) {
  2738. output.add(tabRuleStr);
  2739. rules[i].genCSS(context, output);
  2740. }
  2741. output.add(tabSetStr + "}");
  2742. }
  2743. context.tabLevel--;
  2744. };
  2745. return AtRule;
  2746. }(Node));
  2747. AtRule.prototype.type = 'AtRule';
  2748. var DetachedRuleset = /** @class */ (function (_super) {
  2749. tslib.__extends(DetachedRuleset, _super);
  2750. function DetachedRuleset(ruleset, frames) {
  2751. var _this = _super.call(this) || this;
  2752. _this.ruleset = ruleset;
  2753. _this.frames = frames;
  2754. _this.setParent(_this.ruleset, _this);
  2755. return _this;
  2756. }
  2757. DetachedRuleset.prototype.accept = function (visitor) {
  2758. this.ruleset = visitor.visit(this.ruleset);
  2759. };
  2760. DetachedRuleset.prototype.eval = function (context) {
  2761. var frames = this.frames || copyArray(context.frames);
  2762. return new DetachedRuleset(this.ruleset, frames);
  2763. };
  2764. DetachedRuleset.prototype.callEval = function (context) {
  2765. return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);
  2766. };
  2767. return DetachedRuleset;
  2768. }(Node));
  2769. DetachedRuleset.prototype.type = 'DetachedRuleset';
  2770. DetachedRuleset.prototype.evalFirst = true;
  2771. var Unit = /** @class */ (function (_super) {
  2772. tslib.__extends(Unit, _super);
  2773. function Unit(numerator, denominator, backupUnit) {
  2774. var _this = _super.call(this) || this;
  2775. _this.numerator = numerator ? copyArray(numerator).sort() : [];
  2776. _this.denominator = denominator ? copyArray(denominator).sort() : [];
  2777. if (backupUnit) {
  2778. _this.backupUnit = backupUnit;
  2779. }
  2780. else if (numerator && numerator.length) {
  2781. _this.backupUnit = numerator[0];
  2782. }
  2783. return _this;
  2784. }
  2785. Unit.prototype.clone = function () {
  2786. return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit);
  2787. };
  2788. Unit.prototype.genCSS = function (context, output) {
  2789. // Dimension checks the unit is singular and throws an error if in strict math mode.
  2790. var strictUnits = context && context.strictUnits;
  2791. if (this.numerator.length === 1) {
  2792. output.add(this.numerator[0]); // the ideal situation
  2793. }
  2794. else if (!strictUnits && this.backupUnit) {
  2795. output.add(this.backupUnit);
  2796. }
  2797. else if (!strictUnits && this.denominator.length) {
  2798. output.add(this.denominator[0]);
  2799. }
  2800. };
  2801. Unit.prototype.toString = function () {
  2802. var i;
  2803. var returnStr = this.numerator.join('*');
  2804. for (i = 0; i < this.denominator.length; i++) {
  2805. returnStr += "/" + this.denominator[i];
  2806. }
  2807. return returnStr;
  2808. };
  2809. Unit.prototype.compare = function (other) {
  2810. return this.is(other.toString()) ? 0 : undefined;
  2811. };
  2812. Unit.prototype.is = function (unitString) {
  2813. return this.toString().toUpperCase() === unitString.toUpperCase();
  2814. };
  2815. Unit.prototype.isLength = function () {
  2816. return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS());
  2817. };
  2818. Unit.prototype.isEmpty = function () {
  2819. return this.numerator.length === 0 && this.denominator.length === 0;
  2820. };
  2821. Unit.prototype.isSingular = function () {
  2822. return this.numerator.length <= 1 && this.denominator.length === 0;
  2823. };
  2824. Unit.prototype.map = function (callback) {
  2825. var i;
  2826. for (i = 0; i < this.numerator.length; i++) {
  2827. this.numerator[i] = callback(this.numerator[i], false);
  2828. }
  2829. for (i = 0; i < this.denominator.length; i++) {
  2830. this.denominator[i] = callback(this.denominator[i], true);
  2831. }
  2832. };
  2833. Unit.prototype.usedUnits = function () {
  2834. var group;
  2835. var result = {};
  2836. var mapUnit;
  2837. var groupName;
  2838. mapUnit = function (atomicUnit) {
  2839. /* jshint loopfunc:true */
  2840. if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
  2841. result[groupName] = atomicUnit;
  2842. }
  2843. return atomicUnit;
  2844. };
  2845. for (groupName in unitConversions) {
  2846. if (unitConversions.hasOwnProperty(groupName)) {
  2847. group = unitConversions[groupName];
  2848. this.map(mapUnit);
  2849. }
  2850. }
  2851. return result;
  2852. };
  2853. Unit.prototype.cancel = function () {
  2854. var counter = {};
  2855. var atomicUnit;
  2856. var i;
  2857. for (i = 0; i < this.numerator.length; i++) {
  2858. atomicUnit = this.numerator[i];
  2859. counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
  2860. }
  2861. for (i = 0; i < this.denominator.length; i++) {
  2862. atomicUnit = this.denominator[i];
  2863. counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
  2864. }
  2865. this.numerator = [];
  2866. this.denominator = [];
  2867. for (atomicUnit in counter) {
  2868. if (counter.hasOwnProperty(atomicUnit)) {
  2869. var count = counter[atomicUnit];
  2870. if (count > 0) {
  2871. for (i = 0; i < count; i++) {
  2872. this.numerator.push(atomicUnit);
  2873. }
  2874. }
  2875. else if (count < 0) {
  2876. for (i = 0; i < -count; i++) {
  2877. this.denominator.push(atomicUnit);
  2878. }
  2879. }
  2880. }
  2881. }
  2882. this.numerator.sort();
  2883. this.denominator.sort();
  2884. };
  2885. return Unit;
  2886. }(Node));
  2887. Unit.prototype.type = 'Unit';
  2888. //
  2889. // A number with a unit
  2890. //
  2891. var Dimension = /** @class */ (function (_super) {
  2892. tslib.__extends(Dimension, _super);
  2893. function Dimension(value, unit) {
  2894. var _this = _super.call(this) || this;
  2895. _this.value = parseFloat(value);
  2896. if (isNaN(_this.value)) {
  2897. throw new Error('Dimension is not a number.');
  2898. }
  2899. _this.unit = (unit && unit instanceof Unit) ? unit :
  2900. new Unit(unit ? [unit] : undefined);
  2901. _this.setParent(_this.unit, _this);
  2902. return _this;
  2903. }
  2904. Dimension.prototype.accept = function (visitor) {
  2905. this.unit = visitor.visit(this.unit);
  2906. };
  2907. Dimension.prototype.eval = function (context) {
  2908. return this;
  2909. };
  2910. Dimension.prototype.toColor = function () {
  2911. return new Color([this.value, this.value, this.value]);
  2912. };
  2913. Dimension.prototype.genCSS = function (context, output) {
  2914. if ((context && context.strictUnits) && !this.unit.isSingular()) {
  2915. throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString());
  2916. }
  2917. var value = this.fround(context, this.value);
  2918. var strValue = String(value);
  2919. if (value !== 0 && value < 0.000001 && value > -0.000001) {
  2920. // would be output 1e-6 etc.
  2921. strValue = value.toFixed(20).replace(/0+$/, '');
  2922. }
  2923. if (context && context.compress) {
  2924. // Zero values doesn't need a unit
  2925. if (value === 0 && this.unit.isLength()) {
  2926. output.add(strValue);
  2927. return;
  2928. }
  2929. // Float values doesn't need a leading zero
  2930. if (value > 0 && value < 1) {
  2931. strValue = (strValue).substr(1);
  2932. }
  2933. }
  2934. output.add(strValue);
  2935. this.unit.genCSS(context, output);
  2936. };
  2937. // In an operation between two Dimensions,
  2938. // we default to the first Dimension's unit,
  2939. // so `1px + 2` will yield `3px`.
  2940. Dimension.prototype.operate = function (context, op, other) {
  2941. /* jshint noempty:false */
  2942. var value = this._operate(context, op, this.value, other.value);
  2943. var unit = this.unit.clone();
  2944. if (op === '+' || op === '-') {
  2945. if (unit.numerator.length === 0 && unit.denominator.length === 0) {
  2946. unit = other.unit.clone();
  2947. if (this.unit.backupUnit) {
  2948. unit.backupUnit = this.unit.backupUnit;
  2949. }
  2950. }
  2951. else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ;
  2952. else {
  2953. other = other.convertTo(this.unit.usedUnits());
  2954. if (context.strictUnits && other.unit.toString() !== unit.toString()) {
  2955. throw new Error("Incompatible units. Change the units or use the unit function. " +
  2956. ("Bad units: '" + unit.toString() + "' and '" + other.unit.toString() + "'."));
  2957. }
  2958. value = this._operate(context, op, this.value, other.value);
  2959. }
  2960. }
  2961. else if (op === '*') {
  2962. unit.numerator = unit.numerator.concat(other.unit.numerator).sort();
  2963. unit.denominator = unit.denominator.concat(other.unit.denominator).sort();
  2964. unit.cancel();
  2965. }
  2966. else if (op === '/') {
  2967. unit.numerator = unit.numerator.concat(other.unit.denominator).sort();
  2968. unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
  2969. unit.cancel();
  2970. }
  2971. return new Dimension(value, unit);
  2972. };
  2973. Dimension.prototype.compare = function (other) {
  2974. var a;
  2975. var b;
  2976. if (!(other instanceof Dimension)) {
  2977. return undefined;
  2978. }
  2979. if (this.unit.isEmpty() || other.unit.isEmpty()) {
  2980. a = this;
  2981. b = other;
  2982. }
  2983. else {
  2984. a = this.unify();
  2985. b = other.unify();
  2986. if (a.unit.compare(b.unit) !== 0) {
  2987. return undefined;
  2988. }
  2989. }
  2990. return Node.numericCompare(a.value, b.value);
  2991. };
  2992. Dimension.prototype.unify = function () {
  2993. return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });
  2994. };
  2995. Dimension.prototype.convertTo = function (conversions) {
  2996. var value = this.value;
  2997. var unit = this.unit.clone();
  2998. var i;
  2999. var groupName;
  3000. var group;
  3001. var targetUnit;
  3002. var derivedConversions = {};
  3003. var applyUnit;
  3004. if (typeof conversions === 'string') {
  3005. for (i in unitConversions) {
  3006. if (unitConversions[i].hasOwnProperty(conversions)) {
  3007. derivedConversions = {};
  3008. derivedConversions[i] = conversions;
  3009. }
  3010. }
  3011. conversions = derivedConversions;
  3012. }
  3013. applyUnit = function (atomicUnit, denominator) {
  3014. /* jshint loopfunc:true */
  3015. if (group.hasOwnProperty(atomicUnit)) {
  3016. if (denominator) {
  3017. value = value / (group[atomicUnit] / group[targetUnit]);
  3018. }
  3019. else {
  3020. value = value * (group[atomicUnit] / group[targetUnit]);
  3021. }
  3022. return targetUnit;
  3023. }
  3024. return atomicUnit;
  3025. };
  3026. for (groupName in conversions) {
  3027. if (conversions.hasOwnProperty(groupName)) {
  3028. targetUnit = conversions[groupName];
  3029. group = unitConversions[groupName];
  3030. unit.map(applyUnit);
  3031. }
  3032. }
  3033. unit.cancel();
  3034. return new Dimension(value, unit);
  3035. };
  3036. return Dimension;
  3037. }(Node));
  3038. Dimension.prototype.type = 'Dimension';
  3039. var MATH$1 = Math$1;
  3040. var Operation = /** @class */ (function (_super) {
  3041. tslib.__extends(Operation, _super);
  3042. function Operation(op, operands, isSpaced) {
  3043. var _this = _super.call(this) || this;
  3044. _this.op = op.trim();
  3045. _this.operands = operands;
  3046. _this.isSpaced = isSpaced;
  3047. return _this;
  3048. }
  3049. Operation.prototype.accept = function (visitor) {
  3050. this.operands = visitor.visitArray(this.operands);
  3051. };
  3052. Operation.prototype.eval = function (context) {
  3053. var a = this.operands[0].eval(context);
  3054. var b = this.operands[1].eval(context);
  3055. var op;
  3056. if (context.isMathOn(this.op)) {
  3057. op = this.op === './' ? '/' : this.op;
  3058. if (a instanceof Dimension && b instanceof Color) {
  3059. a = a.toColor();
  3060. }
  3061. if (b instanceof Dimension && a instanceof Color) {
  3062. b = b.toColor();
  3063. }
  3064. if (!a.operate) {
  3065. if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) {
  3066. return new Operation(this.op, [a, b], this.isSpaced);
  3067. }
  3068. throw { type: 'Operation',
  3069. message: 'Operation on an invalid type' };
  3070. }
  3071. return a.operate(context, op, b);
  3072. }
  3073. else {
  3074. return new Operation(this.op, [a, b], this.isSpaced);
  3075. }
  3076. };
  3077. Operation.prototype.genCSS = function (context, output) {
  3078. this.operands[0].genCSS(context, output);
  3079. if (this.isSpaced) {
  3080. output.add(' ');
  3081. }
  3082. output.add(this.op);
  3083. if (this.isSpaced) {
  3084. output.add(' ');
  3085. }
  3086. this.operands[1].genCSS(context, output);
  3087. };
  3088. return Operation;
  3089. }(Node));
  3090. Operation.prototype.type = 'Operation';
  3091. var MATH$2 = Math$1;
  3092. var Expression = /** @class */ (function (_super) {
  3093. tslib.__extends(Expression, _super);
  3094. function Expression(value, noSpacing) {
  3095. var _this = _super.call(this) || this;
  3096. _this.value = value;
  3097. _this.noSpacing = noSpacing;
  3098. if (!value) {
  3099. throw new Error('Expression requires an array parameter');
  3100. }
  3101. return _this;
  3102. }
  3103. Expression.prototype.accept = function (visitor) {
  3104. this.value = visitor.visitArray(this.value);
  3105. };
  3106. Expression.prototype.eval = function (context) {
  3107. var returnValue;
  3108. var mathOn = context.isMathOn();
  3109. var inParenthesis = this.parens &&
  3110. (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp);
  3111. var doubleParen = false;
  3112. if (inParenthesis) {
  3113. context.inParenthesis();
  3114. }
  3115. if (this.value.length > 1) {
  3116. returnValue = new Expression(this.value.map(function (e) {
  3117. if (!e.eval) {
  3118. return e;
  3119. }
  3120. return e.eval(context);
  3121. }), this.noSpacing);
  3122. }
  3123. else if (this.value.length === 1) {
  3124. if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {
  3125. doubleParen = true;
  3126. }
  3127. returnValue = this.value[0].eval(context);
  3128. }
  3129. else {
  3130. returnValue = this;
  3131. }
  3132. if (inParenthesis) {
  3133. context.outOfParenthesis();
  3134. }
  3135. if (this.parens && this.parensInOp && !mathOn && !doubleParen
  3136. && (!(returnValue instanceof Dimension))) {
  3137. returnValue = new Paren(returnValue);
  3138. }
  3139. return returnValue;
  3140. };
  3141. Expression.prototype.genCSS = function (context, output) {
  3142. for (var i_1 = 0; i_1 < this.value.length; i_1++) {
  3143. this.value[i_1].genCSS(context, output);
  3144. if (!this.noSpacing && i_1 + 1 < this.value.length) {
  3145. output.add(' ');
  3146. }
  3147. }
  3148. };
  3149. Expression.prototype.throwAwayComments = function () {
  3150. this.value = this.value.filter(function (v) { return !(v instanceof Comment); });
  3151. };
  3152. return Expression;
  3153. }(Node));
  3154. Expression.prototype.type = 'Expression';
  3155. var functionCaller = /** @class */ (function () {
  3156. function functionCaller(name, context, index, currentFileInfo) {
  3157. this.name = name.toLowerCase();
  3158. this.index = index;
  3159. this.context = context;
  3160. this.currentFileInfo = currentFileInfo;
  3161. this.func = context.frames[0].functionRegistry.get(this.name);
  3162. }
  3163. functionCaller.prototype.isValid = function () {
  3164. return Boolean(this.func);
  3165. };
  3166. functionCaller.prototype.call = function (args) {
  3167. // This code is terrible and should be replaced as per this issue...
  3168. // https://github.com/less/less.js/issues/2477
  3169. if (Array.isArray(args)) {
  3170. args = args.filter(function (item) {
  3171. if (item.type === 'Comment') {
  3172. return false;
  3173. }
  3174. return true;
  3175. })
  3176. .map(function (item) {
  3177. if (item.type === 'Expression') {
  3178. var subNodes = item.value.filter(function (item) {
  3179. if (item.type === 'Comment') {
  3180. return false;
  3181. }
  3182. return true;
  3183. });
  3184. if (subNodes.length === 1) {
  3185. return subNodes[0];
  3186. }
  3187. else {
  3188. return new Expression(subNodes);
  3189. }
  3190. }
  3191. return item;
  3192. });
  3193. }
  3194. return this.func.apply(this, args);
  3195. };
  3196. return functionCaller;
  3197. }());
  3198. //
  3199. // A function call node.
  3200. //
  3201. var Call = /** @class */ (function (_super) {
  3202. tslib.__extends(Call, _super);
  3203. function Call(name, args, index, currentFileInfo) {
  3204. var _this = _super.call(this) || this;
  3205. _this.name = name;
  3206. _this.args = args;
  3207. _this.calc = name === 'calc';
  3208. _this._index = index;
  3209. _this._fileInfo = currentFileInfo;
  3210. return _this;
  3211. }
  3212. Call.prototype.accept = function (visitor) {
  3213. if (this.args) {
  3214. this.args = visitor.visitArray(this.args);
  3215. }
  3216. };
  3217. //
  3218. // When evaluating a function call,
  3219. // we either find the function in the functionRegistry,
  3220. // in which case we call it, passing the evaluated arguments,
  3221. // if this returns null or we cannot find the function, we
  3222. // simply print it out as it appeared originally [2].
  3223. //
  3224. // The reason why we evaluate the arguments, is in the case where
  3225. // we try to pass a variable to a function, like: `saturate(@color)`.
  3226. // The function should receive the value, not the variable.
  3227. //
  3228. Call.prototype.eval = function (context) {
  3229. /**
  3230. * Turn off math for calc(), and switch back on for evaluating nested functions
  3231. */
  3232. var currentMathContext = context.mathOn;
  3233. context.mathOn = !this.calc;
  3234. if (this.calc || context.inCalc) {
  3235. context.enterCalc();
  3236. }
  3237. var args = this.args.map(function (a) { return a.eval(context); });
  3238. if (this.calc || context.inCalc) {
  3239. context.exitCalc();
  3240. }
  3241. context.mathOn = currentMathContext;
  3242. var result;
  3243. var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo());
  3244. if (funcCaller.isValid()) {
  3245. try {
  3246. result = funcCaller.call(args);
  3247. }
  3248. catch (e) {
  3249. throw {
  3250. type: e.type || 'Runtime',
  3251. message: "error evaluating function `" + this.name + "`" + (e.message ? ": " + e.message : ''),
  3252. index: this.getIndex(),
  3253. filename: this.fileInfo().filename,
  3254. line: e.lineNumber,
  3255. column: e.columnNumber
  3256. };
  3257. }
  3258. if (result !== null && result !== undefined) {
  3259. // Results that that are not nodes are cast as Anonymous nodes
  3260. // Falsy values or booleans are returned as empty nodes
  3261. if (!(result instanceof Node)) {
  3262. if (!result || result === true) {
  3263. result = new Anonymous(null);
  3264. }
  3265. else {
  3266. result = new Anonymous(result.toString());
  3267. }
  3268. }
  3269. result._index = this._index;
  3270. result._fileInfo = this._fileInfo;
  3271. return result;
  3272. }
  3273. }
  3274. return new Call(this.name, args, this.getIndex(), this.fileInfo());
  3275. };
  3276. Call.prototype.genCSS = function (context, output) {
  3277. output.add(this.name + "(", this.fileInfo(), this.getIndex());
  3278. for (var i_1 = 0; i_1 < this.args.length; i_1++) {
  3279. this.args[i_1].genCSS(context, output);
  3280. if (i_1 + 1 < this.args.length) {
  3281. output.add(', ');
  3282. }
  3283. }
  3284. output.add(')');
  3285. };
  3286. return Call;
  3287. }(Node));
  3288. Call.prototype.type = 'Call';
  3289. var Variable = /** @class */ (function (_super) {
  3290. tslib.__extends(Variable, _super);
  3291. function Variable(name, index, currentFileInfo) {
  3292. var _this = _super.call(this) || this;
  3293. _this.name = name;
  3294. _this._index = index;
  3295. _this._fileInfo = currentFileInfo;
  3296. return _this;
  3297. }
  3298. Variable.prototype.eval = function (context) {
  3299. var variable;
  3300. var name = this.name;
  3301. if (name.indexOf('@@') === 0) {
  3302. name = "@" + new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value;
  3303. }
  3304. if (this.evaluating) {
  3305. throw { type: 'Name',
  3306. message: "Recursive variable definition for " + name,
  3307. filename: this.fileInfo().filename,
  3308. index: this.getIndex() };
  3309. }
  3310. this.evaluating = true;
  3311. variable = this.find(context.frames, function (frame) {
  3312. var v = frame.variable(name);
  3313. if (v) {
  3314. if (v.important) {
  3315. var importantScope = context.importantScope[context.importantScope.length - 1];
  3316. importantScope.important = v.important;
  3317. }
  3318. // If in calc, wrap vars in a function call to cascade evaluate args first
  3319. if (context.inCalc) {
  3320. return (new Call('_SELF', [v.value])).eval(context);
  3321. }
  3322. else {
  3323. return v.value.eval(context);
  3324. }
  3325. }
  3326. });
  3327. if (variable) {
  3328. this.evaluating = false;
  3329. return variable;
  3330. }
  3331. else {
  3332. throw { type: 'Name',
  3333. message: "variable " + name + " is undefined",
  3334. filename: this.fileInfo().filename,
  3335. index: this.getIndex() };
  3336. }
  3337. };
  3338. Variable.prototype.find = function (obj, fun) {
  3339. for (var i_1 = 0, r = void 0; i_1 < obj.length; i_1++) {
  3340. r = fun.call(obj, obj[i_1]);
  3341. if (r) {
  3342. return r;
  3343. }
  3344. }
  3345. return null;
  3346. };
  3347. return Variable;
  3348. }(Node));
  3349. Variable.prototype.type = 'Variable';
  3350. var Property = /** @class */ (function (_super) {
  3351. tslib.__extends(Property, _super);
  3352. function Property(name, index, currentFileInfo) {
  3353. var _this = _super.call(this) || this;
  3354. _this.name = name;
  3355. _this._index = index;
  3356. _this._fileInfo = currentFileInfo;
  3357. return _this;
  3358. }
  3359. Property.prototype.eval = function (context) {
  3360. var property;
  3361. var name = this.name;
  3362. // TODO: shorten this reference
  3363. var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules;
  3364. if (this.evaluating) {
  3365. throw { type: 'Name',
  3366. message: "Recursive property reference for " + name,
  3367. filename: this.fileInfo().filename,
  3368. index: this.getIndex() };
  3369. }
  3370. this.evaluating = true;
  3371. property = this.find(context.frames, function (frame) {
  3372. var v;
  3373. var vArr = frame.property(name);
  3374. if (vArr) {
  3375. for (var i_1 = 0; i_1 < vArr.length; i_1++) {
  3376. v = vArr[i_1];
  3377. vArr[i_1] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable);
  3378. }
  3379. mergeRules(vArr);
  3380. v = vArr[vArr.length - 1];
  3381. if (v.important) {
  3382. var importantScope = context.importantScope[context.importantScope.length - 1];
  3383. importantScope.important = v.important;
  3384. }
  3385. v = v.value.eval(context);
  3386. return v;
  3387. }
  3388. });
  3389. if (property) {
  3390. this.evaluating = false;
  3391. return property;
  3392. }
  3393. else {
  3394. throw { type: 'Name',
  3395. message: "Property '" + name + "' is undefined",
  3396. filename: this.currentFileInfo.filename,
  3397. index: this.index };
  3398. }
  3399. };
  3400. Property.prototype.find = function (obj, fun) {
  3401. for (var i_2 = 0, r = void 0; i_2 < obj.length; i_2++) {
  3402. r = fun.call(obj, obj[i_2]);
  3403. if (r) {
  3404. return r;
  3405. }
  3406. }
  3407. return null;
  3408. };
  3409. return Property;
  3410. }(Node));
  3411. Property.prototype.type = 'Property';
  3412. var Attribute = /** @class */ (function (_super) {
  3413. tslib.__extends(Attribute, _super);
  3414. function Attribute(key, op, value) {
  3415. var _this = _super.call(this) || this;
  3416. _this.key = key;
  3417. _this.op = op;
  3418. _this.value = value;
  3419. return _this;
  3420. }
  3421. Attribute.prototype.eval = function (context) {
  3422. return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);
  3423. };
  3424. Attribute.prototype.genCSS = function (context, output) {
  3425. output.add(this.toCSS(context));
  3426. };
  3427. Attribute.prototype.toCSS = function (context) {
  3428. var value = this.key.toCSS ? this.key.toCSS(context) : this.key;
  3429. if (this.op) {
  3430. value += this.op;
  3431. value += (this.value.toCSS ? this.value.toCSS(context) : this.value);
  3432. }
  3433. return "[" + value + "]";
  3434. };
  3435. return Attribute;
  3436. }(Node));
  3437. Attribute.prototype.type = 'Attribute';
  3438. var Quoted = /** @class */ (function (_super) {
  3439. tslib.__extends(Quoted, _super);
  3440. function Quoted(str, content, escaped, index, currentFileInfo) {
  3441. var _this = _super.call(this) || this;
  3442. _this.escaped = (escaped == null) ? true : escaped;
  3443. _this.value = content || '';
  3444. _this.quote = str.charAt(0);
  3445. _this._index = index;
  3446. _this._fileInfo = currentFileInfo;
  3447. _this.variableRegex = /@\{([\w-]+)\}/g;
  3448. _this.propRegex = /\$\{([\w-]+)\}/g;
  3449. _this.allowRoot = escaped;
  3450. return _this;
  3451. }
  3452. Quoted.prototype.genCSS = function (context, output) {
  3453. if (!this.escaped) {
  3454. output.add(this.quote, this.fileInfo(), this.getIndex());
  3455. }
  3456. output.add(this.value);
  3457. if (!this.escaped) {
  3458. output.add(this.quote);
  3459. }
  3460. };
  3461. Quoted.prototype.containsVariables = function () {
  3462. return this.value.match(this.variableRegex);
  3463. };
  3464. Quoted.prototype.eval = function (context) {
  3465. var that = this;
  3466. var value = this.value;
  3467. var variableReplacement = function (_, name) {
  3468. var v = new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context, true);
  3469. return (v instanceof Quoted) ? v.value : v.toCSS();
  3470. };
  3471. var propertyReplacement = function (_, name) {
  3472. var v = new Property("$" + name, that.getIndex(), that.fileInfo()).eval(context, true);
  3473. return (v instanceof Quoted) ? v.value : v.toCSS();
  3474. };
  3475. function iterativeReplace(value, regexp, replacementFnc) {
  3476. var evaluatedValue = value;
  3477. do {
  3478. value = evaluatedValue.toString();
  3479. evaluatedValue = value.replace(regexp, replacementFnc);
  3480. } while (value !== evaluatedValue);
  3481. return evaluatedValue;
  3482. }
  3483. value = iterativeReplace(value, this.variableRegex, variableReplacement);
  3484. value = iterativeReplace(value, this.propRegex, propertyReplacement);
  3485. return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo());
  3486. };
  3487. Quoted.prototype.compare = function (other) {
  3488. // when comparing quoted strings allow the quote to differ
  3489. if (other.type === 'Quoted' && !this.escaped && !other.escaped) {
  3490. return Node.numericCompare(this.value, other.value);
  3491. }
  3492. else {
  3493. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  3494. }
  3495. };
  3496. return Quoted;
  3497. }(Node));
  3498. Quoted.prototype.type = 'Quoted';
  3499. var URL = /** @class */ (function (_super) {
  3500. tslib.__extends(URL, _super);
  3501. function URL(val, index, currentFileInfo, isEvald) {
  3502. var _this = _super.call(this) || this;
  3503. _this.value = val;
  3504. _this._index = index;
  3505. _this._fileInfo = currentFileInfo;
  3506. _this.isEvald = isEvald;
  3507. return _this;
  3508. }
  3509. URL.prototype.accept = function (visitor) {
  3510. this.value = visitor.visit(this.value);
  3511. };
  3512. URL.prototype.genCSS = function (context, output) {
  3513. output.add('url(');
  3514. this.value.genCSS(context, output);
  3515. output.add(')');
  3516. };
  3517. URL.prototype.eval = function (context) {
  3518. var val = this.value.eval(context);
  3519. var rootpath;
  3520. if (!this.isEvald) {
  3521. // Add the rootpath if the URL requires a rewrite
  3522. rootpath = this.fileInfo() && this.fileInfo().rootpath;
  3523. if (typeof rootpath === 'string' &&
  3524. typeof val.value === 'string' &&
  3525. context.pathRequiresRewrite(val.value)) {
  3526. if (!val.quote) {
  3527. rootpath = escapePath(rootpath);
  3528. }
  3529. val.value = context.rewritePath(val.value, rootpath);
  3530. }
  3531. else {
  3532. val.value = context.normalizePath(val.value);
  3533. }
  3534. // Add url args if enabled
  3535. if (context.urlArgs) {
  3536. if (!val.value.match(/^\s*data:/)) {
  3537. var delimiter = val.value.indexOf('?') === -1 ? '?' : '&';
  3538. var urlArgs = delimiter + context.urlArgs;
  3539. if (val.value.indexOf('#') !== -1) {
  3540. val.value = val.value.replace('#', urlArgs + "#");
  3541. }
  3542. else {
  3543. val.value += urlArgs;
  3544. }
  3545. }
  3546. }
  3547. }
  3548. return new URL(val, this.getIndex(), this.fileInfo(), true);
  3549. };
  3550. return URL;
  3551. }(Node));
  3552. URL.prototype.type = 'Url';
  3553. function escapePath(path) {
  3554. return path.replace(/[\(\)'"\s]/g, function (match) { return "\\" + match; });
  3555. }
  3556. var Media = /** @class */ (function (_super) {
  3557. tslib.__extends(Media, _super);
  3558. function Media(value, features, index, currentFileInfo, visibilityInfo) {
  3559. var _this = _super.call(this) || this;
  3560. _this._index = index;
  3561. _this._fileInfo = currentFileInfo;
  3562. var selectors = (new Selector([], null, null, _this._index, _this._fileInfo)).createEmptySelectors();
  3563. _this.features = new Value(features);
  3564. _this.rules = [new Ruleset(selectors, value)];
  3565. _this.rules[0].allowImports = true;
  3566. _this.copyVisibilityInfo(visibilityInfo);
  3567. _this.allowRoot = true;
  3568. _this.setParent(selectors, _this);
  3569. _this.setParent(_this.features, _this);
  3570. _this.setParent(_this.rules, _this);
  3571. return _this;
  3572. }
  3573. Media.prototype.isRulesetLike = function () {
  3574. return true;
  3575. };
  3576. Media.prototype.accept = function (visitor) {
  3577. if (this.features) {
  3578. this.features = visitor.visit(this.features);
  3579. }
  3580. if (this.rules) {
  3581. this.rules = visitor.visitArray(this.rules);
  3582. }
  3583. };
  3584. Media.prototype.genCSS = function (context, output) {
  3585. output.add('@media ', this._fileInfo, this._index);
  3586. this.features.genCSS(context, output);
  3587. this.outputRuleset(context, output, this.rules);
  3588. };
  3589. Media.prototype.eval = function (context) {
  3590. if (!context.mediaBlocks) {
  3591. context.mediaBlocks = [];
  3592. context.mediaPath = [];
  3593. }
  3594. var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo());
  3595. if (this.debugInfo) {
  3596. this.rules[0].debugInfo = this.debugInfo;
  3597. media.debugInfo = this.debugInfo;
  3598. }
  3599. media.features = this.features.eval(context);
  3600. context.mediaPath.push(media);
  3601. context.mediaBlocks.push(media);
  3602. this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();
  3603. context.frames.unshift(this.rules[0]);
  3604. media.rules = [this.rules[0].eval(context)];
  3605. context.frames.shift();
  3606. context.mediaPath.pop();
  3607. return context.mediaPath.length === 0 ? media.evalTop(context) :
  3608. media.evalNested(context);
  3609. };
  3610. Media.prototype.evalTop = function (context) {
  3611. var result = this;
  3612. // Render all dependent Media blocks.
  3613. if (context.mediaBlocks.length > 1) {
  3614. var selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors();
  3615. result = new Ruleset(selectors, context.mediaBlocks);
  3616. result.multiMedia = true;
  3617. result.copyVisibilityInfo(this.visibilityInfo());
  3618. this.setParent(result, this);
  3619. }
  3620. delete context.mediaBlocks;
  3621. delete context.mediaPath;
  3622. return result;
  3623. };
  3624. Media.prototype.evalNested = function (context) {
  3625. var i;
  3626. var value;
  3627. var path = context.mediaPath.concat([this]);
  3628. // Extract the media-query conditions separated with `,` (OR).
  3629. for (i = 0; i < path.length; i++) {
  3630. value = path[i].features instanceof Value ?
  3631. path[i].features.value : path[i].features;
  3632. path[i] = Array.isArray(value) ? value : [value];
  3633. }
  3634. // Trace all permutations to generate the resulting media-query.
  3635. //
  3636. // (a, b and c) with nested (d, e) ->
  3637. // a and d
  3638. // a and e
  3639. // b and c and d
  3640. // b and c and e
  3641. this.features = new Value(this.permute(path).map(function (path) {
  3642. path = path.map(function (fragment) { return fragment.toCSS ? fragment : new Anonymous(fragment); });
  3643. for (i = path.length - 1; i > 0; i--) {
  3644. path.splice(i, 0, new Anonymous('and'));
  3645. }
  3646. return new Expression(path);
  3647. }));
  3648. this.setParent(this.features, this);
  3649. // Fake a tree-node that doesn't output anything.
  3650. return new Ruleset([], []);
  3651. };
  3652. Media.prototype.permute = function (arr) {
  3653. if (arr.length === 0) {
  3654. return [];
  3655. }
  3656. else if (arr.length === 1) {
  3657. return arr[0];
  3658. }
  3659. else {
  3660. var result = [];
  3661. var rest = this.permute(arr.slice(1));
  3662. for (var i_1 = 0; i_1 < rest.length; i_1++) {
  3663. for (var j = 0; j < arr[0].length; j++) {
  3664. result.push([arr[0][j]].concat(rest[i_1]));
  3665. }
  3666. }
  3667. return result;
  3668. }
  3669. };
  3670. Media.prototype.bubbleSelectors = function (selectors) {
  3671. if (!selectors) {
  3672. return;
  3673. }
  3674. this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])];
  3675. this.setParent(this.rules, this);
  3676. };
  3677. return Media;
  3678. }(AtRule));
  3679. Media.prototype.type = 'Media';
  3680. //
  3681. // CSS @import node
  3682. //
  3683. // The general strategy here is that we don't want to wait
  3684. // for the parsing to be completed, before we start importing
  3685. // the file. That's because in the context of a browser,
  3686. // most of the time will be spent waiting for the server to respond.
  3687. //
  3688. // On creation, we push the import path to our import queue, though
  3689. // `import,push`, we also pass it a callback, which it'll call once
  3690. // the file has been fetched, and parsed.
  3691. //
  3692. var Import = /** @class */ (function (_super) {
  3693. tslib.__extends(Import, _super);
  3694. function Import(path, features, options, index, currentFileInfo, visibilityInfo) {
  3695. var _this = _super.call(this) || this;
  3696. _this.options = options;
  3697. _this._index = index;
  3698. _this._fileInfo = currentFileInfo;
  3699. _this.path = path;
  3700. _this.features = features;
  3701. _this.allowRoot = true;
  3702. if (_this.options.less !== undefined || _this.options.inline) {
  3703. _this.css = !_this.options.less || _this.options.inline;
  3704. }
  3705. else {
  3706. var pathValue = _this.getPath();
  3707. if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) {
  3708. _this.css = true;
  3709. }
  3710. }
  3711. _this.copyVisibilityInfo(visibilityInfo);
  3712. _this.setParent(_this.features, _this);
  3713. _this.setParent(_this.path, _this);
  3714. return _this;
  3715. }
  3716. Import.prototype.accept = function (visitor) {
  3717. if (this.features) {
  3718. this.features = visitor.visit(this.features);
  3719. }
  3720. this.path = visitor.visit(this.path);
  3721. if (!this.options.isPlugin && !this.options.inline && this.root) {
  3722. this.root = visitor.visit(this.root);
  3723. }
  3724. };
  3725. Import.prototype.genCSS = function (context, output) {
  3726. if (this.css && this.path._fileInfo.reference === undefined) {
  3727. output.add('@import ', this._fileInfo, this._index);
  3728. this.path.genCSS(context, output);
  3729. if (this.features) {
  3730. output.add(' ');
  3731. this.features.genCSS(context, output);
  3732. }
  3733. output.add(';');
  3734. }
  3735. };
  3736. Import.prototype.getPath = function () {
  3737. return (this.path instanceof URL) ?
  3738. this.path.value.value : this.path.value;
  3739. };
  3740. Import.prototype.isVariableImport = function () {
  3741. var path = this.path;
  3742. if (path instanceof URL) {
  3743. path = path.value;
  3744. }
  3745. if (path instanceof Quoted) {
  3746. return path.containsVariables();
  3747. }
  3748. return true;
  3749. };
  3750. Import.prototype.evalForImport = function (context) {
  3751. var path = this.path;
  3752. if (path instanceof URL) {
  3753. path = path.value;
  3754. }
  3755. return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo());
  3756. };
  3757. Import.prototype.evalPath = function (context) {
  3758. var path = this.path.eval(context);
  3759. var fileInfo = this._fileInfo;
  3760. if (!(path instanceof URL)) {
  3761. // Add the rootpath if the URL requires a rewrite
  3762. var pathValue = path.value;
  3763. if (fileInfo &&
  3764. pathValue &&
  3765. context.pathRequiresRewrite(pathValue)) {
  3766. path.value = context.rewritePath(pathValue, fileInfo.rootpath);
  3767. }
  3768. else {
  3769. path.value = context.normalizePath(path.value);
  3770. }
  3771. }
  3772. return path;
  3773. };
  3774. Import.prototype.eval = function (context) {
  3775. var result = this.doEval(context);
  3776. if (this.options.reference || this.blocksVisibility()) {
  3777. if (result.length || result.length === 0) {
  3778. result.forEach(function (node) {
  3779. node.addVisibilityBlock();
  3780. });
  3781. }
  3782. else {
  3783. result.addVisibilityBlock();
  3784. }
  3785. }
  3786. return result;
  3787. };
  3788. Import.prototype.doEval = function (context) {
  3789. var ruleset;
  3790. var registry;
  3791. var features = this.features && this.features.eval(context);
  3792. if (this.options.isPlugin) {
  3793. if (this.root && this.root.eval) {
  3794. try {
  3795. this.root.eval(context);
  3796. }
  3797. catch (e) {
  3798. e.message = 'Plugin error during evaluation';
  3799. throw new LessError(e, this.root.imports, this.root.filename);
  3800. }
  3801. }
  3802. registry = context.frames[0] && context.frames[0].functionRegistry;
  3803. if (registry && this.root && this.root.functions) {
  3804. registry.addMultiple(this.root.functions);
  3805. }
  3806. return [];
  3807. }
  3808. if (this.skip) {
  3809. if (typeof this.skip === 'function') {
  3810. this.skip = this.skip();
  3811. }
  3812. if (this.skip) {
  3813. return [];
  3814. }
  3815. }
  3816. if (this.options.inline) {
  3817. var contents = new Anonymous(this.root, 0, {
  3818. filename: this.importedFilename,
  3819. reference: this.path._fileInfo && this.path._fileInfo.reference
  3820. }, true, true);
  3821. return this.features ? new Media([contents], this.features.value) : [contents];
  3822. }
  3823. else if (this.css) {
  3824. var newImport = new Import(this.evalPath(context), features, this.options, this._index);
  3825. if (!newImport.css && this.error) {
  3826. throw this.error;
  3827. }
  3828. return newImport;
  3829. }
  3830. else {
  3831. ruleset = new Ruleset(null, copyArray(this.root.rules));
  3832. ruleset.evalImports(context);
  3833. return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;
  3834. }
  3835. };
  3836. return Import;
  3837. }(Node));
  3838. Import.prototype.type = 'Import';
  3839. var JsEvalNode = /** @class */ (function (_super) {
  3840. tslib.__extends(JsEvalNode, _super);
  3841. function JsEvalNode() {
  3842. return _super !== null && _super.apply(this, arguments) || this;
  3843. }
  3844. JsEvalNode.prototype.evaluateJavaScript = function (expression, context) {
  3845. var result;
  3846. var that = this;
  3847. var evalContext = {};
  3848. if (!context.javascriptEnabled) {
  3849. throw { message: 'Inline JavaScript is not enabled. Is it set in your options?',
  3850. filename: this.fileInfo().filename,
  3851. index: this.getIndex() };
  3852. }
  3853. expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { return that.jsify(new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context)); });
  3854. try {
  3855. expression = new Function("return (" + expression + ")");
  3856. }
  3857. catch (e) {
  3858. throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`",
  3859. filename: this.fileInfo().filename,
  3860. index: this.getIndex() };
  3861. }
  3862. var variables = context.frames[0].variables();
  3863. for (var k in variables) {
  3864. if (variables.hasOwnProperty(k)) {
  3865. /* jshint loopfunc:true */
  3866. evalContext[k.slice(1)] = {
  3867. value: variables[k].value,
  3868. toJS: function () {
  3869. return this.value.eval(context).toCSS();
  3870. }
  3871. };
  3872. }
  3873. }
  3874. try {
  3875. result = expression.call(evalContext);
  3876. }
  3877. catch (e) {
  3878. throw { message: "JavaScript evaluation error: '" + e.name + ": " + e.message.replace(/["]/g, '\'') + "'",
  3879. filename: this.fileInfo().filename,
  3880. index: this.getIndex() };
  3881. }
  3882. return result;
  3883. };
  3884. JsEvalNode.prototype.jsify = function (obj) {
  3885. if (Array.isArray(obj.value) && (obj.value.length > 1)) {
  3886. return "[" + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + "]";
  3887. }
  3888. else {
  3889. return obj.toCSS();
  3890. }
  3891. };
  3892. return JsEvalNode;
  3893. }(Node));
  3894. var JavaScript = /** @class */ (function (_super) {
  3895. tslib.__extends(JavaScript, _super);
  3896. function JavaScript(string, escaped, index, currentFileInfo) {
  3897. var _this = _super.call(this) || this;
  3898. _this.escaped = escaped;
  3899. _this.expression = string;
  3900. _this._index = index;
  3901. _this._fileInfo = currentFileInfo;
  3902. return _this;
  3903. }
  3904. JavaScript.prototype.eval = function (context) {
  3905. var result = this.evaluateJavaScript(this.expression, context);
  3906. var type = typeof result;
  3907. if (type === 'number' && !isNaN(result)) {
  3908. return new Dimension(result);
  3909. }
  3910. else if (type === 'string') {
  3911. return new Quoted("\"" + result + "\"", result, this.escaped, this._index);
  3912. }
  3913. else if (Array.isArray(result)) {
  3914. return new Anonymous(result.join(', '));
  3915. }
  3916. else {
  3917. return new Anonymous(result);
  3918. }
  3919. };
  3920. return JavaScript;
  3921. }(JsEvalNode));
  3922. JavaScript.prototype.type = 'JavaScript';
  3923. var Assignment = /** @class */ (function (_super) {
  3924. tslib.__extends(Assignment, _super);
  3925. function Assignment(key, val) {
  3926. var _this = _super.call(this) || this;
  3927. _this.key = key;
  3928. _this.value = val;
  3929. return _this;
  3930. }
  3931. Assignment.prototype.accept = function (visitor) {
  3932. this.value = visitor.visit(this.value);
  3933. };
  3934. Assignment.prototype.eval = function (context) {
  3935. if (this.value.eval) {
  3936. return new Assignment(this.key, this.value.eval(context));
  3937. }
  3938. return this;
  3939. };
  3940. Assignment.prototype.genCSS = function (context, output) {
  3941. output.add(this.key + "=");
  3942. if (this.value.genCSS) {
  3943. this.value.genCSS(context, output);
  3944. }
  3945. else {
  3946. output.add(this.value);
  3947. }
  3948. };
  3949. return Assignment;
  3950. }(Node));
  3951. Assignment.prototype.type = 'Assignment';
  3952. var Condition = /** @class */ (function (_super) {
  3953. tslib.__extends(Condition, _super);
  3954. function Condition(op, l, r, i, negate) {
  3955. var _this = _super.call(this) || this;
  3956. _this.op = op.trim();
  3957. _this.lvalue = l;
  3958. _this.rvalue = r;
  3959. _this._index = i;
  3960. _this.negate = negate;
  3961. return _this;
  3962. }
  3963. Condition.prototype.accept = function (visitor) {
  3964. this.lvalue = visitor.visit(this.lvalue);
  3965. this.rvalue = visitor.visit(this.rvalue);
  3966. };
  3967. Condition.prototype.eval = function (context) {
  3968. var result = (function (op, a, b) {
  3969. switch (op) {
  3970. case 'and': return a && b;
  3971. case 'or': return a || b;
  3972. default:
  3973. switch (Node.compare(a, b)) {
  3974. case -1:
  3975. return op === '<' || op === '=<' || op === '<=';
  3976. case 0:
  3977. return op === '=' || op === '>=' || op === '=<' || op === '<=';
  3978. case 1:
  3979. return op === '>' || op === '>=';
  3980. default:
  3981. return false;
  3982. }
  3983. }
  3984. })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));
  3985. return this.negate ? !result : result;
  3986. };
  3987. return Condition;
  3988. }(Node));
  3989. Condition.prototype.type = 'Condition';
  3990. var UnicodeDescriptor = /** @class */ (function (_super) {
  3991. tslib.__extends(UnicodeDescriptor, _super);
  3992. function UnicodeDescriptor(value) {
  3993. var _this = _super.call(this) || this;
  3994. _this.value = value;
  3995. return _this;
  3996. }
  3997. return UnicodeDescriptor;
  3998. }(Node));
  3999. UnicodeDescriptor.prototype.type = 'UnicodeDescriptor';
  4000. var Negative = /** @class */ (function (_super) {
  4001. tslib.__extends(Negative, _super);
  4002. function Negative(node) {
  4003. var _this = _super.call(this) || this;
  4004. _this.value = node;
  4005. return _this;
  4006. }
  4007. Negative.prototype.genCSS = function (context, output) {
  4008. output.add('-');
  4009. this.value.genCSS(context, output);
  4010. };
  4011. Negative.prototype.eval = function (context) {
  4012. if (context.isMathOn()) {
  4013. return (new Operation('*', [new Dimension(-1), this.value])).eval(context);
  4014. }
  4015. return new Negative(this.value.eval(context));
  4016. };
  4017. return Negative;
  4018. }(Node));
  4019. Negative.prototype.type = 'Negative';
  4020. var Extend = /** @class */ (function (_super) {
  4021. tslib.__extends(Extend, _super);
  4022. function Extend(selector, option, index, currentFileInfo, visibilityInfo) {
  4023. var _this = _super.call(this) || this;
  4024. _this.selector = selector;
  4025. _this.option = option;
  4026. _this.object_id = Extend.next_id++;
  4027. _this.parent_ids = [_this.object_id];
  4028. _this._index = index;
  4029. _this._fileInfo = currentFileInfo;
  4030. _this.copyVisibilityInfo(visibilityInfo);
  4031. _this.allowRoot = true;
  4032. switch (option) {
  4033. case 'all':
  4034. _this.allowBefore = true;
  4035. _this.allowAfter = true;
  4036. break;
  4037. default:
  4038. _this.allowBefore = false;
  4039. _this.allowAfter = false;
  4040. break;
  4041. }
  4042. _this.setParent(_this.selector, _this);
  4043. return _this;
  4044. }
  4045. Extend.prototype.accept = function (visitor) {
  4046. this.selector = visitor.visit(this.selector);
  4047. };
  4048. Extend.prototype.eval = function (context) {
  4049. return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  4050. };
  4051. Extend.prototype.clone = function (context) {
  4052. return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());
  4053. };
  4054. // it concatenates (joins) all selectors in selector array
  4055. Extend.prototype.findSelfSelectors = function (selectors) {
  4056. var selfElements = [];
  4057. var i;
  4058. var selectorElements;
  4059. for (i = 0; i < selectors.length; i++) {
  4060. selectorElements = selectors[i].elements;
  4061. // duplicate the logic in genCSS function inside the selector node.
  4062. // future TODO - move both logics into the selector joiner visitor
  4063. if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {
  4064. selectorElements[0].combinator.value = ' ';
  4065. }
  4066. selfElements = selfElements.concat(selectors[i].elements);
  4067. }
  4068. this.selfSelectors = [new Selector(selfElements)];
  4069. this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
  4070. };
  4071. return Extend;
  4072. }(Node));
  4073. Extend.next_id = 0;
  4074. Extend.prototype.type = 'Extend';
  4075. var VariableCall = /** @class */ (function (_super) {
  4076. tslib.__extends(VariableCall, _super);
  4077. function VariableCall(variable, index, currentFileInfo) {
  4078. var _this = _super.call(this) || this;
  4079. _this.variable = variable;
  4080. _this._index = index;
  4081. _this._fileInfo = currentFileInfo;
  4082. _this.allowRoot = true;
  4083. return _this;
  4084. }
  4085. VariableCall.prototype.eval = function (context) {
  4086. var rules;
  4087. var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context);
  4088. var error = new LessError({ message: "Could not evaluate variable call " + this.variable });
  4089. if (!detachedRuleset.ruleset) {
  4090. if (detachedRuleset.rules) {
  4091. rules = detachedRuleset;
  4092. }
  4093. else if (Array.isArray(detachedRuleset)) {
  4094. rules = new Ruleset('', detachedRuleset);
  4095. }
  4096. else if (Array.isArray(detachedRuleset.value)) {
  4097. rules = new Ruleset('', detachedRuleset.value);
  4098. }
  4099. else {
  4100. throw error;
  4101. }
  4102. detachedRuleset = new DetachedRuleset(rules);
  4103. }
  4104. if (detachedRuleset.ruleset) {
  4105. return detachedRuleset.callEval(context);
  4106. }
  4107. throw error;
  4108. };
  4109. return VariableCall;
  4110. }(Node));
  4111. VariableCall.prototype.type = 'VariableCall';
  4112. var NamespaceValue = /** @class */ (function (_super) {
  4113. tslib.__extends(NamespaceValue, _super);
  4114. function NamespaceValue(ruleCall, lookups, index, fileInfo) {
  4115. var _this = _super.call(this) || this;
  4116. _this.value = ruleCall;
  4117. _this.lookups = lookups;
  4118. _this._index = index;
  4119. _this._fileInfo = fileInfo;
  4120. return _this;
  4121. }
  4122. NamespaceValue.prototype.eval = function (context) {
  4123. var i;
  4124. var name;
  4125. var rules = this.value.eval(context);
  4126. for (i = 0; i < this.lookups.length; i++) {
  4127. name = this.lookups[i];
  4128. /**
  4129. * Eval'd DRs return rulesets.
  4130. * Eval'd mixins return rules, so let's make a ruleset if we need it.
  4131. * We need to do this because of late parsing of values
  4132. */
  4133. if (Array.isArray(rules)) {
  4134. rules = new Ruleset([new Selector()], rules);
  4135. }
  4136. if (name === '') {
  4137. rules = rules.lastDeclaration();
  4138. }
  4139. else if (name.charAt(0) === '@') {
  4140. if (name.charAt(1) === '@') {
  4141. name = "@" + new Variable(name.substr(1)).eval(context).value;
  4142. }
  4143. if (rules.variables) {
  4144. rules = rules.variable(name);
  4145. }
  4146. if (!rules) {
  4147. throw { type: 'Name',
  4148. message: "variable " + name + " not found",
  4149. filename: this.fileInfo().filename,
  4150. index: this.getIndex() };
  4151. }
  4152. }
  4153. else {
  4154. if (name.substring(0, 2) === '$@') {
  4155. name = "$" + new Variable(name.substr(1)).eval(context).value;
  4156. }
  4157. else {
  4158. name = name.charAt(0) === '$' ? name : "$" + name;
  4159. }
  4160. if (rules.properties) {
  4161. rules = rules.property(name);
  4162. }
  4163. if (!rules) {
  4164. throw { type: 'Name',
  4165. message: "property \"" + name.substr(1) + "\" not found",
  4166. filename: this.fileInfo().filename,
  4167. index: this.getIndex() };
  4168. }
  4169. // Properties are an array of values, since a ruleset can have multiple props.
  4170. // We pick the last one (the "cascaded" value)
  4171. rules = rules[rules.length - 1];
  4172. }
  4173. if (rules.value) {
  4174. rules = rules.eval(context).value;
  4175. }
  4176. if (rules.ruleset) {
  4177. rules = rules.ruleset.eval(context);
  4178. }
  4179. }
  4180. return rules;
  4181. };
  4182. return NamespaceValue;
  4183. }(Node));
  4184. NamespaceValue.prototype.type = 'NamespaceValue';
  4185. var Definition = /** @class */ (function (_super) {
  4186. tslib.__extends(Definition, _super);
  4187. function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) {
  4188. var _this = _super.call(this) || this;
  4189. _this.name = name || 'anonymous mixin';
  4190. _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])];
  4191. _this.params = params;
  4192. _this.condition = condition;
  4193. _this.variadic = variadic;
  4194. _this.arity = params.length;
  4195. _this.rules = rules;
  4196. _this._lookups = {};
  4197. var optionalParameters = [];
  4198. _this.required = params.reduce(function (count, p) {
  4199. if (!p.name || (p.name && !p.value)) {
  4200. return count + 1;
  4201. }
  4202. else {
  4203. optionalParameters.push(p.name);
  4204. return count;
  4205. }
  4206. }, 0);
  4207. _this.optionalParameters = optionalParameters;
  4208. _this.frames = frames;
  4209. _this.copyVisibilityInfo(visibilityInfo);
  4210. _this.allowRoot = true;
  4211. return _this;
  4212. }
  4213. Definition.prototype.accept = function (visitor) {
  4214. if (this.params && this.params.length) {
  4215. this.params = visitor.visitArray(this.params);
  4216. }
  4217. this.rules = visitor.visitArray(this.rules);
  4218. if (this.condition) {
  4219. this.condition = visitor.visit(this.condition);
  4220. }
  4221. };
  4222. Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) {
  4223. /* jshint boss:true */
  4224. var frame = new Ruleset(null, null);
  4225. var varargs;
  4226. var arg;
  4227. var params = copyArray(this.params);
  4228. var i;
  4229. var j;
  4230. var val;
  4231. var name;
  4232. var isNamedFound;
  4233. var argIndex;
  4234. var argsLength = 0;
  4235. if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {
  4236. frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();
  4237. }
  4238. mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));
  4239. if (args) {
  4240. args = copyArray(args);
  4241. argsLength = args.length;
  4242. for (i = 0; i < argsLength; i++) {
  4243. arg = args[i];
  4244. if (name = (arg && arg.name)) {
  4245. isNamedFound = false;
  4246. for (j = 0; j < params.length; j++) {
  4247. if (!evaldArguments[j] && name === params[j].name) {
  4248. evaldArguments[j] = arg.value.eval(context);
  4249. frame.prependRule(new Declaration(name, arg.value.eval(context)));
  4250. isNamedFound = true;
  4251. break;
  4252. }
  4253. }
  4254. if (isNamedFound) {
  4255. args.splice(i, 1);
  4256. i--;
  4257. continue;
  4258. }
  4259. else {
  4260. throw { type: 'Runtime', message: "Named argument for " + this.name + " " + args[i].name + " not found" };
  4261. }
  4262. }
  4263. }
  4264. }
  4265. argIndex = 0;
  4266. for (i = 0; i < params.length; i++) {
  4267. if (evaldArguments[i]) {
  4268. continue;
  4269. }
  4270. arg = args && args[argIndex];
  4271. if (name = params[i].name) {
  4272. if (params[i].variadic) {
  4273. varargs = [];
  4274. for (j = argIndex; j < argsLength; j++) {
  4275. varargs.push(args[j].value.eval(context));
  4276. }
  4277. frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));
  4278. }
  4279. else {
  4280. val = arg && arg.value;
  4281. if (val) {
  4282. // This was a mixin call, pass in a detached ruleset of it's eval'd rules
  4283. if (Array.isArray(val)) {
  4284. val = new DetachedRuleset(new Ruleset('', val));
  4285. }
  4286. else {
  4287. val = val.eval(context);
  4288. }
  4289. }
  4290. else if (params[i].value) {
  4291. val = params[i].value.eval(mixinEnv);
  4292. frame.resetCache();
  4293. }
  4294. else {
  4295. throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + " (" + argsLength + " for " + this.arity + ")" };
  4296. }
  4297. frame.prependRule(new Declaration(name, val));
  4298. evaldArguments[i] = val;
  4299. }
  4300. }
  4301. if (params[i].variadic && args) {
  4302. for (j = argIndex; j < argsLength; j++) {
  4303. evaldArguments[j] = args[j].value.eval(context);
  4304. }
  4305. }
  4306. argIndex++;
  4307. }
  4308. return frame;
  4309. };
  4310. Definition.prototype.makeImportant = function () {
  4311. var rules = !this.rules ? this.rules : this.rules.map(function (r) {
  4312. if (r.makeImportant) {
  4313. return r.makeImportant(true);
  4314. }
  4315. else {
  4316. return r;
  4317. }
  4318. });
  4319. var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
  4320. return result;
  4321. };
  4322. Definition.prototype.eval = function (context) {
  4323. return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames));
  4324. };
  4325. Definition.prototype.evalCall = function (context, args, important) {
  4326. var _arguments = [];
  4327. var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames;
  4328. var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);
  4329. var rules;
  4330. var ruleset;
  4331. frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));
  4332. rules = copyArray(this.rules);
  4333. ruleset = new Ruleset(null, rules);
  4334. ruleset.originalRuleset = this;
  4335. ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));
  4336. if (important) {
  4337. ruleset = ruleset.makeImportant();
  4338. }
  4339. return ruleset;
  4340. };
  4341. Definition.prototype.matchCondition = function (args, context) {
  4342. if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, /* the parameter variables */ new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]
  4343. .concat(this.frames || []) // the parent namespace/mixin frames
  4344. .concat(context.frames)))) { // the current environment frames
  4345. return false;
  4346. }
  4347. return true;
  4348. };
  4349. Definition.prototype.matchArgs = function (args, context) {
  4350. var allArgsCnt = (args && args.length) || 0;
  4351. var len;
  4352. var optionalParameters = this.optionalParameters;
  4353. var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) {
  4354. if (optionalParameters.indexOf(p.name) < 0) {
  4355. return count + 1;
  4356. }
  4357. else {
  4358. return count;
  4359. }
  4360. }, 0);
  4361. if (!this.variadic) {
  4362. if (requiredArgsCnt < this.required) {
  4363. return false;
  4364. }
  4365. if (allArgsCnt > this.params.length) {
  4366. return false;
  4367. }
  4368. }
  4369. else {
  4370. if (requiredArgsCnt < (this.required - 1)) {
  4371. return false;
  4372. }
  4373. }
  4374. // check patterns
  4375. len = Math.min(requiredArgsCnt, this.arity);
  4376. for (var i_1 = 0; i_1 < len; i_1++) {
  4377. if (!this.params[i_1].name && !this.params[i_1].variadic) {
  4378. if (args[i_1].value.eval(context).toCSS() != this.params[i_1].value.eval(context).toCSS()) {
  4379. return false;
  4380. }
  4381. }
  4382. }
  4383. return true;
  4384. };
  4385. return Definition;
  4386. }(Ruleset));
  4387. Definition.prototype.type = 'MixinDefinition';
  4388. Definition.prototype.evalFirst = true;
  4389. var MixinCall = /** @class */ (function (_super) {
  4390. tslib.__extends(MixinCall, _super);
  4391. function MixinCall(elements, args, index, currentFileInfo, important) {
  4392. var _this = _super.call(this) || this;
  4393. _this.selector = new Selector(elements);
  4394. _this.arguments = args || [];
  4395. _this._index = index;
  4396. _this._fileInfo = currentFileInfo;
  4397. _this.important = important;
  4398. _this.allowRoot = true;
  4399. _this.setParent(_this.selector, _this);
  4400. return _this;
  4401. }
  4402. MixinCall.prototype.accept = function (visitor) {
  4403. if (this.selector) {
  4404. this.selector = visitor.visit(this.selector);
  4405. }
  4406. if (this.arguments.length) {
  4407. this.arguments = visitor.visitArray(this.arguments);
  4408. }
  4409. };
  4410. MixinCall.prototype.eval = function (context) {
  4411. var mixins;
  4412. var mixin;
  4413. var mixinPath;
  4414. var args = [];
  4415. var arg;
  4416. var argValue;
  4417. var rules = [];
  4418. var match = false;
  4419. var i;
  4420. var m;
  4421. var f;
  4422. var isRecursive;
  4423. var isOneFound;
  4424. var candidates = [];
  4425. var candidate;
  4426. var conditionResult = [];
  4427. var defaultResult;
  4428. var defFalseEitherCase = -1;
  4429. var defNone = 0;
  4430. var defTrue = 1;
  4431. var defFalse = 2;
  4432. var count;
  4433. var originalRuleset;
  4434. var noArgumentsFilter;
  4435. this.selector = this.selector.eval(context);
  4436. function calcDefGroup(mixin, mixinPath) {
  4437. var f;
  4438. var p;
  4439. var namespace;
  4440. for (f = 0; f < 2; f++) {
  4441. conditionResult[f] = true;
  4442. defaultFunc.value(f);
  4443. for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
  4444. namespace = mixinPath[p];
  4445. if (namespace.matchCondition) {
  4446. conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
  4447. }
  4448. }
  4449. if (mixin.matchCondition) {
  4450. conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);
  4451. }
  4452. }
  4453. if (conditionResult[0] || conditionResult[1]) {
  4454. if (conditionResult[0] != conditionResult[1]) {
  4455. return conditionResult[1] ?
  4456. defTrue : defFalse;
  4457. }
  4458. return defNone;
  4459. }
  4460. return defFalseEitherCase;
  4461. }
  4462. for (i = 0; i < this.arguments.length; i++) {
  4463. arg = this.arguments[i];
  4464. argValue = arg.value.eval(context);
  4465. if (arg.expand && Array.isArray(argValue.value)) {
  4466. argValue = argValue.value;
  4467. for (m = 0; m < argValue.length; m++) {
  4468. args.push({ value: argValue[m] });
  4469. }
  4470. }
  4471. else {
  4472. args.push({ name: arg.name, value: argValue });
  4473. }
  4474. }
  4475. noArgumentsFilter = function (rule) { return rule.matchArgs(null, context); };
  4476. for (i = 0; i < context.frames.length; i++) {
  4477. if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {
  4478. isOneFound = true;
  4479. // To make `default()` function independent of definition order we have two "subpasses" here.
  4480. // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
  4481. // and build candidate list with corresponding flags. Then, when we know all possible matches,
  4482. // we make a final decision.
  4483. for (m = 0; m < mixins.length; m++) {
  4484. mixin = mixins[m].rule;
  4485. mixinPath = mixins[m].path;
  4486. isRecursive = false;
  4487. for (f = 0; f < context.frames.length; f++) {
  4488. if ((!(mixin instanceof Definition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {
  4489. isRecursive = true;
  4490. break;
  4491. }
  4492. }
  4493. if (isRecursive) {
  4494. continue;
  4495. }
  4496. if (mixin.matchArgs(args, context)) {
  4497. candidate = { mixin: mixin, group: calcDefGroup(mixin, mixinPath) };
  4498. if (candidate.group !== defFalseEitherCase) {
  4499. candidates.push(candidate);
  4500. }
  4501. match = true;
  4502. }
  4503. }
  4504. defaultFunc.reset();
  4505. count = [0, 0, 0];
  4506. for (m = 0; m < candidates.length; m++) {
  4507. count[candidates[m].group]++;
  4508. }
  4509. if (count[defNone] > 0) {
  4510. defaultResult = defFalse;
  4511. }
  4512. else {
  4513. defaultResult = defTrue;
  4514. if ((count[defTrue] + count[defFalse]) > 1) {
  4515. throw { type: 'Runtime',
  4516. message: "Ambiguous use of `default()` found when matching for `" + this.format(args) + "`",
  4517. index: this.getIndex(), filename: this.fileInfo().filename };
  4518. }
  4519. }
  4520. for (m = 0; m < candidates.length; m++) {
  4521. candidate = candidates[m].group;
  4522. if ((candidate === defNone) || (candidate === defaultResult)) {
  4523. try {
  4524. mixin = candidates[m].mixin;
  4525. if (!(mixin instanceof Definition)) {
  4526. originalRuleset = mixin.originalRuleset || mixin;
  4527. mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
  4528. mixin.originalRuleset = originalRuleset;
  4529. }
  4530. var newRules = mixin.evalCall(context, args, this.important).rules;
  4531. this._setVisibilityToReplacement(newRules);
  4532. Array.prototype.push.apply(rules, newRules);
  4533. }
  4534. catch (e) {
  4535. throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack };
  4536. }
  4537. }
  4538. }
  4539. if (match) {
  4540. return rules;
  4541. }
  4542. }
  4543. }
  4544. if (isOneFound) {
  4545. throw { type: 'Runtime',
  4546. message: "No matching definition was found for `" + this.format(args) + "`",
  4547. index: this.getIndex(), filename: this.fileInfo().filename };
  4548. }
  4549. else {
  4550. throw { type: 'Name',
  4551. message: this.selector.toCSS().trim() + " is undefined",
  4552. index: this.getIndex(), filename: this.fileInfo().filename };
  4553. }
  4554. };
  4555. MixinCall.prototype._setVisibilityToReplacement = function (replacement) {
  4556. var i;
  4557. var rule;
  4558. if (this.blocksVisibility()) {
  4559. for (i = 0; i < replacement.length; i++) {
  4560. rule = replacement[i];
  4561. rule.addVisibilityBlock();
  4562. }
  4563. }
  4564. };
  4565. MixinCall.prototype.format = function (args) {
  4566. return this.selector.toCSS().trim() + "(" + (args ? args.map(function (a) {
  4567. var argValue = '';
  4568. if (a.name) {
  4569. argValue += a.name + ":";
  4570. }
  4571. if (a.value.toCSS) {
  4572. argValue += a.value.toCSS();
  4573. }
  4574. else {
  4575. argValue += '???';
  4576. }
  4577. return argValue;
  4578. }).join(', ') : '') + ")";
  4579. };
  4580. return MixinCall;
  4581. }(Node));
  4582. MixinCall.prototype.type = 'MixinCall';
  4583. var tree = {
  4584. Node: Node, Color: Color, AtRule: AtRule, DetachedRuleset: DetachedRuleset, Operation: Operation,
  4585. Dimension: Dimension, Unit: Unit, Keyword: Keyword, Variable: Variable, Property: Property,
  4586. Ruleset: Ruleset, Element: Element, Attribute: Attribute, Combinator: Combinator, Selector: Selector,
  4587. Quoted: Quoted, Expression: Expression, Declaration: Declaration, Call: Call, URL: URL, Import: Import,
  4588. Comment: Comment, Anonymous: Anonymous, Value: Value, JavaScript: JavaScript, Assignment: Assignment,
  4589. Condition: Condition, Paren: Paren, Media: Media, UnicodeDescriptor: UnicodeDescriptor, Negative: Negative,
  4590. Extend: Extend, VariableCall: VariableCall, NamespaceValue: NamespaceValue,
  4591. mixin: {
  4592. Call: MixinCall,
  4593. Definition: Definition
  4594. }
  4595. };
  4596. /**
  4597. * @todo Document why this abstraction exists, and the relationship between
  4598. * environment, file managers, and plugin manager
  4599. */
  4600. var environment$1 = /** @class */ (function () {
  4601. function environment(externalEnvironment, fileManagers) {
  4602. this.fileManagers = fileManagers || [];
  4603. externalEnvironment = externalEnvironment || {};
  4604. var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'];
  4605. var requiredFunctions = [];
  4606. var functions = requiredFunctions.concat(optionalFunctions);
  4607. for (var i_1 = 0; i_1 < functions.length; i_1++) {
  4608. var propName = functions[i_1];
  4609. var environmentFunc = externalEnvironment[propName];
  4610. if (environmentFunc) {
  4611. this[propName] = environmentFunc.bind(externalEnvironment);
  4612. }
  4613. else if (i_1 < requiredFunctions.length) {
  4614. this.warn("missing required function in environment - " + propName);
  4615. }
  4616. }
  4617. }
  4618. environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
  4619. if (!filename) {
  4620. logger.warn('getFileManager called with no filename.. Please report this issue. continuing.');
  4621. }
  4622. if (currentDirectory == null) {
  4623. logger.warn('getFileManager called with null directory.. Please report this issue. continuing.');
  4624. }
  4625. var fileManagers = this.fileManagers;
  4626. if (options.pluginManager) {
  4627. fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());
  4628. }
  4629. for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) {
  4630. var fileManager = fileManagers[i_2];
  4631. if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {
  4632. return fileManager;
  4633. }
  4634. }
  4635. return null;
  4636. };
  4637. environment.prototype.addFileManager = function (fileManager) {
  4638. this.fileManagers.push(fileManager);
  4639. };
  4640. environment.prototype.clearFileManagers = function () {
  4641. this.fileManagers = [];
  4642. };
  4643. return environment;
  4644. }());
  4645. var AbstractPluginLoader = /** @class */ (function () {
  4646. function AbstractPluginLoader() {
  4647. // Implemented by Node.js plugin loader
  4648. this.require = function () { return null; };
  4649. }
  4650. AbstractPluginLoader.prototype.evalPlugin = function (contents, context, imports, pluginOptions, fileInfo) {
  4651. var loader;
  4652. var registry;
  4653. var pluginObj;
  4654. var localModule;
  4655. var pluginManager;
  4656. var filename;
  4657. var result;
  4658. pluginManager = context.pluginManager;
  4659. if (fileInfo) {
  4660. if (typeof fileInfo === 'string') {
  4661. filename = fileInfo;
  4662. }
  4663. else {
  4664. filename = fileInfo.filename;
  4665. }
  4666. }
  4667. var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename;
  4668. if (filename) {
  4669. pluginObj = pluginManager.get(filename);
  4670. if (pluginObj) {
  4671. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  4672. if (result) {
  4673. return result;
  4674. }
  4675. try {
  4676. if (pluginObj.use) {
  4677. pluginObj.use.call(this.context, pluginObj);
  4678. }
  4679. }
  4680. catch (e) {
  4681. e.message = e.message || 'Error during @plugin call';
  4682. return new LessError(e, imports, filename);
  4683. }
  4684. return pluginObj;
  4685. }
  4686. }
  4687. localModule = {
  4688. exports: {},
  4689. pluginManager: pluginManager,
  4690. fileInfo: fileInfo
  4691. };
  4692. registry = functionRegistry.create();
  4693. var registerPlugin = function (obj) {
  4694. pluginObj = obj;
  4695. };
  4696. try {
  4697. loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents);
  4698. loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo);
  4699. }
  4700. catch (e) {
  4701. return new LessError(e, imports, filename);
  4702. }
  4703. if (!pluginObj) {
  4704. pluginObj = localModule.exports;
  4705. }
  4706. pluginObj = this.validatePlugin(pluginObj, filename, shortname);
  4707. if (pluginObj instanceof LessError) {
  4708. return pluginObj;
  4709. }
  4710. if (pluginObj) {
  4711. pluginObj.imports = imports;
  4712. pluginObj.filename = filename;
  4713. // For < 3.x (or unspecified minVersion) - setOptions() before install()
  4714. if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) {
  4715. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  4716. if (result) {
  4717. return result;
  4718. }
  4719. }
  4720. // Run on first load
  4721. pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);
  4722. pluginObj.functions = registry.getLocalFunctions();
  4723. // Need to call setOptions again because the pluginObj might have functions
  4724. result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
  4725. if (result) {
  4726. return result;
  4727. }
  4728. // Run every @plugin call
  4729. try {
  4730. if (pluginObj.use) {
  4731. pluginObj.use.call(this.context, pluginObj);
  4732. }
  4733. }
  4734. catch (e) {
  4735. e.message = e.message || 'Error during @plugin call';
  4736. return new LessError(e, imports, filename);
  4737. }
  4738. }
  4739. else {
  4740. return new LessError({ message: 'Not a valid plugin' }, imports, filename);
  4741. }
  4742. return pluginObj;
  4743. };
  4744. AbstractPluginLoader.prototype.trySetOptions = function (plugin, filename, name, options) {
  4745. if (options && !plugin.setOptions) {
  4746. return new LessError({
  4747. message: "Options have been provided but the plugin " + name + " does not support any options."
  4748. });
  4749. }
  4750. try {
  4751. plugin.setOptions && plugin.setOptions(options);
  4752. }
  4753. catch (e) {
  4754. return new LessError(e);
  4755. }
  4756. };
  4757. AbstractPluginLoader.prototype.validatePlugin = function (plugin, filename, name) {
  4758. if (plugin) {
  4759. // support plugins being a function
  4760. // so that the plugin can be more usable programmatically
  4761. if (typeof plugin === 'function') {
  4762. plugin = new plugin();
  4763. }
  4764. if (plugin.minVersion) {
  4765. if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {
  4766. return new LessError({
  4767. message: "Plugin " + name + " requires version " + this.versionToString(plugin.minVersion)
  4768. });
  4769. }
  4770. }
  4771. return plugin;
  4772. }
  4773. return null;
  4774. };
  4775. AbstractPluginLoader.prototype.compareVersion = function (aVersion, bVersion) {
  4776. if (typeof aVersion === 'string') {
  4777. aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/);
  4778. aVersion.shift();
  4779. }
  4780. for (var i_1 = 0; i_1 < aVersion.length; i_1++) {
  4781. if (aVersion[i_1] !== bVersion[i_1]) {
  4782. return parseInt(aVersion[i_1]) > parseInt(bVersion[i_1]) ? -1 : 1;
  4783. }
  4784. }
  4785. return 0;
  4786. };
  4787. AbstractPluginLoader.prototype.versionToString = function (version) {
  4788. var versionString = '';
  4789. for (var i_2 = 0; i_2 < version.length; i_2++) {
  4790. versionString += (versionString ? '.' : '') + version[i_2];
  4791. }
  4792. return versionString;
  4793. };
  4794. AbstractPluginLoader.prototype.printUsage = function (plugins) {
  4795. for (var i_3 = 0; i_3 < plugins.length; i_3++) {
  4796. var plugin = plugins[i_3];
  4797. if (plugin.printUsage) {
  4798. plugin.printUsage();
  4799. }
  4800. }
  4801. };
  4802. return AbstractPluginLoader;
  4803. }());
  4804. var _visitArgs = { visitDeeper: true };
  4805. var _hasIndexed = false;
  4806. function _noop(node) {
  4807. return node;
  4808. }
  4809. function indexNodeTypes(parent, ticker) {
  4810. // add .typeIndex to tree node types for lookup table
  4811. var key;
  4812. var child;
  4813. for (key in parent) {
  4814. /* eslint guard-for-in: 0 */
  4815. child = parent[key];
  4816. switch (typeof child) {
  4817. case 'function':
  4818. // ignore bound functions directly on tree which do not have a prototype
  4819. // or aren't nodes
  4820. if (child.prototype && child.prototype.type) {
  4821. child.prototype.typeIndex = ticker++;
  4822. }
  4823. break;
  4824. case 'object':
  4825. ticker = indexNodeTypes(child, ticker);
  4826. break;
  4827. }
  4828. }
  4829. return ticker;
  4830. }
  4831. var Visitor = /** @class */ (function () {
  4832. function Visitor(implementation) {
  4833. this._implementation = implementation;
  4834. this._visitInCache = {};
  4835. this._visitOutCache = {};
  4836. if (!_hasIndexed) {
  4837. indexNodeTypes(tree, 1);
  4838. _hasIndexed = true;
  4839. }
  4840. }
  4841. Visitor.prototype.visit = function (node) {
  4842. if (!node) {
  4843. return node;
  4844. }
  4845. var nodeTypeIndex = node.typeIndex;
  4846. if (!nodeTypeIndex) {
  4847. // MixinCall args aren't a node type?
  4848. if (node.value && node.value.typeIndex) {
  4849. this.visit(node.value);
  4850. }
  4851. return node;
  4852. }
  4853. var impl = this._implementation;
  4854. var func = this._visitInCache[nodeTypeIndex];
  4855. var funcOut = this._visitOutCache[nodeTypeIndex];
  4856. var visitArgs = _visitArgs;
  4857. var fnName;
  4858. visitArgs.visitDeeper = true;
  4859. if (!func) {
  4860. fnName = "visit" + node.type;
  4861. func = impl[fnName] || _noop;
  4862. funcOut = impl[fnName + "Out"] || _noop;
  4863. this._visitInCache[nodeTypeIndex] = func;
  4864. this._visitOutCache[nodeTypeIndex] = funcOut;
  4865. }
  4866. if (func !== _noop) {
  4867. var newNode = func.call(impl, node, visitArgs);
  4868. if (node && impl.isReplacing) {
  4869. node = newNode;
  4870. }
  4871. }
  4872. if (visitArgs.visitDeeper && node) {
  4873. if (node.length) {
  4874. for (var i = 0, cnt = node.length; i < cnt; i++) {
  4875. if (node[i].accept) {
  4876. node[i].accept(this);
  4877. }
  4878. }
  4879. }
  4880. else if (node.accept) {
  4881. node.accept(this);
  4882. }
  4883. }
  4884. if (funcOut != _noop) {
  4885. funcOut.call(impl, node);
  4886. }
  4887. return node;
  4888. };
  4889. Visitor.prototype.visitArray = function (nodes, nonReplacing) {
  4890. if (!nodes) {
  4891. return nodes;
  4892. }
  4893. var cnt = nodes.length;
  4894. var i;
  4895. // Non-replacing
  4896. if (nonReplacing || !this._implementation.isReplacing) {
  4897. for (i = 0; i < cnt; i++) {
  4898. this.visit(nodes[i]);
  4899. }
  4900. return nodes;
  4901. }
  4902. // Replacing
  4903. var out = [];
  4904. for (i = 0; i < cnt; i++) {
  4905. var evald = this.visit(nodes[i]);
  4906. if (evald === undefined) {
  4907. continue;
  4908. }
  4909. if (!evald.splice) {
  4910. out.push(evald);
  4911. }
  4912. else if (evald.length) {
  4913. this.flatten(evald, out);
  4914. }
  4915. }
  4916. return out;
  4917. };
  4918. Visitor.prototype.flatten = function (arr, out) {
  4919. if (!out) {
  4920. out = [];
  4921. }
  4922. var cnt;
  4923. var i;
  4924. var item;
  4925. var nestedCnt;
  4926. var j;
  4927. var nestedItem;
  4928. for (i = 0, cnt = arr.length; i < cnt; i++) {
  4929. item = arr[i];
  4930. if (item === undefined) {
  4931. continue;
  4932. }
  4933. if (!item.splice) {
  4934. out.push(item);
  4935. continue;
  4936. }
  4937. for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {
  4938. nestedItem = item[j];
  4939. if (nestedItem === undefined) {
  4940. continue;
  4941. }
  4942. if (!nestedItem.splice) {
  4943. out.push(nestedItem);
  4944. }
  4945. else if (nestedItem.length) {
  4946. this.flatten(nestedItem, out);
  4947. }
  4948. }
  4949. }
  4950. return out;
  4951. };
  4952. return Visitor;
  4953. }());
  4954. var ImportSequencer = /** @class */ (function () {
  4955. function ImportSequencer(onSequencerEmpty) {
  4956. this.imports = [];
  4957. this.variableImports = [];
  4958. this._onSequencerEmpty = onSequencerEmpty;
  4959. this._currentDepth = 0;
  4960. }
  4961. ImportSequencer.prototype.addImport = function (callback) {
  4962. var importSequencer = this;
  4963. var importItem = {
  4964. callback: callback,
  4965. args: null,
  4966. isReady: false
  4967. };
  4968. this.imports.push(importItem);
  4969. return function () {
  4970. var args = [];
  4971. for (var _i = 0; _i < arguments.length; _i++) {
  4972. args[_i] = arguments[_i];
  4973. }
  4974. importItem.args = Array.prototype.slice.call(args, 0);
  4975. importItem.isReady = true;
  4976. importSequencer.tryRun();
  4977. };
  4978. };
  4979. ImportSequencer.prototype.addVariableImport = function (callback) {
  4980. this.variableImports.push(callback);
  4981. };
  4982. ImportSequencer.prototype.tryRun = function () {
  4983. this._currentDepth++;
  4984. try {
  4985. while (true) {
  4986. while (this.imports.length > 0) {
  4987. var importItem = this.imports[0];
  4988. if (!importItem.isReady) {
  4989. return;
  4990. }
  4991. this.imports = this.imports.slice(1);
  4992. importItem.callback.apply(null, importItem.args);
  4993. }
  4994. if (this.variableImports.length === 0) {
  4995. break;
  4996. }
  4997. var variableImport = this.variableImports[0];
  4998. this.variableImports = this.variableImports.slice(1);
  4999. variableImport();
  5000. }
  5001. }
  5002. finally {
  5003. this._currentDepth--;
  5004. }
  5005. if (this._currentDepth === 0 && this._onSequencerEmpty) {
  5006. this._onSequencerEmpty();
  5007. }
  5008. };
  5009. return ImportSequencer;
  5010. }());
  5011. var ImportVisitor = function (importer, finish) {
  5012. this._visitor = new Visitor(this);
  5013. this._importer = importer;
  5014. this._finish = finish;
  5015. this.context = new contexts.Eval();
  5016. this.importCount = 0;
  5017. this.onceFileDetectionMap = {};
  5018. this.recursionDetector = {};
  5019. this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));
  5020. };
  5021. ImportVisitor.prototype = {
  5022. isReplacing: false,
  5023. run: function (root) {
  5024. try {
  5025. // process the contents
  5026. this._visitor.visit(root);
  5027. }
  5028. catch (e) {
  5029. this.error = e;
  5030. }
  5031. this.isFinished = true;
  5032. this._sequencer.tryRun();
  5033. },
  5034. _onSequencerEmpty: function () {
  5035. if (!this.isFinished) {
  5036. return;
  5037. }
  5038. this._finish(this.error);
  5039. },
  5040. visitImport: function (importNode, visitArgs) {
  5041. var inlineCSS = importNode.options.inline;
  5042. if (!importNode.css || inlineCSS) {
  5043. var context = new contexts.Eval(this.context, copyArray(this.context.frames));
  5044. var importParent = context.frames[0];
  5045. this.importCount++;
  5046. if (importNode.isVariableImport()) {
  5047. this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));
  5048. }
  5049. else {
  5050. this.processImportNode(importNode, context, importParent);
  5051. }
  5052. }
  5053. visitArgs.visitDeeper = false;
  5054. },
  5055. processImportNode: function (importNode, context, importParent) {
  5056. var evaldImportNode;
  5057. var inlineCSS = importNode.options.inline;
  5058. try {
  5059. evaldImportNode = importNode.evalForImport(context);
  5060. }
  5061. catch (e) {
  5062. if (!e.filename) {
  5063. e.index = importNode.getIndex();
  5064. e.filename = importNode.fileInfo().filename;
  5065. }
  5066. // attempt to eval properly and treat as css
  5067. importNode.css = true;
  5068. // if that fails, this error will be thrown
  5069. importNode.error = e;
  5070. }
  5071. if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {
  5072. if (evaldImportNode.options.multiple) {
  5073. context.importMultiple = true;
  5074. }
  5075. // try appending if we haven't determined if it is css or not
  5076. var tryAppendLessExtension = evaldImportNode.css === undefined;
  5077. for (var i_1 = 0; i_1 < importParent.rules.length; i_1++) {
  5078. if (importParent.rules[i_1] === importNode) {
  5079. importParent.rules[i_1] = evaldImportNode;
  5080. break;
  5081. }
  5082. }
  5083. var onImported = this.onImported.bind(this, evaldImportNode, context);
  5084. var sequencedOnImported = this._sequencer.addImport(onImported);
  5085. this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported);
  5086. }
  5087. else {
  5088. this.importCount--;
  5089. if (this.isFinished) {
  5090. this._sequencer.tryRun();
  5091. }
  5092. }
  5093. },
  5094. onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {
  5095. if (e) {
  5096. if (!e.filename) {
  5097. e.index = importNode.getIndex();
  5098. e.filename = importNode.fileInfo().filename;
  5099. }
  5100. this.error = e;
  5101. }
  5102. var importVisitor = this;
  5103. var inlineCSS = importNode.options.inline;
  5104. var isPlugin = importNode.options.isPlugin;
  5105. var isOptional = importNode.options.optional;
  5106. var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;
  5107. if (!context.importMultiple) {
  5108. if (duplicateImport) {
  5109. importNode.skip = true;
  5110. }
  5111. else {
  5112. importNode.skip = function () {
  5113. if (fullPath in importVisitor.onceFileDetectionMap) {
  5114. return true;
  5115. }
  5116. importVisitor.onceFileDetectionMap[fullPath] = true;
  5117. return false;
  5118. };
  5119. }
  5120. }
  5121. if (!fullPath && isOptional) {
  5122. importNode.skip = true;
  5123. }
  5124. if (root) {
  5125. importNode.root = root;
  5126. importNode.importedFilename = fullPath;
  5127. if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {
  5128. importVisitor.recursionDetector[fullPath] = true;
  5129. var oldContext = this.context;
  5130. this.context = context;
  5131. try {
  5132. this._visitor.visit(root);
  5133. }
  5134. catch (e) {
  5135. this.error = e;
  5136. }
  5137. this.context = oldContext;
  5138. }
  5139. }
  5140. importVisitor.importCount--;
  5141. if (importVisitor.isFinished) {
  5142. importVisitor._sequencer.tryRun();
  5143. }
  5144. },
  5145. visitDeclaration: function (declNode, visitArgs) {
  5146. if (declNode.value.type === 'DetachedRuleset') {
  5147. this.context.frames.unshift(declNode);
  5148. }
  5149. else {
  5150. visitArgs.visitDeeper = false;
  5151. }
  5152. },
  5153. visitDeclarationOut: function (declNode) {
  5154. if (declNode.value.type === 'DetachedRuleset') {
  5155. this.context.frames.shift();
  5156. }
  5157. },
  5158. visitAtRule: function (atRuleNode, visitArgs) {
  5159. this.context.frames.unshift(atRuleNode);
  5160. },
  5161. visitAtRuleOut: function (atRuleNode) {
  5162. this.context.frames.shift();
  5163. },
  5164. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  5165. this.context.frames.unshift(mixinDefinitionNode);
  5166. },
  5167. visitMixinDefinitionOut: function (mixinDefinitionNode) {
  5168. this.context.frames.shift();
  5169. },
  5170. visitRuleset: function (rulesetNode, visitArgs) {
  5171. this.context.frames.unshift(rulesetNode);
  5172. },
  5173. visitRulesetOut: function (rulesetNode) {
  5174. this.context.frames.shift();
  5175. },
  5176. visitMedia: function (mediaNode, visitArgs) {
  5177. this.context.frames.unshift(mediaNode.rules[0]);
  5178. },
  5179. visitMediaOut: function (mediaNode) {
  5180. this.context.frames.shift();
  5181. }
  5182. };
  5183. var SetTreeVisibilityVisitor = /** @class */ (function () {
  5184. function SetTreeVisibilityVisitor(visible) {
  5185. this.visible = visible;
  5186. }
  5187. SetTreeVisibilityVisitor.prototype.run = function (root) {
  5188. this.visit(root);
  5189. };
  5190. SetTreeVisibilityVisitor.prototype.visitArray = function (nodes) {
  5191. if (!nodes) {
  5192. return nodes;
  5193. }
  5194. var cnt = nodes.length;
  5195. var i;
  5196. for (i = 0; i < cnt; i++) {
  5197. this.visit(nodes[i]);
  5198. }
  5199. return nodes;
  5200. };
  5201. SetTreeVisibilityVisitor.prototype.visit = function (node) {
  5202. if (!node) {
  5203. return node;
  5204. }
  5205. if (node.constructor === Array) {
  5206. return this.visitArray(node);
  5207. }
  5208. if (!node.blocksVisibility || node.blocksVisibility()) {
  5209. return node;
  5210. }
  5211. if (this.visible) {
  5212. node.ensureVisibility();
  5213. }
  5214. else {
  5215. node.ensureInvisibility();
  5216. }
  5217. node.accept(this);
  5218. return node;
  5219. };
  5220. return SetTreeVisibilityVisitor;
  5221. }());
  5222. /* jshint loopfunc:true */
  5223. var ExtendFinderVisitor = /** @class */ (function () {
  5224. function ExtendFinderVisitor() {
  5225. this._visitor = new Visitor(this);
  5226. this.contexts = [];
  5227. this.allExtendsStack = [[]];
  5228. }
  5229. ExtendFinderVisitor.prototype.run = function (root) {
  5230. root = this._visitor.visit(root);
  5231. root.allExtends = this.allExtendsStack[0];
  5232. return root;
  5233. };
  5234. ExtendFinderVisitor.prototype.visitDeclaration = function (declNode, visitArgs) {
  5235. visitArgs.visitDeeper = false;
  5236. };
  5237. ExtendFinderVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  5238. visitArgs.visitDeeper = false;
  5239. };
  5240. ExtendFinderVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  5241. if (rulesetNode.root) {
  5242. return;
  5243. }
  5244. var i;
  5245. var j;
  5246. var extend;
  5247. var allSelectorsExtendList = [];
  5248. var extendList;
  5249. // get &:extend(.a); rules which apply to all selectors in this ruleset
  5250. var rules = rulesetNode.rules;
  5251. var ruleCnt = rules ? rules.length : 0;
  5252. for (i = 0; i < ruleCnt; i++) {
  5253. if (rulesetNode.rules[i] instanceof tree.Extend) {
  5254. allSelectorsExtendList.push(rules[i]);
  5255. rulesetNode.extendOnEveryPath = true;
  5256. }
  5257. }
  5258. // now find every selector and apply the extends that apply to all extends
  5259. // and the ones which apply to an individual extend
  5260. var paths = rulesetNode.paths;
  5261. for (i = 0; i < paths.length; i++) {
  5262. var selectorPath = paths[i];
  5263. var selector = selectorPath[selectorPath.length - 1];
  5264. var selExtendList = selector.extendList;
  5265. extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList)
  5266. : allSelectorsExtendList;
  5267. if (extendList) {
  5268. extendList = extendList.map(function (allSelectorsExtend) { return allSelectorsExtend.clone(); });
  5269. }
  5270. for (j = 0; j < extendList.length; j++) {
  5271. this.foundExtends = true;
  5272. extend = extendList[j];
  5273. extend.findSelfSelectors(selectorPath);
  5274. extend.ruleset = rulesetNode;
  5275. if (j === 0) {
  5276. extend.firstExtendOnThisSelectorPath = true;
  5277. }
  5278. this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);
  5279. }
  5280. }
  5281. this.contexts.push(rulesetNode.selectors);
  5282. };
  5283. ExtendFinderVisitor.prototype.visitRulesetOut = function (rulesetNode) {
  5284. if (!rulesetNode.root) {
  5285. this.contexts.length = this.contexts.length - 1;
  5286. }
  5287. };
  5288. ExtendFinderVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  5289. mediaNode.allExtends = [];
  5290. this.allExtendsStack.push(mediaNode.allExtends);
  5291. };
  5292. ExtendFinderVisitor.prototype.visitMediaOut = function (mediaNode) {
  5293. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  5294. };
  5295. ExtendFinderVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  5296. atRuleNode.allExtends = [];
  5297. this.allExtendsStack.push(atRuleNode.allExtends);
  5298. };
  5299. ExtendFinderVisitor.prototype.visitAtRuleOut = function (atRuleNode) {
  5300. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  5301. };
  5302. return ExtendFinderVisitor;
  5303. }());
  5304. var ProcessExtendsVisitor = /** @class */ (function () {
  5305. function ProcessExtendsVisitor() {
  5306. this._visitor = new Visitor(this);
  5307. }
  5308. ProcessExtendsVisitor.prototype.run = function (root) {
  5309. var extendFinder = new ExtendFinderVisitor();
  5310. this.extendIndices = {};
  5311. extendFinder.run(root);
  5312. if (!extendFinder.foundExtends) {
  5313. return root;
  5314. }
  5315. root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
  5316. this.allExtendsStack = [root.allExtends];
  5317. var newRoot = this._visitor.visit(root);
  5318. this.checkExtendsForNonMatched(root.allExtends);
  5319. return newRoot;
  5320. };
  5321. ProcessExtendsVisitor.prototype.checkExtendsForNonMatched = function (extendList) {
  5322. var indices = this.extendIndices;
  5323. extendList.filter(function (extend) { return !extend.hasFoundMatches && extend.parent_ids.length == 1; }).forEach(function (extend) {
  5324. var selector = '_unknown_';
  5325. try {
  5326. selector = extend.selector.toCSS({});
  5327. }
  5328. catch (_) { }
  5329. if (!indices[extend.index + " " + selector]) {
  5330. indices[extend.index + " " + selector] = true;
  5331. logger.warn("extend '" + selector + "' has no matches");
  5332. }
  5333. });
  5334. };
  5335. ProcessExtendsVisitor.prototype.doExtendChaining = function (extendsList, extendsListTarget, iterationCount) {
  5336. //
  5337. // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering
  5338. // and pasting the selector we would do normally, but we are also adding an extend with the same target selector
  5339. // this means this new extend can then go and alter other extends
  5340. //
  5341. // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors
  5342. // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already
  5343. // processed if we look at each selector at a time, as is done in visitRuleset
  5344. var extendIndex;
  5345. var targetExtendIndex;
  5346. var matches;
  5347. var extendsToAdd = [];
  5348. var newSelector;
  5349. var extendVisitor = this;
  5350. var selectorPath;
  5351. var extend;
  5352. var targetExtend;
  5353. var newExtend;
  5354. iterationCount = iterationCount || 0;
  5355. // loop through comparing every extend with every target extend.
  5356. // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
  5357. // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
  5358. // and the second is the target.
  5359. // the separation into two lists allows us to process a subset of chains with a bigger set, as is the
  5360. // case when processing media queries
  5361. for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {
  5362. for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {
  5363. extend = extendsList[extendIndex];
  5364. targetExtend = extendsListTarget[targetExtendIndex];
  5365. // look for circular references
  5366. if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) {
  5367. continue;
  5368. }
  5369. // find a match in the target extends self selector (the bit before :extend)
  5370. selectorPath = [targetExtend.selfSelectors[0]];
  5371. matches = extendVisitor.findMatch(extend, selectorPath);
  5372. if (matches.length) {
  5373. extend.hasFoundMatches = true;
  5374. // we found a match, so for each self selector..
  5375. extend.selfSelectors.forEach(function (selfSelector) {
  5376. var info = targetExtend.visibilityInfo();
  5377. // process the extend as usual
  5378. newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());
  5379. // but now we create a new extend from it
  5380. newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info);
  5381. newExtend.selfSelectors = newSelector;
  5382. // add the extend onto the list of extends for that selector
  5383. newSelector[newSelector.length - 1].extendList = [newExtend];
  5384. // record that we need to add it.
  5385. extendsToAdd.push(newExtend);
  5386. newExtend.ruleset = targetExtend.ruleset;
  5387. // remember its parents for circular references
  5388. newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);
  5389. // only process the selector once.. if we have :extend(.a,.b) then multiple
  5390. // extends will look at the same selector path, so when extending
  5391. // we know that any others will be duplicates in terms of what is added to the css
  5392. if (targetExtend.firstExtendOnThisSelectorPath) {
  5393. newExtend.firstExtendOnThisSelectorPath = true;
  5394. targetExtend.ruleset.paths.push(newSelector);
  5395. }
  5396. });
  5397. }
  5398. }
  5399. }
  5400. if (extendsToAdd.length) {
  5401. // try to detect circular references to stop a stack overflow.
  5402. // may no longer be needed.
  5403. this.extendChainCount++;
  5404. if (iterationCount > 100) {
  5405. var selectorOne = '{unable to calculate}';
  5406. var selectorTwo = '{unable to calculate}';
  5407. try {
  5408. selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
  5409. selectorTwo = extendsToAdd[0].selector.toCSS();
  5410. }
  5411. catch (e) { }
  5412. throw { message: "extend circular reference detected. One of the circular extends is currently:" + selectorOne + ":extend(" + selectorTwo + ")" };
  5413. }
  5414. // now process the new extends on the existing rules so that we can handle a extending b extending c extending
  5415. // d extending e...
  5416. return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));
  5417. }
  5418. else {
  5419. return extendsToAdd;
  5420. }
  5421. };
  5422. ProcessExtendsVisitor.prototype.visitDeclaration = function (ruleNode, visitArgs) {
  5423. visitArgs.visitDeeper = false;
  5424. };
  5425. ProcessExtendsVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  5426. visitArgs.visitDeeper = false;
  5427. };
  5428. ProcessExtendsVisitor.prototype.visitSelector = function (selectorNode, visitArgs) {
  5429. visitArgs.visitDeeper = false;
  5430. };
  5431. ProcessExtendsVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  5432. if (rulesetNode.root) {
  5433. return;
  5434. }
  5435. var matches;
  5436. var pathIndex;
  5437. var extendIndex;
  5438. var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1];
  5439. var selectorsToAdd = [];
  5440. var extendVisitor = this;
  5441. var selectorPath;
  5442. // look at each selector path in the ruleset, find any extend matches and then copy, find and replace
  5443. for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {
  5444. for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {
  5445. selectorPath = rulesetNode.paths[pathIndex];
  5446. // extending extends happens initially, before the main pass
  5447. if (rulesetNode.extendOnEveryPath) {
  5448. continue;
  5449. }
  5450. var extendList = selectorPath[selectorPath.length - 1].extendList;
  5451. if (extendList && extendList.length) {
  5452. continue;
  5453. }
  5454. matches = this.findMatch(allExtends[extendIndex], selectorPath);
  5455. if (matches.length) {
  5456. allExtends[extendIndex].hasFoundMatches = true;
  5457. allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) {
  5458. var extendedSelectors;
  5459. extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());
  5460. selectorsToAdd.push(extendedSelectors);
  5461. });
  5462. }
  5463. }
  5464. }
  5465. rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
  5466. };
  5467. ProcessExtendsVisitor.prototype.findMatch = function (extend, haystackSelectorPath) {
  5468. //
  5469. // look through the haystack selector path to try and find the needle - extend.selector
  5470. // returns an array of selector matches that can then be replaced
  5471. //
  5472. var haystackSelectorIndex;
  5473. var hackstackSelector;
  5474. var hackstackElementIndex;
  5475. var haystackElement;
  5476. var targetCombinator;
  5477. var i;
  5478. var extendVisitor = this;
  5479. var needleElements = extend.selector.elements;
  5480. var potentialMatches = [];
  5481. var potentialMatch;
  5482. var matches = [];
  5483. // loop through the haystack elements
  5484. for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {
  5485. hackstackSelector = haystackSelectorPath[haystackSelectorIndex];
  5486. for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {
  5487. haystackElement = hackstackSelector.elements[hackstackElementIndex];
  5488. // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
  5489. if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {
  5490. potentialMatches.push({ pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,
  5491. initialCombinator: haystackElement.combinator });
  5492. }
  5493. for (i = 0; i < potentialMatches.length; i++) {
  5494. potentialMatch = potentialMatches[i];
  5495. // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
  5496. // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to
  5497. // work out what the resulting combinator will be
  5498. targetCombinator = haystackElement.combinator.value;
  5499. if (targetCombinator === '' && hackstackElementIndex === 0) {
  5500. targetCombinator = ' ';
  5501. }
  5502. // if we don't match, null our match to indicate failure
  5503. if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||
  5504. (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {
  5505. potentialMatch = null;
  5506. }
  5507. else {
  5508. potentialMatch.matched++;
  5509. }
  5510. // if we are still valid and have finished, test whether we have elements after and whether these are allowed
  5511. if (potentialMatch) {
  5512. potentialMatch.finished = potentialMatch.matched === needleElements.length;
  5513. if (potentialMatch.finished &&
  5514. (!extend.allowAfter &&
  5515. (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {
  5516. potentialMatch = null;
  5517. }
  5518. }
  5519. // if null we remove, if not, we are still valid, so either push as a valid match or continue
  5520. if (potentialMatch) {
  5521. if (potentialMatch.finished) {
  5522. potentialMatch.length = needleElements.length;
  5523. potentialMatch.endPathIndex = haystackSelectorIndex;
  5524. potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match
  5525. potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again
  5526. matches.push(potentialMatch);
  5527. }
  5528. }
  5529. else {
  5530. potentialMatches.splice(i, 1);
  5531. i--;
  5532. }
  5533. }
  5534. }
  5535. }
  5536. return matches;
  5537. };
  5538. ProcessExtendsVisitor.prototype.isElementValuesEqual = function (elementValue1, elementValue2) {
  5539. if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') {
  5540. return elementValue1 === elementValue2;
  5541. }
  5542. if (elementValue1 instanceof tree.Attribute) {
  5543. if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {
  5544. return false;
  5545. }
  5546. if (!elementValue1.value || !elementValue2.value) {
  5547. if (elementValue1.value || elementValue2.value) {
  5548. return false;
  5549. }
  5550. return true;
  5551. }
  5552. elementValue1 = elementValue1.value.value || elementValue1.value;
  5553. elementValue2 = elementValue2.value.value || elementValue2.value;
  5554. return elementValue1 === elementValue2;
  5555. }
  5556. elementValue1 = elementValue1.value;
  5557. elementValue2 = elementValue2.value;
  5558. if (elementValue1 instanceof tree.Selector) {
  5559. if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {
  5560. return false;
  5561. }
  5562. for (var i_1 = 0; i_1 < elementValue1.elements.length; i_1++) {
  5563. if (elementValue1.elements[i_1].combinator.value !== elementValue2.elements[i_1].combinator.value) {
  5564. if (i_1 !== 0 || (elementValue1.elements[i_1].combinator.value || ' ') !== (elementValue2.elements[i_1].combinator.value || ' ')) {
  5565. return false;
  5566. }
  5567. }
  5568. if (!this.isElementValuesEqual(elementValue1.elements[i_1].value, elementValue2.elements[i_1].value)) {
  5569. return false;
  5570. }
  5571. }
  5572. return true;
  5573. }
  5574. return false;
  5575. };
  5576. ProcessExtendsVisitor.prototype.extendSelector = function (matches, selectorPath, replacementSelector, isVisible) {
  5577. // for a set of matches, replace each match with the replacement selector
  5578. var currentSelectorPathIndex = 0;
  5579. var currentSelectorPathElementIndex = 0;
  5580. var path = [];
  5581. var matchIndex;
  5582. var selector;
  5583. var firstElement;
  5584. var match;
  5585. var newElements;
  5586. for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {
  5587. match = matches[matchIndex];
  5588. selector = selectorPath[match.pathIndex];
  5589. firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo());
  5590. if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {
  5591. path[path.length - 1].elements = path[path.length - 1]
  5592. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  5593. currentSelectorPathElementIndex = 0;
  5594. currentSelectorPathIndex++;
  5595. }
  5596. newElements = selector.elements
  5597. .slice(currentSelectorPathElementIndex, match.index)
  5598. .concat([firstElement])
  5599. .concat(replacementSelector.elements.slice(1));
  5600. if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {
  5601. path[path.length - 1].elements =
  5602. path[path.length - 1].elements.concat(newElements);
  5603. }
  5604. else {
  5605. path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));
  5606. path.push(new tree.Selector(newElements));
  5607. }
  5608. currentSelectorPathIndex = match.endPathIndex;
  5609. currentSelectorPathElementIndex = match.endPathElementIndex;
  5610. if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {
  5611. currentSelectorPathElementIndex = 0;
  5612. currentSelectorPathIndex++;
  5613. }
  5614. }
  5615. if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {
  5616. path[path.length - 1].elements = path[path.length - 1]
  5617. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  5618. currentSelectorPathIndex++;
  5619. }
  5620. path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));
  5621. path = path.map(function (currentValue) {
  5622. // we can re-use elements here, because the visibility property matters only for selectors
  5623. var derived = currentValue.createDerived(currentValue.elements);
  5624. if (isVisible) {
  5625. derived.ensureVisibility();
  5626. }
  5627. else {
  5628. derived.ensureInvisibility();
  5629. }
  5630. return derived;
  5631. });
  5632. return path;
  5633. };
  5634. ProcessExtendsVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  5635. var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  5636. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));
  5637. this.allExtendsStack.push(newAllExtends);
  5638. };
  5639. ProcessExtendsVisitor.prototype.visitMediaOut = function (mediaNode) {
  5640. var lastIndex = this.allExtendsStack.length - 1;
  5641. this.allExtendsStack.length = lastIndex;
  5642. };
  5643. ProcessExtendsVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  5644. var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  5645. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends));
  5646. this.allExtendsStack.push(newAllExtends);
  5647. };
  5648. ProcessExtendsVisitor.prototype.visitAtRuleOut = function (atRuleNode) {
  5649. var lastIndex = this.allExtendsStack.length - 1;
  5650. this.allExtendsStack.length = lastIndex;
  5651. };
  5652. return ProcessExtendsVisitor;
  5653. }());
  5654. var JoinSelectorVisitor = /** @class */ (function () {
  5655. function JoinSelectorVisitor() {
  5656. this.contexts = [[]];
  5657. this._visitor = new Visitor(this);
  5658. }
  5659. JoinSelectorVisitor.prototype.run = function (root) {
  5660. return this._visitor.visit(root);
  5661. };
  5662. JoinSelectorVisitor.prototype.visitDeclaration = function (declNode, visitArgs) {
  5663. visitArgs.visitDeeper = false;
  5664. };
  5665. JoinSelectorVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) {
  5666. visitArgs.visitDeeper = false;
  5667. };
  5668. JoinSelectorVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) {
  5669. var context = this.contexts[this.contexts.length - 1];
  5670. var paths = [];
  5671. var selectors;
  5672. this.contexts.push(paths);
  5673. if (!rulesetNode.root) {
  5674. selectors = rulesetNode.selectors;
  5675. if (selectors) {
  5676. selectors = selectors.filter(function (selector) { return selector.getIsOutput(); });
  5677. rulesetNode.selectors = selectors.length ? selectors : (selectors = null);
  5678. if (selectors) {
  5679. rulesetNode.joinSelectors(paths, context, selectors);
  5680. }
  5681. }
  5682. if (!selectors) {
  5683. rulesetNode.rules = null;
  5684. }
  5685. rulesetNode.paths = paths;
  5686. }
  5687. };
  5688. JoinSelectorVisitor.prototype.visitRulesetOut = function (rulesetNode) {
  5689. this.contexts.length = this.contexts.length - 1;
  5690. };
  5691. JoinSelectorVisitor.prototype.visitMedia = function (mediaNode, visitArgs) {
  5692. var context = this.contexts[this.contexts.length - 1];
  5693. mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);
  5694. };
  5695. JoinSelectorVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) {
  5696. var context = this.contexts[this.contexts.length - 1];
  5697. if (atRuleNode.rules && atRuleNode.rules.length) {
  5698. atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null);
  5699. }
  5700. };
  5701. return JoinSelectorVisitor;
  5702. }());
  5703. var CSSVisitorUtils = /** @class */ (function () {
  5704. function CSSVisitorUtils(context) {
  5705. this._visitor = new Visitor(this);
  5706. this._context = context;
  5707. }
  5708. CSSVisitorUtils.prototype.containsSilentNonBlockedChild = function (bodyRules) {
  5709. var rule;
  5710. if (!bodyRules) {
  5711. return false;
  5712. }
  5713. for (var r = 0; r < bodyRules.length; r++) {
  5714. rule = bodyRules[r];
  5715. if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {
  5716. // the atrule contains something that was referenced (likely by extend)
  5717. // therefore it needs to be shown in output too
  5718. return true;
  5719. }
  5720. }
  5721. return false;
  5722. };
  5723. CSSVisitorUtils.prototype.keepOnlyVisibleChilds = function (owner) {
  5724. if (owner && owner.rules) {
  5725. owner.rules = owner.rules.filter(function (thing) { return thing.isVisible(); });
  5726. }
  5727. };
  5728. CSSVisitorUtils.prototype.isEmpty = function (owner) {
  5729. return (owner && owner.rules)
  5730. ? (owner.rules.length === 0) : true;
  5731. };
  5732. CSSVisitorUtils.prototype.hasVisibleSelector = function (rulesetNode) {
  5733. return (rulesetNode && rulesetNode.paths)
  5734. ? (rulesetNode.paths.length > 0) : false;
  5735. };
  5736. CSSVisitorUtils.prototype.resolveVisibility = function (node, originalRules) {
  5737. if (!node.blocksVisibility()) {
  5738. if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {
  5739. return;
  5740. }
  5741. return node;
  5742. }
  5743. var compiledRulesBody = node.rules[0];
  5744. this.keepOnlyVisibleChilds(compiledRulesBody);
  5745. if (this.isEmpty(compiledRulesBody)) {
  5746. return;
  5747. }
  5748. node.ensureVisibility();
  5749. node.removeVisibilityBlock();
  5750. return node;
  5751. };
  5752. CSSVisitorUtils.prototype.isVisibleRuleset = function (rulesetNode) {
  5753. if (rulesetNode.firstRoot) {
  5754. return true;
  5755. }
  5756. if (this.isEmpty(rulesetNode)) {
  5757. return false;
  5758. }
  5759. if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {
  5760. return false;
  5761. }
  5762. return true;
  5763. };
  5764. return CSSVisitorUtils;
  5765. }());
  5766. var ToCSSVisitor = function (context) {
  5767. this._visitor = new Visitor(this);
  5768. this._context = context;
  5769. this.utils = new CSSVisitorUtils(context);
  5770. };
  5771. ToCSSVisitor.prototype = {
  5772. isReplacing: true,
  5773. run: function (root) {
  5774. return this._visitor.visit(root);
  5775. },
  5776. visitDeclaration: function (declNode, visitArgs) {
  5777. if (declNode.blocksVisibility() || declNode.variable) {
  5778. return;
  5779. }
  5780. return declNode;
  5781. },
  5782. visitMixinDefinition: function (mixinNode, visitArgs) {
  5783. // mixin definitions do not get eval'd - this means they keep state
  5784. // so we have to clear that state here so it isn't used if toCSS is called twice
  5785. mixinNode.frames = [];
  5786. },
  5787. visitExtend: function (extendNode, visitArgs) {
  5788. },
  5789. visitComment: function (commentNode, visitArgs) {
  5790. if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {
  5791. return;
  5792. }
  5793. return commentNode;
  5794. },
  5795. visitMedia: function (mediaNode, visitArgs) {
  5796. var originalRules = mediaNode.rules[0].rules;
  5797. mediaNode.accept(this._visitor);
  5798. visitArgs.visitDeeper = false;
  5799. return this.utils.resolveVisibility(mediaNode, originalRules);
  5800. },
  5801. visitImport: function (importNode, visitArgs) {
  5802. if (importNode.blocksVisibility()) {
  5803. return;
  5804. }
  5805. return importNode;
  5806. },
  5807. visitAtRule: function (atRuleNode, visitArgs) {
  5808. if (atRuleNode.rules && atRuleNode.rules.length) {
  5809. return this.visitAtRuleWithBody(atRuleNode, visitArgs);
  5810. }
  5811. else {
  5812. return this.visitAtRuleWithoutBody(atRuleNode, visitArgs);
  5813. }
  5814. },
  5815. visitAnonymous: function (anonymousNode, visitArgs) {
  5816. if (!anonymousNode.blocksVisibility()) {
  5817. anonymousNode.accept(this._visitor);
  5818. return anonymousNode;
  5819. }
  5820. },
  5821. visitAtRuleWithBody: function (atRuleNode, visitArgs) {
  5822. // if there is only one nested ruleset and that one has no path, then it is
  5823. // just fake ruleset
  5824. function hasFakeRuleset(atRuleNode) {
  5825. var bodyRules = atRuleNode.rules;
  5826. return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);
  5827. }
  5828. function getBodyRules(atRuleNode) {
  5829. var nodeRules = atRuleNode.rules;
  5830. if (hasFakeRuleset(atRuleNode)) {
  5831. return nodeRules[0].rules;
  5832. }
  5833. return nodeRules;
  5834. }
  5835. // it is still true that it is only one ruleset in array
  5836. // this is last such moment
  5837. // process childs
  5838. var originalRules = getBodyRules(atRuleNode);
  5839. atRuleNode.accept(this._visitor);
  5840. visitArgs.visitDeeper = false;
  5841. if (!this.utils.isEmpty(atRuleNode)) {
  5842. this._mergeRules(atRuleNode.rules[0].rules);
  5843. }
  5844. return this.utils.resolveVisibility(atRuleNode, originalRules);
  5845. },
  5846. visitAtRuleWithoutBody: function (atRuleNode, visitArgs) {
  5847. if (atRuleNode.blocksVisibility()) {
  5848. return;
  5849. }
  5850. if (atRuleNode.name === '@charset') {
  5851. // Only output the debug info together with subsequent @charset definitions
  5852. // a comment (or @media statement) before the actual @charset atrule would
  5853. // be considered illegal css as it has to be on the first line
  5854. if (this.charset) {
  5855. if (atRuleNode.debugInfo) {
  5856. var comment = new tree.Comment("/* " + atRuleNode.toCSS(this._context).replace(/\n/g, '') + " */\n");
  5857. comment.debugInfo = atRuleNode.debugInfo;
  5858. return this._visitor.visit(comment);
  5859. }
  5860. return;
  5861. }
  5862. this.charset = true;
  5863. }
  5864. return atRuleNode;
  5865. },
  5866. checkValidNodes: function (rules, isRoot) {
  5867. if (!rules) {
  5868. return;
  5869. }
  5870. for (var i_1 = 0; i_1 < rules.length; i_1++) {
  5871. var ruleNode = rules[i_1];
  5872. if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) {
  5873. throw { message: 'Properties must be inside selector blocks. They cannot be in the root',
  5874. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  5875. }
  5876. if (ruleNode instanceof tree.Call) {
  5877. throw { message: "Function '" + ruleNode.name + "' is undefined",
  5878. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  5879. }
  5880. if (ruleNode.type && !ruleNode.allowRoot) {
  5881. throw { message: ruleNode.type + " node returned by a function is not valid here",
  5882. index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename };
  5883. }
  5884. }
  5885. },
  5886. visitRuleset: function (rulesetNode, visitArgs) {
  5887. // at this point rulesets are nested into each other
  5888. var rule;
  5889. var rulesets = [];
  5890. this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);
  5891. if (!rulesetNode.root) {
  5892. // remove invisible paths
  5893. this._compileRulesetPaths(rulesetNode);
  5894. // remove rulesets from this ruleset body and compile them separately
  5895. var nodeRules = rulesetNode.rules;
  5896. var nodeRuleCnt = nodeRules ? nodeRules.length : 0;
  5897. for (var i_2 = 0; i_2 < nodeRuleCnt;) {
  5898. rule = nodeRules[i_2];
  5899. if (rule && rule.rules) {
  5900. // visit because we are moving them out from being a child
  5901. rulesets.push(this._visitor.visit(rule));
  5902. nodeRules.splice(i_2, 1);
  5903. nodeRuleCnt--;
  5904. continue;
  5905. }
  5906. i_2++;
  5907. }
  5908. // accept the visitor to remove rules and refactor itself
  5909. // then we can decide nogw whether we want it or not
  5910. // compile body
  5911. if (nodeRuleCnt > 0) {
  5912. rulesetNode.accept(this._visitor);
  5913. }
  5914. else {
  5915. rulesetNode.rules = null;
  5916. }
  5917. visitArgs.visitDeeper = false;
  5918. }
  5919. else { // if (! rulesetNode.root) {
  5920. rulesetNode.accept(this._visitor);
  5921. visitArgs.visitDeeper = false;
  5922. }
  5923. if (rulesetNode.rules) {
  5924. this._mergeRules(rulesetNode.rules);
  5925. this._removeDuplicateRules(rulesetNode.rules);
  5926. }
  5927. // now decide whether we keep the ruleset
  5928. if (this.utils.isVisibleRuleset(rulesetNode)) {
  5929. rulesetNode.ensureVisibility();
  5930. rulesets.splice(0, 0, rulesetNode);
  5931. }
  5932. if (rulesets.length === 1) {
  5933. return rulesets[0];
  5934. }
  5935. return rulesets;
  5936. },
  5937. _compileRulesetPaths: function (rulesetNode) {
  5938. if (rulesetNode.paths) {
  5939. rulesetNode.paths = rulesetNode.paths
  5940. .filter(function (p) {
  5941. var i;
  5942. if (p[0].elements[0].combinator.value === ' ') {
  5943. p[0].elements[0].combinator = new (tree.Combinator)('');
  5944. }
  5945. for (i = 0; i < p.length; i++) {
  5946. if (p[i].isVisible() && p[i].getIsOutput()) {
  5947. return true;
  5948. }
  5949. }
  5950. return false;
  5951. });
  5952. }
  5953. },
  5954. _removeDuplicateRules: function (rules) {
  5955. if (!rules) {
  5956. return;
  5957. }
  5958. // remove duplicates
  5959. var ruleCache = {};
  5960. var ruleList;
  5961. var rule;
  5962. var i;
  5963. for (i = rules.length - 1; i >= 0; i--) {
  5964. rule = rules[i];
  5965. if (rule instanceof tree.Declaration) {
  5966. if (!ruleCache[rule.name]) {
  5967. ruleCache[rule.name] = rule;
  5968. }
  5969. else {
  5970. ruleList = ruleCache[rule.name];
  5971. if (ruleList instanceof tree.Declaration) {
  5972. ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];
  5973. }
  5974. var ruleCSS = rule.toCSS(this._context);
  5975. if (ruleList.indexOf(ruleCSS) !== -1) {
  5976. rules.splice(i, 1);
  5977. }
  5978. else {
  5979. ruleList.push(ruleCSS);
  5980. }
  5981. }
  5982. }
  5983. }
  5984. },
  5985. _mergeRules: function (rules) {
  5986. if (!rules) {
  5987. return;
  5988. }
  5989. var groups = {};
  5990. var groupsArr = [];
  5991. for (var i_3 = 0; i_3 < rules.length; i_3++) {
  5992. var rule = rules[i_3];
  5993. if (rule.merge) {
  5994. var key = rule.name;
  5995. groups[key] ? rules.splice(i_3--, 1) :
  5996. groupsArr.push(groups[key] = []);
  5997. groups[key].push(rule);
  5998. }
  5999. }
  6000. groupsArr.forEach(function (group) {
  6001. if (group.length > 0) {
  6002. var result_1 = group[0];
  6003. var space_1 = [];
  6004. var comma_1 = [new tree.Expression(space_1)];
  6005. group.forEach(function (rule) {
  6006. if ((rule.merge === '+') && (space_1.length > 0)) {
  6007. comma_1.push(new tree.Expression(space_1 = []));
  6008. }
  6009. space_1.push(rule.value);
  6010. result_1.important = result_1.important || rule.important;
  6011. });
  6012. result_1.value = new tree.Value(comma_1);
  6013. }
  6014. });
  6015. }
  6016. };
  6017. var visitors = {
  6018. Visitor: Visitor,
  6019. ImportVisitor: ImportVisitor,
  6020. MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor,
  6021. ExtendVisitor: ProcessExtendsVisitor,
  6022. JoinSelectorVisitor: JoinSelectorVisitor,
  6023. ToCSSVisitor: ToCSSVisitor
  6024. };
  6025. // Split the input into chunks.
  6026. var chunker = (function (input, fail) {
  6027. var len = input.length;
  6028. var level = 0;
  6029. var parenLevel = 0;
  6030. var lastOpening;
  6031. var lastOpeningParen;
  6032. var lastMultiComment;
  6033. var lastMultiCommentEndBrace;
  6034. var chunks = [];
  6035. var emitFrom = 0;
  6036. var chunkerCurrentIndex;
  6037. var currentChunkStartIndex;
  6038. var cc;
  6039. var cc2;
  6040. var matched;
  6041. function emitChunk(force) {
  6042. var len = chunkerCurrentIndex - emitFrom;
  6043. if (((len < 512) && !force) || !len) {
  6044. return;
  6045. }
  6046. chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
  6047. emitFrom = chunkerCurrentIndex + 1;
  6048. }
  6049. for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  6050. cc = input.charCodeAt(chunkerCurrentIndex);
  6051. if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
  6052. // a-z or whitespace
  6053. continue;
  6054. }
  6055. switch (cc) {
  6056. case 40: // (
  6057. parenLevel++;
  6058. lastOpeningParen = chunkerCurrentIndex;
  6059. continue;
  6060. case 41: // )
  6061. if (--parenLevel < 0) {
  6062. return fail('missing opening `(`', chunkerCurrentIndex);
  6063. }
  6064. continue;
  6065. case 59: // ;
  6066. if (!parenLevel) {
  6067. emitChunk();
  6068. }
  6069. continue;
  6070. case 123: // {
  6071. level++;
  6072. lastOpening = chunkerCurrentIndex;
  6073. continue;
  6074. case 125: // }
  6075. if (--level < 0) {
  6076. return fail('missing opening `{`', chunkerCurrentIndex);
  6077. }
  6078. if (!level && !parenLevel) {
  6079. emitChunk();
  6080. }
  6081. continue;
  6082. case 92: // \
  6083. if (chunkerCurrentIndex < len - 1) {
  6084. chunkerCurrentIndex++;
  6085. continue;
  6086. }
  6087. return fail('unescaped `\\`', chunkerCurrentIndex);
  6088. case 34:
  6089. case 39:
  6090. case 96: // ", ' and `
  6091. matched = 0;
  6092. currentChunkStartIndex = chunkerCurrentIndex;
  6093. for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  6094. cc2 = input.charCodeAt(chunkerCurrentIndex);
  6095. if (cc2 > 96) {
  6096. continue;
  6097. }
  6098. if (cc2 == cc) {
  6099. matched = 1;
  6100. break;
  6101. }
  6102. if (cc2 == 92) { // \
  6103. if (chunkerCurrentIndex == len - 1) {
  6104. return fail('unescaped `\\`', chunkerCurrentIndex);
  6105. }
  6106. chunkerCurrentIndex++;
  6107. }
  6108. }
  6109. if (matched) {
  6110. continue;
  6111. }
  6112. return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
  6113. case 47: // /, check for comment
  6114. if (parenLevel || (chunkerCurrentIndex == len - 1)) {
  6115. continue;
  6116. }
  6117. cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
  6118. if (cc2 == 47) {
  6119. // //, find lnfeed
  6120. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  6121. cc2 = input.charCodeAt(chunkerCurrentIndex);
  6122. if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) {
  6123. break;
  6124. }
  6125. }
  6126. }
  6127. else if (cc2 == 42) {
  6128. // /*, find */
  6129. lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
  6130. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
  6131. cc2 = input.charCodeAt(chunkerCurrentIndex);
  6132. if (cc2 == 125) {
  6133. lastMultiCommentEndBrace = chunkerCurrentIndex;
  6134. }
  6135. if (cc2 != 42) {
  6136. continue;
  6137. }
  6138. if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) {
  6139. break;
  6140. }
  6141. }
  6142. if (chunkerCurrentIndex == len - 1) {
  6143. return fail('missing closing `*/`', currentChunkStartIndex);
  6144. }
  6145. chunkerCurrentIndex++;
  6146. }
  6147. continue;
  6148. case 42: // *, check for unmatched */
  6149. if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
  6150. return fail('unmatched `/*`', chunkerCurrentIndex);
  6151. }
  6152. continue;
  6153. }
  6154. }
  6155. if (level !== 0) {
  6156. if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
  6157. return fail('missing closing `}` or `*/`', lastOpening);
  6158. }
  6159. else {
  6160. return fail('missing closing `}`', lastOpening);
  6161. }
  6162. }
  6163. else if (parenLevel !== 0) {
  6164. return fail('missing closing `)`', lastOpeningParen);
  6165. }
  6166. emitChunk(true);
  6167. return chunks;
  6168. });
  6169. var getParserInput = (function () {
  6170. var // Less input string
  6171. input;
  6172. var // current chunk
  6173. j;
  6174. var // holds state for backtracking
  6175. saveStack = [];
  6176. var // furthest index the parser has gone to
  6177. furthest;
  6178. var // if this is furthest we got to, this is the probably cause
  6179. furthestPossibleErrorMessage;
  6180. var // chunkified input
  6181. chunks;
  6182. var // current chunk
  6183. current;
  6184. var // index of current chunk, in `input`
  6185. currentPos;
  6186. var parserInput = {};
  6187. var CHARCODE_SPACE = 32;
  6188. var CHARCODE_TAB = 9;
  6189. var CHARCODE_LF = 10;
  6190. var CHARCODE_CR = 13;
  6191. var CHARCODE_PLUS = 43;
  6192. var CHARCODE_COMMA = 44;
  6193. var CHARCODE_FORWARD_SLASH = 47;
  6194. var CHARCODE_9 = 57;
  6195. function skipWhitespace(length) {
  6196. var oldi = parserInput.i;
  6197. var oldj = j;
  6198. var curr = parserInput.i - currentPos;
  6199. var endIndex = parserInput.i + current.length - curr;
  6200. var mem = (parserInput.i += length);
  6201. var inp = input;
  6202. var c;
  6203. var nextChar;
  6204. var comment;
  6205. for (; parserInput.i < endIndex; parserInput.i++) {
  6206. c = inp.charCodeAt(parserInput.i);
  6207. if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {
  6208. nextChar = inp.charAt(parserInput.i + 1);
  6209. if (nextChar === '/') {
  6210. comment = { index: parserInput.i, isLineComment: true };
  6211. var nextNewLine = inp.indexOf('\n', parserInput.i + 2);
  6212. if (nextNewLine < 0) {
  6213. nextNewLine = endIndex;
  6214. }
  6215. parserInput.i = nextNewLine;
  6216. comment.text = inp.substr(comment.index, parserInput.i - comment.index);
  6217. parserInput.commentStore.push(comment);
  6218. continue;
  6219. }
  6220. else if (nextChar === '*') {
  6221. var nextStarSlash = inp.indexOf('*/', parserInput.i + 2);
  6222. if (nextStarSlash >= 0) {
  6223. comment = {
  6224. index: parserInput.i,
  6225. text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
  6226. isLineComment: false
  6227. };
  6228. parserInput.i += comment.text.length - 1;
  6229. parserInput.commentStore.push(comment);
  6230. continue;
  6231. }
  6232. }
  6233. break;
  6234. }
  6235. if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {
  6236. break;
  6237. }
  6238. }
  6239. current = current.slice(length + parserInput.i - mem + curr);
  6240. currentPos = parserInput.i;
  6241. if (!current.length) {
  6242. if (j < chunks.length - 1) {
  6243. current = chunks[++j];
  6244. skipWhitespace(0); // skip space at the beginning of a chunk
  6245. return true; // things changed
  6246. }
  6247. parserInput.finished = true;
  6248. }
  6249. return oldi !== parserInput.i || oldj !== j;
  6250. }
  6251. parserInput.save = function () {
  6252. currentPos = parserInput.i;
  6253. saveStack.push({ current: current, i: parserInput.i, j: j });
  6254. };
  6255. parserInput.restore = function (possibleErrorMessage) {
  6256. if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {
  6257. furthest = parserInput.i;
  6258. furthestPossibleErrorMessage = possibleErrorMessage;
  6259. }
  6260. var state = saveStack.pop();
  6261. current = state.current;
  6262. currentPos = parserInput.i = state.i;
  6263. j = state.j;
  6264. };
  6265. parserInput.forget = function () {
  6266. saveStack.pop();
  6267. };
  6268. parserInput.isWhitespace = function (offset) {
  6269. var pos = parserInput.i + (offset || 0);
  6270. var code = input.charCodeAt(pos);
  6271. return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);
  6272. };
  6273. // Specialization of $(tok)
  6274. parserInput.$re = function (tok) {
  6275. if (parserInput.i > currentPos) {
  6276. current = current.slice(parserInput.i - currentPos);
  6277. currentPos = parserInput.i;
  6278. }
  6279. var m = tok.exec(current);
  6280. if (!m) {
  6281. return null;
  6282. }
  6283. skipWhitespace(m[0].length);
  6284. if (typeof m === 'string') {
  6285. return m;
  6286. }
  6287. return m.length === 1 ? m[0] : m;
  6288. };
  6289. parserInput.$char = function (tok) {
  6290. if (input.charAt(parserInput.i) !== tok) {
  6291. return null;
  6292. }
  6293. skipWhitespace(1);
  6294. return tok;
  6295. };
  6296. parserInput.$str = function (tok) {
  6297. var tokLength = tok.length;
  6298. // https://jsperf.com/string-startswith/21
  6299. for (var i_1 = 0; i_1 < tokLength; i_1++) {
  6300. if (input.charAt(parserInput.i + i_1) !== tok.charAt(i_1)) {
  6301. return null;
  6302. }
  6303. }
  6304. skipWhitespace(tokLength);
  6305. return tok;
  6306. };
  6307. parserInput.$quoted = function (loc) {
  6308. var pos = loc || parserInput.i;
  6309. var startChar = input.charAt(pos);
  6310. if (startChar !== '\'' && startChar !== '"') {
  6311. return;
  6312. }
  6313. var length = input.length;
  6314. var currentPosition = pos;
  6315. for (var i_2 = 1; i_2 + currentPosition < length; i_2++) {
  6316. var nextChar = input.charAt(i_2 + currentPosition);
  6317. switch (nextChar) {
  6318. case '\\':
  6319. i_2++;
  6320. continue;
  6321. case '\r':
  6322. case '\n':
  6323. break;
  6324. case startChar:
  6325. var str = input.substr(currentPosition, i_2 + 1);
  6326. if (!loc && loc !== 0) {
  6327. skipWhitespace(i_2 + 1);
  6328. return str;
  6329. }
  6330. return [startChar, str];
  6331. }
  6332. }
  6333. return null;
  6334. };
  6335. /**
  6336. * Permissive parsing. Ignores everything except matching {} [] () and quotes
  6337. * until matching token (outside of blocks)
  6338. */
  6339. parserInput.$parseUntil = function (tok) {
  6340. var quote = '';
  6341. var returnVal = null;
  6342. var inComment = false;
  6343. var blockDepth = 0;
  6344. var blockStack = [];
  6345. var parseGroups = [];
  6346. var length = input.length;
  6347. var startPos = parserInput.i;
  6348. var lastPos = parserInput.i;
  6349. var i = parserInput.i;
  6350. var loop = true;
  6351. var testChar;
  6352. if (typeof tok === 'string') {
  6353. testChar = function (char) { return char === tok; };
  6354. }
  6355. else {
  6356. testChar = function (char) { return tok.test(char); };
  6357. }
  6358. do {
  6359. var nextChar = input.charAt(i);
  6360. if (blockDepth === 0 && testChar(nextChar)) {
  6361. returnVal = input.substr(lastPos, i - lastPos);
  6362. if (returnVal) {
  6363. parseGroups.push(returnVal);
  6364. }
  6365. else {
  6366. parseGroups.push(' ');
  6367. }
  6368. returnVal = parseGroups;
  6369. skipWhitespace(i - startPos);
  6370. loop = false;
  6371. }
  6372. else {
  6373. if (inComment) {
  6374. if (nextChar === '*' &&
  6375. input.charAt(i + 1) === '/') {
  6376. i++;
  6377. blockDepth--;
  6378. inComment = false;
  6379. }
  6380. i++;
  6381. continue;
  6382. }
  6383. switch (nextChar) {
  6384. case '\\':
  6385. i++;
  6386. nextChar = input.charAt(i);
  6387. parseGroups.push(input.substr(lastPos, i - lastPos + 1));
  6388. lastPos = i + 1;
  6389. break;
  6390. case '/':
  6391. if (input.charAt(i + 1) === '*') {
  6392. i++;
  6393. inComment = true;
  6394. blockDepth++;
  6395. }
  6396. break;
  6397. case '\'':
  6398. case '"':
  6399. quote = parserInput.$quoted(i);
  6400. if (quote) {
  6401. parseGroups.push(input.substr(lastPos, i - lastPos), quote);
  6402. i += quote[1].length - 1;
  6403. lastPos = i + 1;
  6404. }
  6405. else {
  6406. skipWhitespace(i - startPos);
  6407. returnVal = nextChar;
  6408. loop = false;
  6409. }
  6410. break;
  6411. case '{':
  6412. blockStack.push('}');
  6413. blockDepth++;
  6414. break;
  6415. case '(':
  6416. blockStack.push(')');
  6417. blockDepth++;
  6418. break;
  6419. case '[':
  6420. blockStack.push(']');
  6421. blockDepth++;
  6422. break;
  6423. case '}':
  6424. case ')':
  6425. case ']':
  6426. var expected = blockStack.pop();
  6427. if (nextChar === expected) {
  6428. blockDepth--;
  6429. }
  6430. else {
  6431. // move the parser to the error and return expected
  6432. skipWhitespace(i - startPos);
  6433. returnVal = expected;
  6434. loop = false;
  6435. }
  6436. }
  6437. i++;
  6438. if (i > length) {
  6439. loop = false;
  6440. }
  6441. }
  6442. } while (loop);
  6443. return returnVal ? returnVal : null;
  6444. };
  6445. parserInput.autoCommentAbsorb = true;
  6446. parserInput.commentStore = [];
  6447. parserInput.finished = false;
  6448. // Same as $(), but don't change the state of the parser,
  6449. // just return the match.
  6450. parserInput.peek = function (tok) {
  6451. if (typeof tok === 'string') {
  6452. // https://jsperf.com/string-startswith/21
  6453. for (var i_3 = 0; i_3 < tok.length; i_3++) {
  6454. if (input.charAt(parserInput.i + i_3) !== tok.charAt(i_3)) {
  6455. return false;
  6456. }
  6457. }
  6458. return true;
  6459. }
  6460. else {
  6461. return tok.test(current);
  6462. }
  6463. };
  6464. // Specialization of peek()
  6465. // TODO remove or change some currentChar calls to peekChar
  6466. parserInput.peekChar = function (tok) { return input.charAt(parserInput.i) === tok; };
  6467. parserInput.currentChar = function () { return input.charAt(parserInput.i); };
  6468. parserInput.prevChar = function () { return input.charAt(parserInput.i - 1); };
  6469. parserInput.getInput = function () { return input; };
  6470. parserInput.peekNotNumeric = function () {
  6471. var c = input.charCodeAt(parserInput.i);
  6472. // Is the first char of the dimension 0-9, '.', '+' or '-'
  6473. return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;
  6474. };
  6475. parserInput.start = function (str, chunkInput, failFunction) {
  6476. input = str;
  6477. parserInput.i = j = currentPos = furthest = 0;
  6478. // chunking apparently makes things quicker (but my tests indicate
  6479. // it might actually make things slower in node at least)
  6480. // and it is a non-perfect parse - it can't recognise
  6481. // unquoted urls, meaning it can't distinguish comments
  6482. // meaning comments with quotes or {}() in them get 'counted'
  6483. // and then lead to parse errors.
  6484. // In addition if the chunking chunks in the wrong place we might
  6485. // not be able to parse a parser statement in one go
  6486. // this is officially deprecated but can be switched on via an option
  6487. // in the case it causes too much performance issues.
  6488. if (chunkInput) {
  6489. chunks = chunker(str, failFunction);
  6490. }
  6491. else {
  6492. chunks = [str];
  6493. }
  6494. current = chunks[0];
  6495. skipWhitespace(0);
  6496. };
  6497. parserInput.end = function () {
  6498. var message;
  6499. var isFinished = parserInput.i >= input.length;
  6500. if (parserInput.i < furthest) {
  6501. message = furthestPossibleErrorMessage;
  6502. parserInput.i = furthest;
  6503. }
  6504. return {
  6505. isFinished: isFinished,
  6506. furthest: parserInput.i,
  6507. furthestPossibleErrorMessage: message,
  6508. furthestReachedEnd: parserInput.i >= input.length - 1,
  6509. furthestChar: input[parserInput.i]
  6510. };
  6511. };
  6512. return parserInput;
  6513. });
  6514. //
  6515. // less.js - parser
  6516. //
  6517. // A relatively straight-forward predictive parser.
  6518. // There is no tokenization/lexing stage, the input is parsed
  6519. // in one sweep.
  6520. //
  6521. // To make the parser fast enough to run in the browser, several
  6522. // optimization had to be made:
  6523. //
  6524. // - Matching and slicing on a huge input is often cause of slowdowns.
  6525. // The solution is to chunkify the input into smaller strings.
  6526. // The chunks are stored in the `chunks` var,
  6527. // `j` holds the current chunk index, and `currentPos` holds
  6528. // the index of the current chunk in relation to `input`.
  6529. // This gives us an almost 4x speed-up.
  6530. //
  6531. // - In many cases, we don't need to match individual tokens;
  6532. // for example, if a value doesn't hold any variables, operations
  6533. // or dynamic references, the parser can effectively 'skip' it,
  6534. // treating it as a literal.
  6535. // An example would be '1px solid #000' - which evaluates to itself,
  6536. // we don't need to know what the individual components are.
  6537. // The drawback, of course is that you don't get the benefits of
  6538. // syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
  6539. // and a smaller speed-up in the code-gen.
  6540. //
  6541. //
  6542. // Token matching is done with the `$` function, which either takes
  6543. // a terminal string or regexp, or a non-terminal function to call.
  6544. // It also takes care of moving all the indices forwards.
  6545. //
  6546. var Parser = function Parser(context, imports, fileInfo) {
  6547. var parsers;
  6548. var parserInput = getParserInput();
  6549. function error(msg, type) {
  6550. throw new LessError({
  6551. index: parserInput.i,
  6552. filename: fileInfo.filename,
  6553. type: type || 'Syntax',
  6554. message: msg
  6555. }, imports);
  6556. }
  6557. function expect(arg, msg) {
  6558. // some older browsers return typeof 'function' for RegExp
  6559. var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
  6560. if (result) {
  6561. return result;
  6562. }
  6563. error(msg || (typeof arg === 'string'
  6564. ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'"
  6565. : 'unexpected token'));
  6566. }
  6567. // Specialization of expect()
  6568. function expectChar(arg, msg) {
  6569. if (parserInput.$char(arg)) {
  6570. return arg;
  6571. }
  6572. error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'");
  6573. }
  6574. function getDebugInfo(index) {
  6575. var filename = fileInfo.filename;
  6576. return {
  6577. lineNumber: getLocation(index, parserInput.getInput()).line + 1,
  6578. fileName: filename
  6579. };
  6580. }
  6581. /**
  6582. * Used after initial parsing to create nodes on the fly
  6583. *
  6584. * @param {String} str - string to parse
  6585. * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"]
  6586. * @param {Number} currentIndex - start number to begin indexing
  6587. * @param {Object} fileInfo - fileInfo to attach to created nodes
  6588. */
  6589. function parseNode(str, parseList, currentIndex, fileInfo, callback) {
  6590. var result;
  6591. var returnNodes = [];
  6592. var parser = parserInput;
  6593. try {
  6594. parser.start(str, false, function fail(msg, index) {
  6595. callback({
  6596. message: msg,
  6597. index: index + currentIndex
  6598. });
  6599. });
  6600. for (var x = 0, p = void 0, i_1; (p = parseList[x]); x++) {
  6601. i_1 = parser.i;
  6602. result = parsers[p]();
  6603. if (result) {
  6604. try {
  6605. result._index = i_1 + currentIndex;
  6606. result._fileInfo = fileInfo;
  6607. }
  6608. catch (e) { }
  6609. returnNodes.push(result);
  6610. }
  6611. else {
  6612. returnNodes.push(null);
  6613. }
  6614. }
  6615. var endInfo = parser.end();
  6616. if (endInfo.isFinished) {
  6617. callback(null, returnNodes);
  6618. }
  6619. else {
  6620. callback(true, null);
  6621. }
  6622. }
  6623. catch (e) {
  6624. throw new LessError({
  6625. index: e.index + currentIndex,
  6626. message: e.message
  6627. }, imports, fileInfo.filename);
  6628. }
  6629. }
  6630. //
  6631. // The Parser
  6632. //
  6633. return {
  6634. parserInput: parserInput,
  6635. imports: imports,
  6636. fileInfo: fileInfo,
  6637. parseNode: parseNode,
  6638. //
  6639. // Parse an input string into an abstract syntax tree,
  6640. // @param str A string containing 'less' markup
  6641. // @param callback call `callback` when done.
  6642. // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply
  6643. //
  6644. parse: function (str, callback, additionalData) {
  6645. var root;
  6646. var error = null;
  6647. var globalVars;
  6648. var modifyVars;
  6649. var ignored;
  6650. var preText = '';
  6651. globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + "\n" : '';
  6652. modifyVars = (additionalData && additionalData.modifyVars) ? "\n" + Parser.serializeVars(additionalData.modifyVars) : '';
  6653. if (context.pluginManager) {
  6654. var preProcessors = context.pluginManager.getPreProcessors();
  6655. for (var i_2 = 0; i_2 < preProcessors.length; i_2++) {
  6656. str = preProcessors[i_2].process(str, { context: context, imports: imports, fileInfo: fileInfo });
  6657. }
  6658. }
  6659. if (globalVars || (additionalData && additionalData.banner)) {
  6660. preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;
  6661. ignored = imports.contentsIgnoredChars;
  6662. ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
  6663. ignored[fileInfo.filename] += preText.length;
  6664. }
  6665. str = str.replace(/\r\n?/g, '\n');
  6666. // Remove potential UTF Byte Order Mark
  6667. str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
  6668. imports.contents[fileInfo.filename] = str;
  6669. // Start with the primary rule.
  6670. // The whole syntax tree is held under a Ruleset node,
  6671. // with the `root` property set to true, so no `{}` are
  6672. // output. The callback is called when the input is parsed.
  6673. try {
  6674. parserInput.start(str, context.chunkInput, function fail(msg, index) {
  6675. throw new LessError({
  6676. index: index,
  6677. type: 'Parse',
  6678. message: msg,
  6679. filename: fileInfo.filename
  6680. }, imports);
  6681. });
  6682. tree.Node.prototype.parse = this;
  6683. root = new tree.Ruleset(null, this.parsers.primary());
  6684. tree.Node.prototype.rootNode = root;
  6685. root.root = true;
  6686. root.firstRoot = true;
  6687. root.functionRegistry = functionRegistry.inherit();
  6688. }
  6689. catch (e) {
  6690. return callback(new LessError(e, imports, fileInfo.filename));
  6691. }
  6692. // If `i` is smaller than the `input.length - 1`,
  6693. // it means the parser wasn't able to parse the whole
  6694. // string, so we've got a parsing error.
  6695. //
  6696. // We try to extract a \n delimited string,
  6697. // showing the line where the parse error occurred.
  6698. // We split it up into two parts (the part which parsed,
  6699. // and the part which didn't), so we can color them differently.
  6700. var endInfo = parserInput.end();
  6701. if (!endInfo.isFinished) {
  6702. var message = endInfo.furthestPossibleErrorMessage;
  6703. if (!message) {
  6704. message = 'Unrecognised input';
  6705. if (endInfo.furthestChar === '}') {
  6706. message += '. Possibly missing opening \'{\'';
  6707. }
  6708. else if (endInfo.furthestChar === ')') {
  6709. message += '. Possibly missing opening \'(\'';
  6710. }
  6711. else if (endInfo.furthestReachedEnd) {
  6712. message += '. Possibly missing something';
  6713. }
  6714. }
  6715. error = new LessError({
  6716. type: 'Parse',
  6717. message: message,
  6718. index: endInfo.furthest,
  6719. filename: fileInfo.filename
  6720. }, imports);
  6721. }
  6722. var finish = function (e) {
  6723. e = error || e || imports.error;
  6724. if (e) {
  6725. if (!(e instanceof LessError)) {
  6726. e = new LessError(e, imports, fileInfo.filename);
  6727. }
  6728. return callback(e);
  6729. }
  6730. else {
  6731. return callback(null, root);
  6732. }
  6733. };
  6734. if (context.processImports !== false) {
  6735. new visitors.ImportVisitor(imports, finish)
  6736. .run(root);
  6737. }
  6738. else {
  6739. return finish();
  6740. }
  6741. },
  6742. //
  6743. // Here in, the parsing rules/functions
  6744. //
  6745. // The basic structure of the syntax tree generated is as follows:
  6746. //
  6747. // Ruleset -> Declaration -> Value -> Expression -> Entity
  6748. //
  6749. // Here's some Less code:
  6750. //
  6751. // .class {
  6752. // color: #fff;
  6753. // border: 1px solid #000;
  6754. // width: @w + 4px;
  6755. // > .child {...}
  6756. // }
  6757. //
  6758. // And here's what the parse tree might look like:
  6759. //
  6760. // Ruleset (Selector '.class', [
  6761. // Declaration ("color", Value ([Expression [Color #fff]]))
  6762. // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
  6763. // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]]))
  6764. // Ruleset (Selector [Element '>', '.child'], [...])
  6765. // ])
  6766. //
  6767. // In general, most rules will try to parse a token with the `$re()` function, and if the return
  6768. // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
  6769. // first, before parsing, that's when we use `peek()`.
  6770. //
  6771. parsers: parsers = {
  6772. //
  6773. // The `primary` rule is the *entry* and *exit* point of the parser.
  6774. // The rules here can appear at any level of the parse tree.
  6775. //
  6776. // The recursive nature of the grammar is an interplay between the `block`
  6777. // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
  6778. // as represented by this simplified grammar:
  6779. //
  6780. // primary → (ruleset | declaration)+
  6781. // ruleset → selector+ block
  6782. // block → '{' primary '}'
  6783. //
  6784. // Only at one point is the primary rule not called from the
  6785. // block rule: at the root level.
  6786. //
  6787. primary: function () {
  6788. var mixin = this.mixin;
  6789. var root = [];
  6790. var node;
  6791. while (true) {
  6792. while (true) {
  6793. node = this.comment();
  6794. if (!node) {
  6795. break;
  6796. }
  6797. root.push(node);
  6798. }
  6799. // always process comments before deciding if finished
  6800. if (parserInput.finished) {
  6801. break;
  6802. }
  6803. if (parserInput.peek('}')) {
  6804. break;
  6805. }
  6806. node = this.extendRule();
  6807. if (node) {
  6808. root = root.concat(node);
  6809. continue;
  6810. }
  6811. node = mixin.definition() || this.declaration() || mixin.call(false, false) ||
  6812. this.ruleset() || this.variableCall() || this.entities.call() || this.atrule();
  6813. if (node) {
  6814. root.push(node);
  6815. }
  6816. else {
  6817. var foundSemiColon = false;
  6818. while (parserInput.$char(';')) {
  6819. foundSemiColon = true;
  6820. }
  6821. if (!foundSemiColon) {
  6822. break;
  6823. }
  6824. }
  6825. }
  6826. return root;
  6827. },
  6828. // comments are collected by the main parsing mechanism and then assigned to nodes
  6829. // where the current structure allows it
  6830. comment: function () {
  6831. if (parserInput.commentStore.length) {
  6832. var comment = parserInput.commentStore.shift();
  6833. return new (tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);
  6834. }
  6835. },
  6836. //
  6837. // Entities are tokens which can be found inside an Expression
  6838. //
  6839. entities: {
  6840. mixinLookup: function () {
  6841. return parsers.mixin.call(true, true);
  6842. },
  6843. //
  6844. // A string, which supports escaping " and '
  6845. //
  6846. // "milky way" 'he\'s the one!'
  6847. //
  6848. quoted: function (forceEscaped) {
  6849. var str;
  6850. var index = parserInput.i;
  6851. var isEscaped = false;
  6852. parserInput.save();
  6853. if (parserInput.$char('~')) {
  6854. isEscaped = true;
  6855. }
  6856. else if (forceEscaped) {
  6857. parserInput.restore();
  6858. return;
  6859. }
  6860. str = parserInput.$quoted();
  6861. if (!str) {
  6862. parserInput.restore();
  6863. return;
  6864. }
  6865. parserInput.forget();
  6866. return new (tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);
  6867. },
  6868. //
  6869. // A catch-all word, such as:
  6870. //
  6871. // black border-collapse
  6872. //
  6873. keyword: function () {
  6874. var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/);
  6875. if (k) {
  6876. return tree.Color.fromKeyword(k) || new (tree.Keyword)(k);
  6877. }
  6878. },
  6879. //
  6880. // A function call
  6881. //
  6882. // rgb(255, 0, 255)
  6883. //
  6884. // The arguments are parsed with the `entities.arguments` parser.
  6885. //
  6886. call: function () {
  6887. var name;
  6888. var args;
  6889. var func;
  6890. var index = parserInput.i;
  6891. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  6892. if (parserInput.peek(/^url\(/i)) {
  6893. return;
  6894. }
  6895. parserInput.save();
  6896. name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/);
  6897. if (!name) {
  6898. parserInput.forget();
  6899. return;
  6900. }
  6901. name = name[1];
  6902. func = this.customFuncCall(name);
  6903. if (func) {
  6904. args = func.parse();
  6905. if (args && func.stop) {
  6906. parserInput.forget();
  6907. return args;
  6908. }
  6909. }
  6910. args = this.arguments(args);
  6911. if (!parserInput.$char(')')) {
  6912. parserInput.restore('Could not parse call arguments or missing \')\'');
  6913. return;
  6914. }
  6915. parserInput.forget();
  6916. return new (tree.Call)(name, args, index, fileInfo);
  6917. },
  6918. //
  6919. // Parsing rules for functions with non-standard args, e.g.:
  6920. //
  6921. // boolean(not(2 > 1))
  6922. //
  6923. // This is a quick prototype, to be modified/improved when
  6924. // more custom-parsed funcs come (e.g. `selector(...)`)
  6925. //
  6926. customFuncCall: function (name) {
  6927. /* Ideally the table is to be moved out of here for faster perf.,
  6928. but it's quite tricky since it relies on all these `parsers`
  6929. and `expect` available only here */
  6930. return {
  6931. alpha: f(parsers.ieAlpha, true),
  6932. boolean: f(condition),
  6933. 'if': f(condition)
  6934. }[name.toLowerCase()];
  6935. function f(parse, stop) {
  6936. return {
  6937. parse: parse,
  6938. stop: stop // when true - stop after parse() and return its result,
  6939. // otherwise continue for plain args
  6940. };
  6941. }
  6942. function condition() {
  6943. return [expect(parsers.condition, 'expected condition')];
  6944. }
  6945. },
  6946. arguments: function (prevArgs) {
  6947. var argsComma = prevArgs || [];
  6948. var argsSemiColon = [];
  6949. var isSemiColonSeparated;
  6950. var value;
  6951. parserInput.save();
  6952. while (true) {
  6953. if (prevArgs) {
  6954. prevArgs = false;
  6955. }
  6956. else {
  6957. value = parsers.detachedRuleset() || this.assignment() || parsers.expression();
  6958. if (!value) {
  6959. break;
  6960. }
  6961. if (value.value && value.value.length == 1) {
  6962. value = value.value[0];
  6963. }
  6964. argsComma.push(value);
  6965. }
  6966. if (parserInput.$char(',')) {
  6967. continue;
  6968. }
  6969. if (parserInput.$char(';') || isSemiColonSeparated) {
  6970. isSemiColonSeparated = true;
  6971. value = (argsComma.length < 1) ? argsComma[0]
  6972. : new tree.Value(argsComma);
  6973. argsSemiColon.push(value);
  6974. argsComma = [];
  6975. }
  6976. }
  6977. parserInput.forget();
  6978. return isSemiColonSeparated ? argsSemiColon : argsComma;
  6979. },
  6980. literal: function () {
  6981. return this.dimension() ||
  6982. this.color() ||
  6983. this.quoted() ||
  6984. this.unicodeDescriptor();
  6985. },
  6986. // Assignments are argument entities for calls.
  6987. // They are present in ie filter properties as shown below.
  6988. //
  6989. // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
  6990. //
  6991. assignment: function () {
  6992. var key;
  6993. var value;
  6994. parserInput.save();
  6995. key = parserInput.$re(/^\w+(?=\s?=)/i);
  6996. if (!key) {
  6997. parserInput.restore();
  6998. return;
  6999. }
  7000. if (!parserInput.$char('=')) {
  7001. parserInput.restore();
  7002. return;
  7003. }
  7004. value = parsers.entity();
  7005. if (value) {
  7006. parserInput.forget();
  7007. return new (tree.Assignment)(key, value);
  7008. }
  7009. else {
  7010. parserInput.restore();
  7011. }
  7012. },
  7013. //
  7014. // Parse url() tokens
  7015. //
  7016. // We use a specific rule for urls, because they don't really behave like
  7017. // standard function calls. The difference is that the argument doesn't have
  7018. // to be enclosed within a string, so it can't be parsed as an Expression.
  7019. //
  7020. url: function () {
  7021. var value;
  7022. var index = parserInput.i;
  7023. parserInput.autoCommentAbsorb = false;
  7024. if (!parserInput.$str('url(')) {
  7025. parserInput.autoCommentAbsorb = true;
  7026. return;
  7027. }
  7028. value = this.quoted() || this.variable() || this.property() ||
  7029. parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || '';
  7030. parserInput.autoCommentAbsorb = true;
  7031. expectChar(')');
  7032. return new (tree.URL)((value.value != null ||
  7033. value instanceof tree.Variable ||
  7034. value instanceof tree.Property) ?
  7035. value : new (tree.Anonymous)(value, index), index, fileInfo);
  7036. },
  7037. //
  7038. // A Variable entity, such as `@fink`, in
  7039. //
  7040. // width: @fink + 2px
  7041. //
  7042. // We use a different parser for variable definitions,
  7043. // see `parsers.variable`.
  7044. //
  7045. variable: function () {
  7046. var ch;
  7047. var name;
  7048. var index = parserInput.i;
  7049. parserInput.save();
  7050. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) {
  7051. ch = parserInput.currentChar();
  7052. if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) {
  7053. // this may be a VariableCall lookup
  7054. var result = parsers.variableCall(name);
  7055. if (result) {
  7056. parserInput.forget();
  7057. return result;
  7058. }
  7059. }
  7060. parserInput.forget();
  7061. return new (tree.Variable)(name, index, fileInfo);
  7062. }
  7063. parserInput.restore();
  7064. },
  7065. // A variable entity using the protective {} e.g. @{var}
  7066. variableCurly: function () {
  7067. var curly;
  7068. var index = parserInput.i;
  7069. if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) {
  7070. return new (tree.Variable)("@" + curly[1], index, fileInfo);
  7071. }
  7072. },
  7073. //
  7074. // A Property accessor, such as `$color`, in
  7075. //
  7076. // background-color: $color
  7077. //
  7078. property: function () {
  7079. var name;
  7080. var index = parserInput.i;
  7081. if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) {
  7082. return new (tree.Property)(name, index, fileInfo);
  7083. }
  7084. },
  7085. // A property entity useing the protective {} e.g. ${prop}
  7086. propertyCurly: function () {
  7087. var curly;
  7088. var index = parserInput.i;
  7089. if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) {
  7090. return new (tree.Property)("$" + curly[1], index, fileInfo);
  7091. }
  7092. },
  7093. //
  7094. // A Hexadecimal color
  7095. //
  7096. // #4F3C2F
  7097. //
  7098. // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
  7099. //
  7100. color: function () {
  7101. var rgb;
  7102. parserInput.save();
  7103. if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) {
  7104. if (!rgb[2]) {
  7105. parserInput.forget();
  7106. return new (tree.Color)(rgb[1], undefined, rgb[0]);
  7107. }
  7108. }
  7109. parserInput.restore();
  7110. },
  7111. colorKeyword: function () {
  7112. parserInput.save();
  7113. var autoCommentAbsorb = parserInput.autoCommentAbsorb;
  7114. parserInput.autoCommentAbsorb = false;
  7115. var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
  7116. parserInput.autoCommentAbsorb = autoCommentAbsorb;
  7117. if (!k) {
  7118. parserInput.forget();
  7119. return;
  7120. }
  7121. parserInput.restore();
  7122. var color = tree.Color.fromKeyword(k);
  7123. if (color) {
  7124. parserInput.$str(k);
  7125. return color;
  7126. }
  7127. },
  7128. //
  7129. // A Dimension, that is, a number and a unit
  7130. //
  7131. // 0.5em 95%
  7132. //
  7133. dimension: function () {
  7134. if (parserInput.peekNotNumeric()) {
  7135. return;
  7136. }
  7137. var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i);
  7138. if (value) {
  7139. return new (tree.Dimension)(value[1], value[2]);
  7140. }
  7141. },
  7142. //
  7143. // A unicode descriptor, as is used in unicode-range
  7144. //
  7145. // U+0?? or U+00A1-00A9
  7146. //
  7147. unicodeDescriptor: function () {
  7148. var ud;
  7149. ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/);
  7150. if (ud) {
  7151. return new (tree.UnicodeDescriptor)(ud[0]);
  7152. }
  7153. },
  7154. //
  7155. // JavaScript code to be evaluated
  7156. //
  7157. // `window.location.href`
  7158. //
  7159. javascript: function () {
  7160. var js;
  7161. var index = parserInput.i;
  7162. parserInput.save();
  7163. var escape = parserInput.$char('~');
  7164. var jsQuote = parserInput.$char('`');
  7165. if (!jsQuote) {
  7166. parserInput.restore();
  7167. return;
  7168. }
  7169. js = parserInput.$re(/^[^`]*`/);
  7170. if (js) {
  7171. parserInput.forget();
  7172. return new (tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);
  7173. }
  7174. parserInput.restore('invalid javascript definition');
  7175. }
  7176. },
  7177. //
  7178. // The variable part of a variable definition. Used in the `rule` parser
  7179. //
  7180. // @fink:
  7181. //
  7182. variable: function () {
  7183. var name;
  7184. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) {
  7185. return name[1];
  7186. }
  7187. },
  7188. //
  7189. // Call a variable value to retrieve a detached ruleset
  7190. // or a value from a detached ruleset's rules.
  7191. //
  7192. // @fink();
  7193. // @fink;
  7194. // color: @fink[@color];
  7195. //
  7196. variableCall: function (parsedName) {
  7197. var lookups;
  7198. var i = parserInput.i;
  7199. var inValue = !!parsedName;
  7200. var name = parsedName;
  7201. parserInput.save();
  7202. if (name || (parserInput.currentChar() === '@'
  7203. && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/)))) {
  7204. lookups = this.mixin.ruleLookups();
  7205. if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) {
  7206. parserInput.restore('Missing \'[...]\' lookup in variable call');
  7207. return;
  7208. }
  7209. if (!inValue) {
  7210. name = name[1];
  7211. }
  7212. var call = new tree.VariableCall(name, i, fileInfo);
  7213. if (!inValue && parsers.end()) {
  7214. parserInput.forget();
  7215. return call;
  7216. }
  7217. else {
  7218. parserInput.forget();
  7219. return new tree.NamespaceValue(call, lookups, i, fileInfo);
  7220. }
  7221. }
  7222. parserInput.restore();
  7223. },
  7224. //
  7225. // extend syntax - used to extend selectors
  7226. //
  7227. extend: function (isRule) {
  7228. var elements;
  7229. var e;
  7230. var index = parserInput.i;
  7231. var option;
  7232. var extendList;
  7233. var extend;
  7234. if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) {
  7235. return;
  7236. }
  7237. do {
  7238. option = null;
  7239. elements = null;
  7240. while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) {
  7241. e = this.element();
  7242. if (!e) {
  7243. break;
  7244. }
  7245. if (elements) {
  7246. elements.push(e);
  7247. }
  7248. else {
  7249. elements = [e];
  7250. }
  7251. }
  7252. option = option && option[1];
  7253. if (!elements) {
  7254. error('Missing target selector for :extend().');
  7255. }
  7256. extend = new (tree.Extend)(new (tree.Selector)(elements), option, index, fileInfo);
  7257. if (extendList) {
  7258. extendList.push(extend);
  7259. }
  7260. else {
  7261. extendList = [extend];
  7262. }
  7263. } while (parserInput.$char(','));
  7264. expect(/^\)/);
  7265. if (isRule) {
  7266. expect(/^;/);
  7267. }
  7268. return extendList;
  7269. },
  7270. //
  7271. // extendRule - used in a rule to extend all the parent selectors
  7272. //
  7273. extendRule: function () {
  7274. return this.extend(true);
  7275. },
  7276. //
  7277. // Mixins
  7278. //
  7279. mixin: {
  7280. //
  7281. // A Mixin call, with an optional argument list
  7282. //
  7283. // #mixins > .square(#fff);
  7284. // #mixins.square(#fff);
  7285. // .rounded(4px, black);
  7286. // .button;
  7287. //
  7288. // We can lookup / return a value using the lookup syntax:
  7289. //
  7290. // color: #mixin.square(#fff)[@color];
  7291. //
  7292. // The `while` loop is there because mixins can be
  7293. // namespaced, but we only support the child and descendant
  7294. // selector for now.
  7295. //
  7296. call: function (inValue, getLookup) {
  7297. var s = parserInput.currentChar();
  7298. var important = false;
  7299. var lookups;
  7300. var index = parserInput.i;
  7301. var elements;
  7302. var args;
  7303. var hasParens;
  7304. if (s !== '.' && s !== '#') {
  7305. return;
  7306. }
  7307. parserInput.save(); // stop us absorbing part of an invalid selector
  7308. elements = this.elements();
  7309. if (elements) {
  7310. if (parserInput.$char('(')) {
  7311. args = this.args(true).args;
  7312. expectChar(')');
  7313. hasParens = true;
  7314. }
  7315. if (getLookup !== false) {
  7316. lookups = this.ruleLookups();
  7317. }
  7318. if (getLookup === true && !lookups) {
  7319. parserInput.restore();
  7320. return;
  7321. }
  7322. if (inValue && !lookups && !hasParens) {
  7323. // This isn't a valid in-value mixin call
  7324. parserInput.restore();
  7325. return;
  7326. }
  7327. if (!inValue && parsers.important()) {
  7328. important = true;
  7329. }
  7330. if (inValue || parsers.end()) {
  7331. parserInput.forget();
  7332. var mixin = new (tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important);
  7333. if (lookups) {
  7334. return new tree.NamespaceValue(mixin, lookups);
  7335. }
  7336. else {
  7337. return mixin;
  7338. }
  7339. }
  7340. }
  7341. parserInput.restore();
  7342. },
  7343. /**
  7344. * Matching elements for mixins
  7345. * (Start with . or # and can have > )
  7346. */
  7347. elements: function () {
  7348. var elements;
  7349. var e;
  7350. var c;
  7351. var elem;
  7352. var elemIndex;
  7353. var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/;
  7354. while (true) {
  7355. elemIndex = parserInput.i;
  7356. e = parserInput.$re(re);
  7357. if (!e) {
  7358. break;
  7359. }
  7360. elem = new (tree.Element)(c, e, false, elemIndex, fileInfo);
  7361. if (elements) {
  7362. elements.push(elem);
  7363. }
  7364. else {
  7365. elements = [elem];
  7366. }
  7367. c = parserInput.$char('>');
  7368. }
  7369. return elements;
  7370. },
  7371. args: function (isCall) {
  7372. var entities = parsers.entities;
  7373. var returner = { args: null, variadic: false };
  7374. var expressions = [];
  7375. var argsSemiColon = [];
  7376. var argsComma = [];
  7377. var isSemiColonSeparated;
  7378. var expressionContainsNamed;
  7379. var name;
  7380. var nameLoop;
  7381. var value;
  7382. var arg;
  7383. var expand;
  7384. var hasSep = true;
  7385. parserInput.save();
  7386. while (true) {
  7387. if (isCall) {
  7388. arg = parsers.detachedRuleset() || parsers.expression();
  7389. }
  7390. else {
  7391. parserInput.commentStore.length = 0;
  7392. if (parserInput.$str('...')) {
  7393. returner.variadic = true;
  7394. if (parserInput.$char(';') && !isSemiColonSeparated) {
  7395. isSemiColonSeparated = true;
  7396. }
  7397. (isSemiColonSeparated ? argsSemiColon : argsComma)
  7398. .push({ variadic: true });
  7399. break;
  7400. }
  7401. arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true);
  7402. }
  7403. if (!arg || !hasSep) {
  7404. break;
  7405. }
  7406. nameLoop = null;
  7407. if (arg.throwAwayComments) {
  7408. arg.throwAwayComments();
  7409. }
  7410. value = arg;
  7411. var val = null;
  7412. if (isCall) {
  7413. // Variable
  7414. if (arg.value && arg.value.length == 1) {
  7415. val = arg.value[0];
  7416. }
  7417. }
  7418. else {
  7419. val = arg;
  7420. }
  7421. if (val && (val instanceof tree.Variable || val instanceof tree.Property)) {
  7422. if (parserInput.$char(':')) {
  7423. if (expressions.length > 0) {
  7424. if (isSemiColonSeparated) {
  7425. error('Cannot mix ; and , as delimiter types');
  7426. }
  7427. expressionContainsNamed = true;
  7428. }
  7429. value = parsers.detachedRuleset() || parsers.expression();
  7430. if (!value) {
  7431. if (isCall) {
  7432. error('could not understand value for named argument');
  7433. }
  7434. else {
  7435. parserInput.restore();
  7436. returner.args = [];
  7437. return returner;
  7438. }
  7439. }
  7440. nameLoop = (name = val.name);
  7441. }
  7442. else if (parserInput.$str('...')) {
  7443. if (!isCall) {
  7444. returner.variadic = true;
  7445. if (parserInput.$char(';') && !isSemiColonSeparated) {
  7446. isSemiColonSeparated = true;
  7447. }
  7448. (isSemiColonSeparated ? argsSemiColon : argsComma)
  7449. .push({ name: arg.name, variadic: true });
  7450. break;
  7451. }
  7452. else {
  7453. expand = true;
  7454. }
  7455. }
  7456. else if (!isCall) {
  7457. name = nameLoop = val.name;
  7458. value = null;
  7459. }
  7460. }
  7461. if (value) {
  7462. expressions.push(value);
  7463. }
  7464. argsComma.push({ name: nameLoop, value: value, expand: expand });
  7465. if (parserInput.$char(',')) {
  7466. hasSep = true;
  7467. continue;
  7468. }
  7469. hasSep = parserInput.$char(';') === ';';
  7470. if (hasSep || isSemiColonSeparated) {
  7471. if (expressionContainsNamed) {
  7472. error('Cannot mix ; and , as delimiter types');
  7473. }
  7474. isSemiColonSeparated = true;
  7475. if (expressions.length > 1) {
  7476. value = new (tree.Value)(expressions);
  7477. }
  7478. argsSemiColon.push({ name: name, value: value, expand: expand });
  7479. name = null;
  7480. expressions = [];
  7481. expressionContainsNamed = false;
  7482. }
  7483. }
  7484. parserInput.forget();
  7485. returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;
  7486. return returner;
  7487. },
  7488. //
  7489. // A Mixin definition, with a list of parameters
  7490. //
  7491. // .rounded (@radius: 2px, @color) {
  7492. // ...
  7493. // }
  7494. //
  7495. // Until we have a finer grained state-machine, we have to
  7496. // do a look-ahead, to make sure we don't have a mixin call.
  7497. // See the `rule` function for more information.
  7498. //
  7499. // We start by matching `.rounded (`, and then proceed on to
  7500. // the argument list, which has optional default values.
  7501. // We store the parameters in `params`, with a `value` key,
  7502. // if there is a value, such as in the case of `@radius`.
  7503. //
  7504. // Once we've got our params list, and a closing `)`, we parse
  7505. // the `{...}` block.
  7506. //
  7507. definition: function () {
  7508. var name;
  7509. var params = [];
  7510. var match;
  7511. var ruleset;
  7512. var cond;
  7513. var variadic = false;
  7514. if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||
  7515. parserInput.peek(/^[^{]*\}/)) {
  7516. return;
  7517. }
  7518. parserInput.save();
  7519. match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/);
  7520. if (match) {
  7521. name = match[1];
  7522. var argInfo = this.args(false);
  7523. params = argInfo.args;
  7524. variadic = argInfo.variadic;
  7525. // .mixincall("@{a}");
  7526. // looks a bit like a mixin definition..
  7527. // also
  7528. // .mixincall(@a: {rule: set;});
  7529. // so we have to be nice and restore
  7530. if (!parserInput.$char(')')) {
  7531. parserInput.restore('Missing closing \')\'');
  7532. return;
  7533. }
  7534. parserInput.commentStore.length = 0;
  7535. if (parserInput.$str('when')) { // Guard
  7536. cond = expect(parsers.conditions, 'expected condition');
  7537. }
  7538. ruleset = parsers.block();
  7539. if (ruleset) {
  7540. parserInput.forget();
  7541. return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic);
  7542. }
  7543. else {
  7544. parserInput.restore();
  7545. }
  7546. }
  7547. else {
  7548. parserInput.restore();
  7549. }
  7550. },
  7551. ruleLookups: function () {
  7552. var rule;
  7553. var lookups = [];
  7554. if (parserInput.currentChar() !== '[') {
  7555. return;
  7556. }
  7557. while (true) {
  7558. parserInput.save();
  7559. rule = this.lookupValue();
  7560. if (!rule && rule !== '') {
  7561. parserInput.restore();
  7562. break;
  7563. }
  7564. lookups.push(rule);
  7565. parserInput.forget();
  7566. }
  7567. if (lookups.length > 0) {
  7568. return lookups;
  7569. }
  7570. },
  7571. lookupValue: function () {
  7572. parserInput.save();
  7573. if (!parserInput.$char('[')) {
  7574. parserInput.restore();
  7575. return;
  7576. }
  7577. var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);
  7578. if (!parserInput.$char(']')) {
  7579. parserInput.restore();
  7580. return;
  7581. }
  7582. if (name || name === '') {
  7583. parserInput.forget();
  7584. return name;
  7585. }
  7586. parserInput.restore();
  7587. }
  7588. },
  7589. //
  7590. // Entities are the smallest recognized token,
  7591. // and can be found inside a rule's value.
  7592. //
  7593. entity: function () {
  7594. var entities = this.entities;
  7595. return this.comment() || entities.literal() || entities.variable() || entities.url() ||
  7596. entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) ||
  7597. entities.javascript();
  7598. },
  7599. //
  7600. // A Declaration terminator. Note that we use `peek()` to check for '}',
  7601. // because the `block` rule will be expecting it, but we still need to make sure
  7602. // it's there, if ';' was omitted.
  7603. //
  7604. end: function () {
  7605. return parserInput.$char(';') || parserInput.peek('}');
  7606. },
  7607. //
  7608. // IE's alpha function
  7609. //
  7610. // alpha(opacity=88)
  7611. //
  7612. ieAlpha: function () {
  7613. var value;
  7614. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  7615. if (!parserInput.$re(/^opacity=/i)) {
  7616. return;
  7617. }
  7618. value = parserInput.$re(/^\d+/);
  7619. if (!value) {
  7620. value = expect(parsers.entities.variable, 'Could not parse alpha');
  7621. value = "@{" + value.name.slice(1) + "}";
  7622. }
  7623. expectChar(')');
  7624. return new tree.Quoted('', "alpha(opacity=" + value + ")");
  7625. },
  7626. //
  7627. // A Selector Element
  7628. //
  7629. // div
  7630. // + h1
  7631. // #socks
  7632. // input[type="text"]
  7633. //
  7634. // Elements are the building blocks for Selectors,
  7635. // they are made out of a `Combinator` (see combinator rule),
  7636. // and an element name, such as a tag a class, or `*`.
  7637. //
  7638. element: function () {
  7639. var e;
  7640. var c;
  7641. var v;
  7642. var index = parserInput.i;
  7643. c = this.combinator();
  7644. e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
  7645. parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
  7646. parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
  7647. parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) ||
  7648. this.entities.variableCurly();
  7649. if (!e) {
  7650. parserInput.save();
  7651. if (parserInput.$char('(')) {
  7652. if ((v = this.selector(false)) && parserInput.$char(')')) {
  7653. e = new (tree.Paren)(v);
  7654. parserInput.forget();
  7655. }
  7656. else {
  7657. parserInput.restore('Missing closing \')\'');
  7658. }
  7659. }
  7660. else {
  7661. parserInput.forget();
  7662. }
  7663. }
  7664. if (e) {
  7665. return new (tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo);
  7666. }
  7667. },
  7668. //
  7669. // Combinators combine elements together, in a Selector.
  7670. //
  7671. // Because our parser isn't white-space sensitive, special care
  7672. // has to be taken, when parsing the descendant combinator, ` `,
  7673. // as it's an empty space. We have to check the previous character
  7674. // in the input, to see if it's a ` ` character. More info on how
  7675. // we deal with this in *combinator.js*.
  7676. //
  7677. combinator: function () {
  7678. var c = parserInput.currentChar();
  7679. if (c === '/') {
  7680. parserInput.save();
  7681. var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i);
  7682. if (slashedCombinator) {
  7683. parserInput.forget();
  7684. return new (tree.Combinator)(slashedCombinator);
  7685. }
  7686. parserInput.restore();
  7687. }
  7688. if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {
  7689. parserInput.i++;
  7690. if (c === '^' && parserInput.currentChar() === '^') {
  7691. c = '^^';
  7692. parserInput.i++;
  7693. }
  7694. while (parserInput.isWhitespace()) {
  7695. parserInput.i++;
  7696. }
  7697. return new (tree.Combinator)(c);
  7698. }
  7699. else if (parserInput.isWhitespace(-1)) {
  7700. return new (tree.Combinator)(' ');
  7701. }
  7702. else {
  7703. return new (tree.Combinator)(null);
  7704. }
  7705. },
  7706. //
  7707. // A CSS Selector
  7708. // with less extensions e.g. the ability to extend and guard
  7709. //
  7710. // .class > div + h1
  7711. // li a:hover
  7712. //
  7713. // Selectors are made out of one or more Elements, see above.
  7714. //
  7715. selector: function (isLess) {
  7716. var index = parserInput.i;
  7717. var elements;
  7718. var extendList;
  7719. var c;
  7720. var e;
  7721. var allExtends;
  7722. var when;
  7723. var condition;
  7724. isLess = isLess !== false;
  7725. while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) {
  7726. if (when) {
  7727. condition = expect(this.conditions, 'expected condition');
  7728. }
  7729. else if (condition) {
  7730. error('CSS guard can only be used at the end of selector');
  7731. }
  7732. else if (extendList) {
  7733. if (allExtends) {
  7734. allExtends = allExtends.concat(extendList);
  7735. }
  7736. else {
  7737. allExtends = extendList;
  7738. }
  7739. }
  7740. else {
  7741. if (allExtends) {
  7742. error('Extend can only be used at the end of selector');
  7743. }
  7744. c = parserInput.currentChar();
  7745. if (elements) {
  7746. elements.push(e);
  7747. }
  7748. else {
  7749. elements = [e];
  7750. }
  7751. e = null;
  7752. }
  7753. if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {
  7754. break;
  7755. }
  7756. }
  7757. if (elements) {
  7758. return new (tree.Selector)(elements, allExtends, condition, index, fileInfo);
  7759. }
  7760. if (allExtends) {
  7761. error('Extend must be used to extend a selector, it cannot be used on its own');
  7762. }
  7763. },
  7764. selectors: function () {
  7765. var s;
  7766. var selectors;
  7767. while (true) {
  7768. s = this.selector();
  7769. if (!s) {
  7770. break;
  7771. }
  7772. if (selectors) {
  7773. selectors.push(s);
  7774. }
  7775. else {
  7776. selectors = [s];
  7777. }
  7778. parserInput.commentStore.length = 0;
  7779. if (s.condition && selectors.length > 1) {
  7780. error("Guards are only currently allowed on a single selector.");
  7781. }
  7782. if (!parserInput.$char(',')) {
  7783. break;
  7784. }
  7785. if (s.condition) {
  7786. error("Guards are only currently allowed on a single selector.");
  7787. }
  7788. parserInput.commentStore.length = 0;
  7789. }
  7790. return selectors;
  7791. },
  7792. attribute: function () {
  7793. if (!parserInput.$char('[')) {
  7794. return;
  7795. }
  7796. var entities = this.entities;
  7797. var key;
  7798. var val;
  7799. var op;
  7800. if (!(key = entities.variableCurly())) {
  7801. key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
  7802. }
  7803. op = parserInput.$re(/^[|~*$^]?=/);
  7804. if (op) {
  7805. val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly();
  7806. }
  7807. expectChar(']');
  7808. return new (tree.Attribute)(key, op, val);
  7809. },
  7810. //
  7811. // The `block` rule is used by `ruleset` and `mixin.definition`.
  7812. // It's a wrapper around the `primary` rule, with added `{}`.
  7813. //
  7814. block: function () {
  7815. var content;
  7816. if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {
  7817. return content;
  7818. }
  7819. },
  7820. blockRuleset: function () {
  7821. var block = this.block();
  7822. if (block) {
  7823. block = new tree.Ruleset(null, block);
  7824. }
  7825. return block;
  7826. },
  7827. detachedRuleset: function () {
  7828. var argInfo;
  7829. var params;
  7830. var variadic;
  7831. parserInput.save();
  7832. if (parserInput.$re(/^[.#]\(/)) {
  7833. /**
  7834. * DR args currently only implemented for each() function, and not
  7835. * yet settable as `@dr: #(@arg) {}`
  7836. * This should be done when DRs are merged with mixins.
  7837. * See: https://github.com/less/less-meta/issues/16
  7838. */
  7839. argInfo = this.mixin.args(false);
  7840. params = argInfo.args;
  7841. variadic = argInfo.variadic;
  7842. if (!parserInput.$char(')')) {
  7843. parserInput.restore();
  7844. return;
  7845. }
  7846. }
  7847. var blockRuleset = this.blockRuleset();
  7848. if (blockRuleset) {
  7849. parserInput.forget();
  7850. if (params) {
  7851. return new tree.mixin.Definition(null, params, blockRuleset, null, variadic);
  7852. }
  7853. return new tree.DetachedRuleset(blockRuleset);
  7854. }
  7855. parserInput.restore();
  7856. },
  7857. //
  7858. // div, .class, body > p {...}
  7859. //
  7860. ruleset: function () {
  7861. var selectors;
  7862. var rules;
  7863. var debugInfo;
  7864. parserInput.save();
  7865. if (context.dumpLineNumbers) {
  7866. debugInfo = getDebugInfo(parserInput.i);
  7867. }
  7868. selectors = this.selectors();
  7869. if (selectors && (rules = this.block())) {
  7870. parserInput.forget();
  7871. var ruleset = new (tree.Ruleset)(selectors, rules, context.strictImports);
  7872. if (context.dumpLineNumbers) {
  7873. ruleset.debugInfo = debugInfo;
  7874. }
  7875. return ruleset;
  7876. }
  7877. else {
  7878. parserInput.restore();
  7879. }
  7880. },
  7881. declaration: function () {
  7882. var name;
  7883. var value;
  7884. var index = parserInput.i;
  7885. var hasDR;
  7886. var c = parserInput.currentChar();
  7887. var important;
  7888. var merge;
  7889. var isVariable;
  7890. if (c === '.' || c === '#' || c === '&' || c === ':') {
  7891. return;
  7892. }
  7893. parserInput.save();
  7894. name = this.variable() || this.ruleProperty();
  7895. if (name) {
  7896. isVariable = typeof name === 'string';
  7897. if (isVariable) {
  7898. value = this.detachedRuleset();
  7899. if (value) {
  7900. hasDR = true;
  7901. }
  7902. }
  7903. parserInput.commentStore.length = 0;
  7904. if (!value) {
  7905. // a name returned by this.ruleProperty() is always an array of the form:
  7906. // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
  7907. // where each item is a tree.Keyword or tree.Variable
  7908. merge = !isVariable && name.length > 1 && name.pop().value;
  7909. // Custom property values get permissive parsing
  7910. if (name[0].value && name[0].value.slice(0, 2) === '--') {
  7911. value = this.permissiveValue();
  7912. }
  7913. // Try to store values as anonymous
  7914. // If we need the value later we'll re-parse it in ruleset.parseValue
  7915. else {
  7916. value = this.anonymousValue();
  7917. }
  7918. if (value) {
  7919. parserInput.forget();
  7920. // anonymous values absorb the end ';' which is required for them to work
  7921. return new (tree.Declaration)(name, value, false, merge, index, fileInfo);
  7922. }
  7923. if (!value) {
  7924. value = this.value();
  7925. }
  7926. if (value) {
  7927. important = this.important();
  7928. }
  7929. else if (isVariable) {
  7930. // As a last resort, try permissiveValue
  7931. value = this.permissiveValue();
  7932. }
  7933. }
  7934. if (value && (this.end() || hasDR)) {
  7935. parserInput.forget();
  7936. return new (tree.Declaration)(name, value, important, merge, index, fileInfo);
  7937. }
  7938. else {
  7939. parserInput.restore();
  7940. }
  7941. }
  7942. else {
  7943. parserInput.restore();
  7944. }
  7945. },
  7946. anonymousValue: function () {
  7947. var index = parserInput.i;
  7948. var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/);
  7949. if (match) {
  7950. return new (tree.Anonymous)(match[1], index);
  7951. }
  7952. },
  7953. /**
  7954. * Used for custom properties, at-rules, and variables (as fallback)
  7955. * Parses almost anything inside of {} [] () "" blocks
  7956. * until it reaches outer-most tokens.
  7957. *
  7958. * First, it will try to parse comments and entities to reach
  7959. * the end. This is mostly like the Expression parser except no
  7960. * math is allowed.
  7961. */
  7962. permissiveValue: function (untilTokens) {
  7963. var i;
  7964. var e;
  7965. var done;
  7966. var value;
  7967. var tok = untilTokens || ';';
  7968. var index = parserInput.i;
  7969. var result = [];
  7970. function testCurrentChar() {
  7971. var char = parserInput.currentChar();
  7972. if (typeof tok === 'string') {
  7973. return char === tok;
  7974. }
  7975. else {
  7976. return tok.test(char);
  7977. }
  7978. }
  7979. if (testCurrentChar()) {
  7980. return;
  7981. }
  7982. value = [];
  7983. do {
  7984. e = this.comment();
  7985. if (e) {
  7986. value.push(e);
  7987. continue;
  7988. }
  7989. e = this.entity();
  7990. if (e) {
  7991. value.push(e);
  7992. }
  7993. } while (e);
  7994. done = testCurrentChar();
  7995. if (value.length > 0) {
  7996. value = new (tree.Expression)(value);
  7997. if (done) {
  7998. return value;
  7999. }
  8000. else {
  8001. result.push(value);
  8002. }
  8003. // Preserve space before $parseUntil as it will not
  8004. if (parserInput.prevChar() === ' ') {
  8005. result.push(new tree.Anonymous(' ', index));
  8006. }
  8007. }
  8008. parserInput.save();
  8009. value = parserInput.$parseUntil(tok);
  8010. if (value) {
  8011. if (typeof value === 'string') {
  8012. error("Expected '" + value + "'", 'Parse');
  8013. }
  8014. if (value.length === 1 && value[0] === ' ') {
  8015. parserInput.forget();
  8016. return new tree.Anonymous('', index);
  8017. }
  8018. var item = void 0;
  8019. for (i = 0; i < value.length; i++) {
  8020. item = value[i];
  8021. if (Array.isArray(item)) {
  8022. // Treat actual quotes as normal quoted values
  8023. result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));
  8024. }
  8025. else {
  8026. if (i === value.length - 1) {
  8027. item = item.trim();
  8028. }
  8029. // Treat like quoted values, but replace vars like unquoted expressions
  8030. var quote = new tree.Quoted('\'', item, true, index, fileInfo);
  8031. quote.variableRegex = /@([\w-]+)/g;
  8032. quote.propRegex = /\$([\w-]+)/g;
  8033. result.push(quote);
  8034. }
  8035. }
  8036. parserInput.forget();
  8037. return new tree.Expression(result, true);
  8038. }
  8039. parserInput.restore();
  8040. },
  8041. //
  8042. // An @import atrule
  8043. //
  8044. // @import "lib";
  8045. //
  8046. // Depending on our environment, importing is done differently:
  8047. // In the browser, it's an XHR request, in Node, it would be a
  8048. // file-system operation. The function used for importing is
  8049. // stored in `import`, which we pass to the Import constructor.
  8050. //
  8051. 'import': function () {
  8052. var path;
  8053. var features;
  8054. var index = parserInput.i;
  8055. var dir = parserInput.$re(/^@import?\s+/);
  8056. if (dir) {
  8057. var options_1 = (dir ? this.importOptions() : null) || {};
  8058. if ((path = this.entities.quoted() || this.entities.url())) {
  8059. features = this.mediaFeatures();
  8060. if (!parserInput.$char(';')) {
  8061. parserInput.i = index;
  8062. error('missing semi-colon or unrecognised media features on import');
  8063. }
  8064. features = features && new (tree.Value)(features);
  8065. return new (tree.Import)(path, features, options_1, index, fileInfo);
  8066. }
  8067. else {
  8068. parserInput.i = index;
  8069. error('malformed import statement');
  8070. }
  8071. }
  8072. },
  8073. importOptions: function () {
  8074. var o;
  8075. var options = {};
  8076. var optionName;
  8077. var value;
  8078. // list of options, surrounded by parens
  8079. if (!parserInput.$char('(')) {
  8080. return null;
  8081. }
  8082. do {
  8083. o = this.importOption();
  8084. if (o) {
  8085. optionName = o;
  8086. value = true;
  8087. switch (optionName) {
  8088. case 'css':
  8089. optionName = 'less';
  8090. value = false;
  8091. break;
  8092. case 'once':
  8093. optionName = 'multiple';
  8094. value = false;
  8095. break;
  8096. }
  8097. options[optionName] = value;
  8098. if (!parserInput.$char(',')) {
  8099. break;
  8100. }
  8101. }
  8102. } while (o);
  8103. expectChar(')');
  8104. return options;
  8105. },
  8106. importOption: function () {
  8107. var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);
  8108. if (opt) {
  8109. return opt[1];
  8110. }
  8111. },
  8112. mediaFeature: function () {
  8113. var entities = this.entities;
  8114. var nodes = [];
  8115. var e;
  8116. var p;
  8117. parserInput.save();
  8118. do {
  8119. e = entities.keyword() || entities.variable() || entities.mixinLookup();
  8120. if (e) {
  8121. nodes.push(e);
  8122. }
  8123. else if (parserInput.$char('(')) {
  8124. p = this.property();
  8125. e = this.value();
  8126. if (parserInput.$char(')')) {
  8127. if (p && e) {
  8128. nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true)));
  8129. }
  8130. else if (e) {
  8131. nodes.push(new (tree.Paren)(e));
  8132. }
  8133. else {
  8134. error('badly formed media feature definition');
  8135. }
  8136. }
  8137. else {
  8138. error('Missing closing \')\'', 'Parse');
  8139. }
  8140. }
  8141. } while (e);
  8142. parserInput.forget();
  8143. if (nodes.length > 0) {
  8144. return new (tree.Expression)(nodes);
  8145. }
  8146. },
  8147. mediaFeatures: function () {
  8148. var entities = this.entities;
  8149. var features = [];
  8150. var e;
  8151. do {
  8152. e = this.mediaFeature();
  8153. if (e) {
  8154. features.push(e);
  8155. if (!parserInput.$char(',')) {
  8156. break;
  8157. }
  8158. }
  8159. else {
  8160. e = entities.variable() || entities.mixinLookup();
  8161. if (e) {
  8162. features.push(e);
  8163. if (!parserInput.$char(',')) {
  8164. break;
  8165. }
  8166. }
  8167. }
  8168. } while (e);
  8169. return features.length > 0 ? features : null;
  8170. },
  8171. media: function () {
  8172. var features;
  8173. var rules;
  8174. var media;
  8175. var debugInfo;
  8176. var index = parserInput.i;
  8177. if (context.dumpLineNumbers) {
  8178. debugInfo = getDebugInfo(index);
  8179. }
  8180. parserInput.save();
  8181. if (parserInput.$str('@media')) {
  8182. features = this.mediaFeatures();
  8183. rules = this.block();
  8184. if (!rules) {
  8185. error('media definitions require block statements after any features');
  8186. }
  8187. parserInput.forget();
  8188. media = new (tree.Media)(rules, features, index, fileInfo);
  8189. if (context.dumpLineNumbers) {
  8190. media.debugInfo = debugInfo;
  8191. }
  8192. return media;
  8193. }
  8194. parserInput.restore();
  8195. },
  8196. //
  8197. // A @plugin directive, used to import plugins dynamically.
  8198. //
  8199. // @plugin (args) "lib";
  8200. //
  8201. plugin: function () {
  8202. var path;
  8203. var args;
  8204. var options;
  8205. var index = parserInput.i;
  8206. var dir = parserInput.$re(/^@plugin?\s+/);
  8207. if (dir) {
  8208. args = this.pluginArgs();
  8209. if (args) {
  8210. options = {
  8211. pluginArgs: args,
  8212. isPlugin: true
  8213. };
  8214. }
  8215. else {
  8216. options = { isPlugin: true };
  8217. }
  8218. if ((path = this.entities.quoted() || this.entities.url())) {
  8219. if (!parserInput.$char(';')) {
  8220. parserInput.i = index;
  8221. error('missing semi-colon on @plugin');
  8222. }
  8223. return new (tree.Import)(path, null, options, index, fileInfo);
  8224. }
  8225. else {
  8226. parserInput.i = index;
  8227. error('malformed @plugin statement');
  8228. }
  8229. }
  8230. },
  8231. pluginArgs: function () {
  8232. // list of options, surrounded by parens
  8233. parserInput.save();
  8234. if (!parserInput.$char('(')) {
  8235. parserInput.restore();
  8236. return null;
  8237. }
  8238. var args = parserInput.$re(/^\s*([^\);]+)\)\s*/);
  8239. if (args[1]) {
  8240. parserInput.forget();
  8241. return args[1].trim();
  8242. }
  8243. else {
  8244. parserInput.restore();
  8245. return null;
  8246. }
  8247. },
  8248. //
  8249. // A CSS AtRule
  8250. //
  8251. // @charset "utf-8";
  8252. //
  8253. atrule: function () {
  8254. var index = parserInput.i;
  8255. var name;
  8256. var value;
  8257. var rules;
  8258. var nonVendorSpecificName;
  8259. var hasIdentifier;
  8260. var hasExpression;
  8261. var hasUnknown;
  8262. var hasBlock = true;
  8263. var isRooted = true;
  8264. if (parserInput.currentChar() !== '@') {
  8265. return;
  8266. }
  8267. value = this['import']() || this.plugin() || this.media();
  8268. if (value) {
  8269. return value;
  8270. }
  8271. parserInput.save();
  8272. name = parserInput.$re(/^@[a-z-]+/);
  8273. if (!name) {
  8274. return;
  8275. }
  8276. nonVendorSpecificName = name;
  8277. if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
  8278. nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
  8279. }
  8280. switch (nonVendorSpecificName) {
  8281. case '@charset':
  8282. hasIdentifier = true;
  8283. hasBlock = false;
  8284. break;
  8285. case '@namespace':
  8286. hasExpression = true;
  8287. hasBlock = false;
  8288. break;
  8289. case '@keyframes':
  8290. case '@counter-style':
  8291. hasIdentifier = true;
  8292. break;
  8293. case '@document':
  8294. case '@supports':
  8295. hasUnknown = true;
  8296. isRooted = false;
  8297. break;
  8298. default:
  8299. hasUnknown = true;
  8300. break;
  8301. }
  8302. parserInput.commentStore.length = 0;
  8303. if (hasIdentifier) {
  8304. value = this.entity();
  8305. if (!value) {
  8306. error("expected " + name + " identifier");
  8307. }
  8308. }
  8309. else if (hasExpression) {
  8310. value = this.expression();
  8311. if (!value) {
  8312. error("expected " + name + " expression");
  8313. }
  8314. }
  8315. else if (hasUnknown) {
  8316. value = this.permissiveValue(/^[{;]/);
  8317. hasBlock = (parserInput.currentChar() === '{');
  8318. if (!value) {
  8319. if (!hasBlock && parserInput.currentChar() !== ';') {
  8320. error(name + " rule is missing block or ending semi-colon");
  8321. }
  8322. }
  8323. else if (!value.value) {
  8324. value = null;
  8325. }
  8326. }
  8327. if (hasBlock) {
  8328. rules = this.blockRuleset();
  8329. }
  8330. if (rules || (!hasBlock && value && parserInput.$char(';'))) {
  8331. parserInput.forget();
  8332. return new (tree.AtRule)(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted);
  8333. }
  8334. parserInput.restore('at-rule options not recognised');
  8335. },
  8336. //
  8337. // A Value is a comma-delimited list of Expressions
  8338. //
  8339. // font-family: Baskerville, Georgia, serif;
  8340. //
  8341. // In a Rule, a Value represents everything after the `:`,
  8342. // and before the `;`.
  8343. //
  8344. value: function () {
  8345. var e;
  8346. var expressions = [];
  8347. var index = parserInput.i;
  8348. do {
  8349. e = this.expression();
  8350. if (e) {
  8351. expressions.push(e);
  8352. if (!parserInput.$char(',')) {
  8353. break;
  8354. }
  8355. }
  8356. } while (e);
  8357. if (expressions.length > 0) {
  8358. return new (tree.Value)(expressions, index);
  8359. }
  8360. },
  8361. important: function () {
  8362. if (parserInput.currentChar() === '!') {
  8363. return parserInput.$re(/^! *important/);
  8364. }
  8365. },
  8366. sub: function () {
  8367. var a;
  8368. var e;
  8369. parserInput.save();
  8370. if (parserInput.$char('(')) {
  8371. a = this.addition();
  8372. if (a && parserInput.$char(')')) {
  8373. parserInput.forget();
  8374. e = new (tree.Expression)([a]);
  8375. e.parens = true;
  8376. return e;
  8377. }
  8378. parserInput.restore('Expected \')\'');
  8379. return;
  8380. }
  8381. parserInput.restore();
  8382. },
  8383. multiplication: function () {
  8384. var m;
  8385. var a;
  8386. var op;
  8387. var operation;
  8388. var isSpaced;
  8389. m = this.operand();
  8390. if (m) {
  8391. isSpaced = parserInput.isWhitespace(-1);
  8392. while (true) {
  8393. if (parserInput.peek(/^\/[*\/]/)) {
  8394. break;
  8395. }
  8396. parserInput.save();
  8397. op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./');
  8398. if (!op) {
  8399. parserInput.forget();
  8400. break;
  8401. }
  8402. a = this.operand();
  8403. if (!a) {
  8404. parserInput.restore();
  8405. break;
  8406. }
  8407. parserInput.forget();
  8408. m.parensInOp = true;
  8409. a.parensInOp = true;
  8410. operation = new (tree.Operation)(op, [operation || m, a], isSpaced);
  8411. isSpaced = parserInput.isWhitespace(-1);
  8412. }
  8413. return operation || m;
  8414. }
  8415. },
  8416. addition: function () {
  8417. var m;
  8418. var a;
  8419. var op;
  8420. var operation;
  8421. var isSpaced;
  8422. m = this.multiplication();
  8423. if (m) {
  8424. isSpaced = parserInput.isWhitespace(-1);
  8425. while (true) {
  8426. op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));
  8427. if (!op) {
  8428. break;
  8429. }
  8430. a = this.multiplication();
  8431. if (!a) {
  8432. break;
  8433. }
  8434. m.parensInOp = true;
  8435. a.parensInOp = true;
  8436. operation = new (tree.Operation)(op, [operation || m, a], isSpaced);
  8437. isSpaced = parserInput.isWhitespace(-1);
  8438. }
  8439. return operation || m;
  8440. }
  8441. },
  8442. conditions: function () {
  8443. var a;
  8444. var b;
  8445. var index = parserInput.i;
  8446. var condition;
  8447. a = this.condition(true);
  8448. if (a) {
  8449. while (true) {
  8450. if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) {
  8451. break;
  8452. }
  8453. b = this.condition(true);
  8454. if (!b) {
  8455. break;
  8456. }
  8457. condition = new (tree.Condition)('or', condition || a, b, index);
  8458. }
  8459. return condition || a;
  8460. }
  8461. },
  8462. condition: function (needsParens) {
  8463. var result;
  8464. var logical;
  8465. var next;
  8466. function or() {
  8467. return parserInput.$str('or');
  8468. }
  8469. result = this.conditionAnd(needsParens);
  8470. if (!result) {
  8471. return;
  8472. }
  8473. logical = or();
  8474. if (logical) {
  8475. next = this.condition(needsParens);
  8476. if (next) {
  8477. result = new (tree.Condition)(logical, result, next);
  8478. }
  8479. else {
  8480. return;
  8481. }
  8482. }
  8483. return result;
  8484. },
  8485. conditionAnd: function (needsParens) {
  8486. var result;
  8487. var logical;
  8488. var next;
  8489. var self = this;
  8490. function insideCondition() {
  8491. var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens);
  8492. if (!cond && !needsParens) {
  8493. return self.atomicCondition(needsParens);
  8494. }
  8495. return cond;
  8496. }
  8497. function and() {
  8498. return parserInput.$str('and');
  8499. }
  8500. result = insideCondition();
  8501. if (!result) {
  8502. return;
  8503. }
  8504. logical = and();
  8505. if (logical) {
  8506. next = this.conditionAnd(needsParens);
  8507. if (next) {
  8508. result = new (tree.Condition)(logical, result, next);
  8509. }
  8510. else {
  8511. return;
  8512. }
  8513. }
  8514. return result;
  8515. },
  8516. negatedCondition: function (needsParens) {
  8517. if (parserInput.$str('not')) {
  8518. var result = this.parenthesisCondition(needsParens);
  8519. if (result) {
  8520. result.negate = !result.negate;
  8521. }
  8522. return result;
  8523. }
  8524. },
  8525. parenthesisCondition: function (needsParens) {
  8526. function tryConditionFollowedByParenthesis(me) {
  8527. var body;
  8528. parserInput.save();
  8529. body = me.condition(needsParens);
  8530. if (!body) {
  8531. parserInput.restore();
  8532. return;
  8533. }
  8534. if (!parserInput.$char(')')) {
  8535. parserInput.restore();
  8536. return;
  8537. }
  8538. parserInput.forget();
  8539. return body;
  8540. }
  8541. var body;
  8542. parserInput.save();
  8543. if (!parserInput.$str('(')) {
  8544. parserInput.restore();
  8545. return;
  8546. }
  8547. body = tryConditionFollowedByParenthesis(this);
  8548. if (body) {
  8549. parserInput.forget();
  8550. return body;
  8551. }
  8552. body = this.atomicCondition(needsParens);
  8553. if (!body) {
  8554. parserInput.restore();
  8555. return;
  8556. }
  8557. if (!parserInput.$char(')')) {
  8558. parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'");
  8559. return;
  8560. }
  8561. parserInput.forget();
  8562. return body;
  8563. },
  8564. atomicCondition: function (needsParens) {
  8565. var entities = this.entities;
  8566. var index = parserInput.i;
  8567. var a;
  8568. var b;
  8569. var c;
  8570. var op;
  8571. function cond() {
  8572. return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();
  8573. }
  8574. cond = cond.bind(this);
  8575. a = cond();
  8576. if (a) {
  8577. if (parserInput.$char('>')) {
  8578. if (parserInput.$char('=')) {
  8579. op = '>=';
  8580. }
  8581. else {
  8582. op = '>';
  8583. }
  8584. }
  8585. else if (parserInput.$char('<')) {
  8586. if (parserInput.$char('=')) {
  8587. op = '<=';
  8588. }
  8589. else {
  8590. op = '<';
  8591. }
  8592. }
  8593. else if (parserInput.$char('=')) {
  8594. if (parserInput.$char('>')) {
  8595. op = '=>';
  8596. }
  8597. else if (parserInput.$char('<')) {
  8598. op = '=<';
  8599. }
  8600. else {
  8601. op = '=';
  8602. }
  8603. }
  8604. if (op) {
  8605. b = cond();
  8606. if (b) {
  8607. c = new (tree.Condition)(op, a, b, index, false);
  8608. }
  8609. else {
  8610. error('expected expression');
  8611. }
  8612. }
  8613. else {
  8614. c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index, false);
  8615. }
  8616. return c;
  8617. }
  8618. },
  8619. //
  8620. // An operand is anything that can be part of an operation,
  8621. // such as a Color, or a Variable
  8622. //
  8623. operand: function () {
  8624. var entities = this.entities;
  8625. var negate;
  8626. if (parserInput.peek(/^-[@\$\(]/)) {
  8627. negate = parserInput.$char('-');
  8628. }
  8629. var o = this.sub() || entities.dimension() ||
  8630. entities.color() || entities.variable() ||
  8631. entities.property() || entities.call() ||
  8632. entities.quoted(true) || entities.colorKeyword() ||
  8633. entities.mixinLookup();
  8634. if (negate) {
  8635. o.parensInOp = true;
  8636. o = new (tree.Negative)(o);
  8637. }
  8638. return o;
  8639. },
  8640. //
  8641. // Expressions either represent mathematical operations,
  8642. // or white-space delimited Entities.
  8643. //
  8644. // 1px solid black
  8645. // @var * 2
  8646. //
  8647. expression: function () {
  8648. var entities = [];
  8649. var e;
  8650. var delim;
  8651. var index = parserInput.i;
  8652. do {
  8653. e = this.comment();
  8654. if (e) {
  8655. entities.push(e);
  8656. continue;
  8657. }
  8658. e = this.addition() || this.entity();
  8659. if (e) {
  8660. entities.push(e);
  8661. // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here
  8662. if (!parserInput.peek(/^\/[\/*]/)) {
  8663. delim = parserInput.$char('/');
  8664. if (delim) {
  8665. entities.push(new (tree.Anonymous)(delim, index));
  8666. }
  8667. }
  8668. }
  8669. } while (e);
  8670. if (entities.length > 0) {
  8671. return new (tree.Expression)(entities);
  8672. }
  8673. },
  8674. property: function () {
  8675. var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);
  8676. if (name) {
  8677. return name[1];
  8678. }
  8679. },
  8680. ruleProperty: function () {
  8681. var name = [];
  8682. var index = [];
  8683. var s;
  8684. var k;
  8685. parserInput.save();
  8686. var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/);
  8687. if (simpleProperty) {
  8688. name = [new (tree.Keyword)(simpleProperty[1])];
  8689. parserInput.forget();
  8690. return name;
  8691. }
  8692. function match(re) {
  8693. var i = parserInput.i;
  8694. var chunk = parserInput.$re(re);
  8695. if (chunk) {
  8696. index.push(i);
  8697. return name.push(chunk[1]);
  8698. }
  8699. }
  8700. match(/^(\*?)/);
  8701. while (true) {
  8702. if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) {
  8703. break;
  8704. }
  8705. }
  8706. if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) {
  8707. parserInput.forget();
  8708. // at last, we have the complete match now. move forward,
  8709. // convert name particles to tree objects and return:
  8710. if (name[0] === '') {
  8711. name.shift();
  8712. index.shift();
  8713. }
  8714. for (k = 0; k < name.length; k++) {
  8715. s = name[k];
  8716. name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?
  8717. new (tree.Keyword)(s) :
  8718. (s.charAt(0) === '@' ?
  8719. new (tree.Variable)("@" + s.slice(2, -1), index[k], fileInfo) :
  8720. new (tree.Property)("$" + s.slice(2, -1), index[k], fileInfo));
  8721. }
  8722. return name;
  8723. }
  8724. parserInput.restore();
  8725. }
  8726. }
  8727. };
  8728. };
  8729. Parser.serializeVars = function (vars) {
  8730. var s = '';
  8731. for (var name_1 in vars) {
  8732. if (Object.hasOwnProperty.call(vars, name_1)) {
  8733. var value = vars[name_1];
  8734. s += ((name_1[0] === '@') ? '' : '@') + name_1 + ": " + value + ((String(value).slice(-1) === ';') ? '' : ';');
  8735. }
  8736. }
  8737. return s;
  8738. };
  8739. function boolean(condition) {
  8740. return condition ? Keyword.True : Keyword.False;
  8741. }
  8742. function If(condition, trueValue, falseValue) {
  8743. return condition ? trueValue
  8744. : (falseValue || new Anonymous);
  8745. }
  8746. var boolean$1 = { boolean: boolean, 'if': If };
  8747. var colorFunctions;
  8748. function clamp$1(val) {
  8749. return Math.min(1, Math.max(0, val));
  8750. }
  8751. function hsla(origColor, hsl) {
  8752. var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a);
  8753. if (color) {
  8754. if (origColor.value &&
  8755. /^(rgb|hsl)/.test(origColor.value)) {
  8756. color.value = origColor.value;
  8757. }
  8758. else {
  8759. color.value = 'rgb';
  8760. }
  8761. return color;
  8762. }
  8763. }
  8764. function toHSL(color) {
  8765. if (color.toHSL) {
  8766. return color.toHSL();
  8767. }
  8768. else {
  8769. throw new Error('Argument cannot be evaluated to a color');
  8770. }
  8771. }
  8772. function toHSV(color) {
  8773. if (color.toHSV) {
  8774. return color.toHSV();
  8775. }
  8776. else {
  8777. throw new Error('Argument cannot be evaluated to a color');
  8778. }
  8779. }
  8780. function number(n) {
  8781. if (n instanceof Dimension) {
  8782. return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);
  8783. }
  8784. else if (typeof n === 'number') {
  8785. return n;
  8786. }
  8787. else {
  8788. throw {
  8789. type: 'Argument',
  8790. message: 'color functions take numbers as parameters'
  8791. };
  8792. }
  8793. }
  8794. function scaled(n, size) {
  8795. if (n instanceof Dimension && n.unit.is('%')) {
  8796. return parseFloat(n.value * size / 100);
  8797. }
  8798. else {
  8799. return number(n);
  8800. }
  8801. }
  8802. colorFunctions = {
  8803. rgb: function (r, g, b) {
  8804. var color = colorFunctions.rgba(r, g, b, 1.0);
  8805. if (color) {
  8806. color.value = 'rgb';
  8807. return color;
  8808. }
  8809. },
  8810. rgba: function (r, g, b, a) {
  8811. try {
  8812. if (r instanceof Color) {
  8813. if (g) {
  8814. a = number(g);
  8815. }
  8816. else {
  8817. a = r.alpha;
  8818. }
  8819. return new Color(r.rgb, a, 'rgba');
  8820. }
  8821. var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });
  8822. a = number(a);
  8823. return new Color(rgb, a, 'rgba');
  8824. }
  8825. catch (e) { }
  8826. },
  8827. hsl: function (h, s, l) {
  8828. var color = colorFunctions.hsla(h, s, l, 1.0);
  8829. if (color) {
  8830. color.value = 'hsl';
  8831. return color;
  8832. }
  8833. },
  8834. hsla: function (h, s, l, a) {
  8835. try {
  8836. if (h instanceof Color) {
  8837. if (s) {
  8838. a = number(s);
  8839. }
  8840. else {
  8841. a = h.alpha;
  8842. }
  8843. return new Color(h.rgb, a, 'hsla');
  8844. }
  8845. var m1_1;
  8846. var m2_1;
  8847. function hue(h) {
  8848. h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
  8849. if (h * 6 < 1) {
  8850. return m1_1 + (m2_1 - m1_1) * h * 6;
  8851. }
  8852. else if (h * 2 < 1) {
  8853. return m2_1;
  8854. }
  8855. else if (h * 3 < 2) {
  8856. return m1_1 + (m2_1 - m1_1) * (2 / 3 - h) * 6;
  8857. }
  8858. else {
  8859. return m1_1;
  8860. }
  8861. }
  8862. h = (number(h) % 360) / 360;
  8863. s = clamp$1(number(s));
  8864. l = clamp$1(number(l));
  8865. a = clamp$1(number(a));
  8866. m2_1 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  8867. m1_1 = l * 2 - m2_1;
  8868. var rgb = [
  8869. hue(h + 1 / 3) * 255,
  8870. hue(h) * 255,
  8871. hue(h - 1 / 3) * 255
  8872. ];
  8873. a = number(a);
  8874. return new Color(rgb, a, 'hsla');
  8875. }
  8876. catch (e) { }
  8877. },
  8878. hsv: function (h, s, v) {
  8879. return colorFunctions.hsva(h, s, v, 1.0);
  8880. },
  8881. hsva: function (h, s, v, a) {
  8882. h = ((number(h) % 360) / 360) * 360;
  8883. s = number(s);
  8884. v = number(v);
  8885. a = number(a);
  8886. var i;
  8887. var f;
  8888. i = Math.floor((h / 60) % 6);
  8889. f = (h / 60) - i;
  8890. var vs = [v,
  8891. v * (1 - s),
  8892. v * (1 - f * s),
  8893. v * (1 - (1 - f) * s)];
  8894. var perm = [[0, 3, 1],
  8895. [2, 0, 1],
  8896. [1, 0, 3],
  8897. [1, 2, 0],
  8898. [3, 1, 0],
  8899. [0, 1, 2]];
  8900. return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a);
  8901. },
  8902. hue: function (color) {
  8903. return new Dimension(toHSL(color).h);
  8904. },
  8905. saturation: function (color) {
  8906. return new Dimension(toHSL(color).s * 100, '%');
  8907. },
  8908. lightness: function (color) {
  8909. return new Dimension(toHSL(color).l * 100, '%');
  8910. },
  8911. hsvhue: function (color) {
  8912. return new Dimension(toHSV(color).h);
  8913. },
  8914. hsvsaturation: function (color) {
  8915. return new Dimension(toHSV(color).s * 100, '%');
  8916. },
  8917. hsvvalue: function (color) {
  8918. return new Dimension(toHSV(color).v * 100, '%');
  8919. },
  8920. red: function (color) {
  8921. return new Dimension(color.rgb[0]);
  8922. },
  8923. green: function (color) {
  8924. return new Dimension(color.rgb[1]);
  8925. },
  8926. blue: function (color) {
  8927. return new Dimension(color.rgb[2]);
  8928. },
  8929. alpha: function (color) {
  8930. return new Dimension(toHSL(color).a);
  8931. },
  8932. luma: function (color) {
  8933. return new Dimension(color.luma() * color.alpha * 100, '%');
  8934. },
  8935. luminance: function (color) {
  8936. var luminance = (0.2126 * color.rgb[0] / 255) +
  8937. (0.7152 * color.rgb[1] / 255) +
  8938. (0.0722 * color.rgb[2] / 255);
  8939. return new Dimension(luminance * color.alpha * 100, '%');
  8940. },
  8941. saturate: function (color, amount, method) {
  8942. // filter: saturate(3.2);
  8943. // should be kept as is, so check for color
  8944. if (!color.rgb) {
  8945. return null;
  8946. }
  8947. var hsl = toHSL(color);
  8948. if (typeof method !== 'undefined' && method.value === 'relative') {
  8949. hsl.s += hsl.s * amount.value / 100;
  8950. }
  8951. else {
  8952. hsl.s += amount.value / 100;
  8953. }
  8954. hsl.s = clamp$1(hsl.s);
  8955. return hsla(color, hsl);
  8956. },
  8957. desaturate: function (color, amount, method) {
  8958. var hsl = toHSL(color);
  8959. if (typeof method !== 'undefined' && method.value === 'relative') {
  8960. hsl.s -= hsl.s * amount.value / 100;
  8961. }
  8962. else {
  8963. hsl.s -= amount.value / 100;
  8964. }
  8965. hsl.s = clamp$1(hsl.s);
  8966. return hsla(color, hsl);
  8967. },
  8968. lighten: function (color, amount, method) {
  8969. var hsl = toHSL(color);
  8970. if (typeof method !== 'undefined' && method.value === 'relative') {
  8971. hsl.l += hsl.l * amount.value / 100;
  8972. }
  8973. else {
  8974. hsl.l += amount.value / 100;
  8975. }
  8976. hsl.l = clamp$1(hsl.l);
  8977. return hsla(color, hsl);
  8978. },
  8979. darken: function (color, amount, method) {
  8980. var hsl = toHSL(color);
  8981. if (typeof method !== 'undefined' && method.value === 'relative') {
  8982. hsl.l -= hsl.l * amount.value / 100;
  8983. }
  8984. else {
  8985. hsl.l -= amount.value / 100;
  8986. }
  8987. hsl.l = clamp$1(hsl.l);
  8988. return hsla(color, hsl);
  8989. },
  8990. fadein: function (color, amount, method) {
  8991. var hsl = toHSL(color);
  8992. if (typeof method !== 'undefined' && method.value === 'relative') {
  8993. hsl.a += hsl.a * amount.value / 100;
  8994. }
  8995. else {
  8996. hsl.a += amount.value / 100;
  8997. }
  8998. hsl.a = clamp$1(hsl.a);
  8999. return hsla(color, hsl);
  9000. },
  9001. fadeout: function (color, amount, method) {
  9002. var hsl = toHSL(color);
  9003. if (typeof method !== 'undefined' && method.value === 'relative') {
  9004. hsl.a -= hsl.a * amount.value / 100;
  9005. }
  9006. else {
  9007. hsl.a -= amount.value / 100;
  9008. }
  9009. hsl.a = clamp$1(hsl.a);
  9010. return hsla(color, hsl);
  9011. },
  9012. fade: function (color, amount) {
  9013. var hsl = toHSL(color);
  9014. hsl.a = amount.value / 100;
  9015. hsl.a = clamp$1(hsl.a);
  9016. return hsla(color, hsl);
  9017. },
  9018. spin: function (color, amount) {
  9019. var hsl = toHSL(color);
  9020. var hue = (hsl.h + amount.value) % 360;
  9021. hsl.h = hue < 0 ? 360 + hue : hue;
  9022. return hsla(color, hsl);
  9023. },
  9024. //
  9025. // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
  9026. // http://sass-lang.com
  9027. //
  9028. mix: function (color1, color2, weight) {
  9029. if (!weight) {
  9030. weight = new Dimension(50);
  9031. }
  9032. var p = weight.value / 100.0;
  9033. var w = p * 2 - 1;
  9034. var a = toHSL(color1).a - toHSL(color2).a;
  9035. var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
  9036. var w2 = 1 - w1;
  9037. var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
  9038. color1.rgb[1] * w1 + color2.rgb[1] * w2,
  9039. color1.rgb[2] * w1 + color2.rgb[2] * w2];
  9040. var alpha = color1.alpha * p + color2.alpha * (1 - p);
  9041. return new Color(rgb, alpha);
  9042. },
  9043. greyscale: function (color) {
  9044. return colorFunctions.desaturate(color, new Dimension(100));
  9045. },
  9046. contrast: function (color, dark, light, threshold) {
  9047. // filter: contrast(3.2);
  9048. // should be kept as is, so check for color
  9049. if (!color.rgb) {
  9050. return null;
  9051. }
  9052. if (typeof light === 'undefined') {
  9053. light = colorFunctions.rgba(255, 255, 255, 1.0);
  9054. }
  9055. if (typeof dark === 'undefined') {
  9056. dark = colorFunctions.rgba(0, 0, 0, 1.0);
  9057. }
  9058. // Figure out which is actually light and dark:
  9059. if (dark.luma() > light.luma()) {
  9060. var t = light;
  9061. light = dark;
  9062. dark = t;
  9063. }
  9064. if (typeof threshold === 'undefined') {
  9065. threshold = 0.43;
  9066. }
  9067. else {
  9068. threshold = number(threshold);
  9069. }
  9070. if (color.luma() < threshold) {
  9071. return light;
  9072. }
  9073. else {
  9074. return dark;
  9075. }
  9076. },
  9077. // Changes made in 2.7.0 - Reverted in 3.0.0
  9078. // contrast: function (color, color1, color2, threshold) {
  9079. // // Return which of `color1` and `color2` has the greatest contrast with `color`
  9080. // // according to the standard WCAG contrast ratio calculation.
  9081. // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef
  9082. // // The threshold param is no longer used, in line with SASS.
  9083. // // filter: contrast(3.2);
  9084. // // should be kept as is, so check for color
  9085. // if (!color.rgb) {
  9086. // return null;
  9087. // }
  9088. // if (typeof color1 === 'undefined') {
  9089. // color1 = colorFunctions.rgba(0, 0, 0, 1.0);
  9090. // }
  9091. // if (typeof color2 === 'undefined') {
  9092. // color2 = colorFunctions.rgba(255, 255, 255, 1.0);
  9093. // }
  9094. // var contrast1, contrast2;
  9095. // var luma = color.luma();
  9096. // var luma1 = color1.luma();
  9097. // var luma2 = color2.luma();
  9098. // // Calculate contrast ratios for each color
  9099. // if (luma > luma1) {
  9100. // contrast1 = (luma + 0.05) / (luma1 + 0.05);
  9101. // } else {
  9102. // contrast1 = (luma1 + 0.05) / (luma + 0.05);
  9103. // }
  9104. // if (luma > luma2) {
  9105. // contrast2 = (luma + 0.05) / (luma2 + 0.05);
  9106. // } else {
  9107. // contrast2 = (luma2 + 0.05) / (luma + 0.05);
  9108. // }
  9109. // if (contrast1 > contrast2) {
  9110. // return color1;
  9111. // } else {
  9112. // return color2;
  9113. // }
  9114. // },
  9115. argb: function (color) {
  9116. return new Anonymous(color.toARGB());
  9117. },
  9118. color: function (c) {
  9119. if ((c instanceof Quoted) &&
  9120. (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) {
  9121. var val = c.value.slice(1);
  9122. return new Color(val, undefined, "#" + val);
  9123. }
  9124. if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {
  9125. c.value = undefined;
  9126. return c;
  9127. }
  9128. throw {
  9129. type: 'Argument',
  9130. message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF'
  9131. };
  9132. },
  9133. tint: function (color, amount) {
  9134. return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);
  9135. },
  9136. shade: function (color, amount) {
  9137. return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);
  9138. }
  9139. };
  9140. var color = colorFunctions;
  9141. // Color Blending
  9142. // ref: http://www.w3.org/TR/compositing-1
  9143. function colorBlend(mode, color1, color2) {
  9144. var ab = color1.alpha; // result
  9145. var // backdrop
  9146. cb;
  9147. var as = color2.alpha;
  9148. var // source
  9149. cs;
  9150. var ar;
  9151. var cr;
  9152. var r = [];
  9153. ar = as + ab * (1 - as);
  9154. for (var i_1 = 0; i_1 < 3; i_1++) {
  9155. cb = color1.rgb[i_1] / 255;
  9156. cs = color2.rgb[i_1] / 255;
  9157. cr = mode(cb, cs);
  9158. if (ar) {
  9159. cr = (as * cs + ab * (cb -
  9160. as * (cb + cs - cr))) / ar;
  9161. }
  9162. r[i_1] = cr * 255;
  9163. }
  9164. return new Color(r, ar);
  9165. }
  9166. var colorBlendModeFunctions = {
  9167. multiply: function (cb, cs) {
  9168. return cb * cs;
  9169. },
  9170. screen: function (cb, cs) {
  9171. return cb + cs - cb * cs;
  9172. },
  9173. overlay: function (cb, cs) {
  9174. cb *= 2;
  9175. return (cb <= 1) ?
  9176. colorBlendModeFunctions.multiply(cb, cs) :
  9177. colorBlendModeFunctions.screen(cb - 1, cs);
  9178. },
  9179. softlight: function (cb, cs) {
  9180. var d = 1;
  9181. var e = cb;
  9182. if (cs > 0.5) {
  9183. e = 1;
  9184. d = (cb > 0.25) ? Math.sqrt(cb)
  9185. : ((16 * cb - 12) * cb + 4) * cb;
  9186. }
  9187. return cb - (1 - 2 * cs) * e * (d - cb);
  9188. },
  9189. hardlight: function (cb, cs) {
  9190. return colorBlendModeFunctions.overlay(cs, cb);
  9191. },
  9192. difference: function (cb, cs) {
  9193. return Math.abs(cb - cs);
  9194. },
  9195. exclusion: function (cb, cs) {
  9196. return cb + cs - 2 * cb * cs;
  9197. },
  9198. // non-w3c functions:
  9199. average: function (cb, cs) {
  9200. return (cb + cs) / 2;
  9201. },
  9202. negation: function (cb, cs) {
  9203. return 1 - Math.abs(cb + cs - 1);
  9204. }
  9205. };
  9206. for (var f in colorBlendModeFunctions) {
  9207. if (colorBlendModeFunctions.hasOwnProperty(f)) {
  9208. colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]);
  9209. }
  9210. }
  9211. var dataUri = (function (environment) {
  9212. var fallback = function (functionThis, node) { return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); };
  9213. return { 'data-uri': function (mimetypeNode, filePathNode) {
  9214. if (!filePathNode) {
  9215. filePathNode = mimetypeNode;
  9216. mimetypeNode = null;
  9217. }
  9218. var mimetype = mimetypeNode && mimetypeNode.value;
  9219. var filePath = filePathNode.value;
  9220. var currentFileInfo = this.currentFileInfo;
  9221. var currentDirectory = currentFileInfo.rewriteUrls ?
  9222. currentFileInfo.currentDirectory : currentFileInfo.entryPath;
  9223. var fragmentStart = filePath.indexOf('#');
  9224. var fragment = '';
  9225. if (fragmentStart !== -1) {
  9226. fragment = filePath.slice(fragmentStart);
  9227. filePath = filePath.slice(0, fragmentStart);
  9228. }
  9229. var context = clone(this.context);
  9230. context.rawBuffer = true;
  9231. var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true);
  9232. if (!fileManager) {
  9233. return fallback(this, filePathNode);
  9234. }
  9235. var useBase64 = false;
  9236. // detect the mimetype if not given
  9237. if (!mimetypeNode) {
  9238. mimetype = environment.mimeLookup(filePath);
  9239. if (mimetype === 'image/svg+xml') {
  9240. useBase64 = false;
  9241. }
  9242. else {
  9243. // use base 64 unless it's an ASCII or UTF-8 format
  9244. var charset = environment.charsetLookup(mimetype);
  9245. useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
  9246. }
  9247. if (useBase64) {
  9248. mimetype += ';base64';
  9249. }
  9250. }
  9251. else {
  9252. useBase64 = /;base64$/.test(mimetype);
  9253. }
  9254. var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);
  9255. if (!fileSync.contents) {
  9256. logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
  9257. return fallback(this, filePathNode || mimetypeNode);
  9258. }
  9259. var buf = fileSync.contents;
  9260. if (useBase64 && !environment.encodeBase64) {
  9261. return fallback(this, filePathNode);
  9262. }
  9263. buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);
  9264. var uri = "data:" + mimetype + "," + buf + fragment;
  9265. return new URL(new Quoted("\"" + uri + "\"", uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  9266. } };
  9267. });
  9268. var getItemsFromNode = function (node) {
  9269. // handle non-array values as an array of length 1
  9270. // return 'undefined' if index is invalid
  9271. var items = Array.isArray(node.value) ?
  9272. node.value : Array(node);
  9273. return items;
  9274. };
  9275. var list = {
  9276. _SELF: function (n) {
  9277. return n;
  9278. },
  9279. extract: function (values, index) {
  9280. // (1-based index)
  9281. index = index.value - 1;
  9282. return getItemsFromNode(values)[index];
  9283. },
  9284. length: function (values) {
  9285. return new Dimension(getItemsFromNode(values).length);
  9286. },
  9287. /**
  9288. * Creates a Less list of incremental values.
  9289. * Modeled after Lodash's range function, also exists natively in PHP
  9290. *
  9291. * @param {Dimension} [start=1]
  9292. * @param {Dimension} end - e.g. 10 or 10px - unit is added to output
  9293. * @param {Dimension} [step=1]
  9294. */
  9295. range: function (start, end, step) {
  9296. var from;
  9297. var to;
  9298. var stepValue = 1;
  9299. var list = [];
  9300. if (end) {
  9301. to = end;
  9302. from = start.value;
  9303. if (step) {
  9304. stepValue = step.value;
  9305. }
  9306. }
  9307. else {
  9308. from = 1;
  9309. to = start;
  9310. }
  9311. for (var i_1 = from; i_1 <= to.value; i_1 += stepValue) {
  9312. list.push(new Dimension(i_1, to.unit));
  9313. }
  9314. return new Expression(list);
  9315. },
  9316. each: function (list, rs) {
  9317. var rules = [];
  9318. var newRules;
  9319. var iterator;
  9320. if (list.value && !(list instanceof Quoted)) {
  9321. if (Array.isArray(list.value)) {
  9322. iterator = list.value;
  9323. }
  9324. else {
  9325. iterator = [list.value];
  9326. }
  9327. }
  9328. else if (list.ruleset) {
  9329. iterator = list.ruleset.rules;
  9330. }
  9331. else if (list.rules) {
  9332. iterator = list.rules;
  9333. }
  9334. else if (Array.isArray(list)) {
  9335. iterator = list;
  9336. }
  9337. else {
  9338. iterator = [list];
  9339. }
  9340. var valueName = '@value';
  9341. var keyName = '@key';
  9342. var indexName = '@index';
  9343. if (rs.params) {
  9344. valueName = rs.params[0] && rs.params[0].name;
  9345. keyName = rs.params[1] && rs.params[1].name;
  9346. indexName = rs.params[2] && rs.params[2].name;
  9347. rs = rs.rules;
  9348. }
  9349. else {
  9350. rs = rs.ruleset;
  9351. }
  9352. for (var i_2 = 0; i_2 < iterator.length; i_2++) {
  9353. var key = void 0;
  9354. var value = void 0;
  9355. var item = iterator[i_2];
  9356. if (item instanceof Declaration) {
  9357. key = typeof item.name === 'string' ? item.name : item.name[0].value;
  9358. value = item.value;
  9359. }
  9360. else {
  9361. key = new Dimension(i_2 + 1);
  9362. value = item;
  9363. }
  9364. if (item instanceof Comment) {
  9365. continue;
  9366. }
  9367. newRules = rs.rules.slice(0);
  9368. if (valueName) {
  9369. newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo));
  9370. }
  9371. if (indexName) {
  9372. newRules.push(new Declaration(indexName, new Dimension(i_2 + 1), false, false, this.index, this.currentFileInfo));
  9373. }
  9374. if (keyName) {
  9375. newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo));
  9376. }
  9377. rules.push(new Ruleset([new (Selector)([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo()));
  9378. }
  9379. return new Ruleset([new (Selector)([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context);
  9380. }
  9381. };
  9382. var MathHelper = function (fn, unit, n) {
  9383. if (!(n instanceof Dimension)) {
  9384. throw { type: 'Argument', message: 'argument must be a number' };
  9385. }
  9386. if (unit == null) {
  9387. unit = n.unit;
  9388. }
  9389. else {
  9390. n = n.unify();
  9391. }
  9392. return new Dimension(fn(parseFloat(n.value)), unit);
  9393. };
  9394. var mathFunctions = {
  9395. // name, unit
  9396. ceil: null,
  9397. floor: null,
  9398. sqrt: null,
  9399. abs: null,
  9400. tan: '',
  9401. sin: '',
  9402. cos: '',
  9403. atan: 'rad',
  9404. asin: 'rad',
  9405. acos: 'rad'
  9406. };
  9407. for (var f$1 in mathFunctions) {
  9408. if (mathFunctions.hasOwnProperty(f$1)) {
  9409. mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]);
  9410. }
  9411. }
  9412. mathFunctions.round = function (n, f) {
  9413. var fraction = typeof f === 'undefined' ? 0 : f.value;
  9414. return MathHelper(function (num) { return num.toFixed(fraction); }, null, n);
  9415. };
  9416. var minMax = function (isMin, args) {
  9417. args = Array.prototype.slice.call(args);
  9418. switch (args.length) {
  9419. case 0: throw { type: 'Argument', message: 'one or more arguments required' };
  9420. }
  9421. var i; // key is the unit.toString() for unified Dimension values,
  9422. var j;
  9423. var current;
  9424. var currentUnified;
  9425. var referenceUnified;
  9426. var unit;
  9427. var unitStatic;
  9428. var unitClone;
  9429. var // elems only contains original argument values.
  9430. order = [];
  9431. var values = {};
  9432. // value is the index into the order array.
  9433. for (i = 0; i < args.length; i++) {
  9434. current = args[i];
  9435. if (!(current instanceof Dimension)) {
  9436. if (Array.isArray(args[i].value)) {
  9437. Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));
  9438. }
  9439. continue;
  9440. }
  9441. currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
  9442. unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
  9443. unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;
  9444. unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;
  9445. j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];
  9446. if (j === undefined) {
  9447. if (unitStatic !== undefined && unit !== unitStatic) {
  9448. throw { type: 'Argument', message: 'incompatible types' };
  9449. }
  9450. values[unit] = order.length;
  9451. order.push(current);
  9452. continue;
  9453. }
  9454. referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
  9455. if (isMin && currentUnified.value < referenceUnified.value ||
  9456. !isMin && currentUnified.value > referenceUnified.value) {
  9457. order[j] = current;
  9458. }
  9459. }
  9460. if (order.length == 1) {
  9461. return order[0];
  9462. }
  9463. args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');
  9464. return new Anonymous((isMin ? 'min' : 'max') + "(" + args + ")");
  9465. };
  9466. var number$1 = {
  9467. min: function () {
  9468. var args = [];
  9469. for (var _i = 0; _i < arguments.length; _i++) {
  9470. args[_i] = arguments[_i];
  9471. }
  9472. return minMax(true, args);
  9473. },
  9474. max: function () {
  9475. var args = [];
  9476. for (var _i = 0; _i < arguments.length; _i++) {
  9477. args[_i] = arguments[_i];
  9478. }
  9479. return minMax(false, args);
  9480. },
  9481. convert: function (val, unit) {
  9482. return val.convertTo(unit.value);
  9483. },
  9484. pi: function () {
  9485. return new Dimension(Math.PI);
  9486. },
  9487. mod: function (a, b) {
  9488. return new Dimension(a.value % b.value, a.unit);
  9489. },
  9490. pow: function (x, y) {
  9491. if (typeof x === 'number' && typeof y === 'number') {
  9492. x = new Dimension(x);
  9493. y = new Dimension(y);
  9494. }
  9495. else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {
  9496. throw { type: 'Argument', message: 'arguments must be numbers' };
  9497. }
  9498. return new Dimension(Math.pow(x.value, y.value), x.unit);
  9499. },
  9500. percentage: function (n) {
  9501. var result = MathHelper(function (num) { return num * 100; }, '%', n);
  9502. return result;
  9503. }
  9504. };
  9505. var string = {
  9506. e: function (str) {
  9507. return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true);
  9508. },
  9509. escape: function (str) {
  9510. return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')
  9511. .replace(/\(/g, '%28').replace(/\)/g, '%29'));
  9512. },
  9513. replace: function (string, pattern, replacement, flags) {
  9514. var result = string.value;
  9515. replacement = (replacement.type === 'Quoted') ?
  9516. replacement.value : replacement.toCSS();
  9517. result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
  9518. return new Quoted(string.quote || '', result, string.escaped);
  9519. },
  9520. '%': function (string /* arg, arg, ... */) {
  9521. var args = Array.prototype.slice.call(arguments, 1);
  9522. var result = string.value;
  9523. var _loop_1 = function (i_1) {
  9524. /* jshint loopfunc:true */
  9525. result = result.replace(/%[sda]/i, function (token) {
  9526. var value = ((args[i_1].type === 'Quoted') &&
  9527. token.match(/s/i)) ? args[i_1].value : args[i_1].toCSS();
  9528. return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
  9529. });
  9530. };
  9531. for (var i_1 = 0; i_1 < args.length; i_1++) {
  9532. _loop_1(i_1);
  9533. }
  9534. result = result.replace(/%%/g, '%');
  9535. return new Quoted(string.quote || '', result, string.escaped);
  9536. }
  9537. };
  9538. var svg = (function (environment) {
  9539. return { 'svg-gradient': function (direction) {
  9540. var stops;
  9541. var gradientDirectionSvg;
  9542. var gradientType = 'linear';
  9543. var rectangleDimension = 'x="0" y="0" width="1" height="1"';
  9544. var renderEnv = { compress: false };
  9545. var returner;
  9546. var directionValue = direction.toCSS(renderEnv);
  9547. var i;
  9548. var color;
  9549. var position;
  9550. var positionValue;
  9551. var alpha;
  9552. function throwArgumentDescriptor() {
  9553. throw { type: 'Argument',
  9554. message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +
  9555. ' end_color [end_position] or direction, color list' };
  9556. }
  9557. if (arguments.length == 2) {
  9558. if (arguments[1].value.length < 2) {
  9559. throwArgumentDescriptor();
  9560. }
  9561. stops = arguments[1].value;
  9562. }
  9563. else if (arguments.length < 3) {
  9564. throwArgumentDescriptor();
  9565. }
  9566. else {
  9567. stops = Array.prototype.slice.call(arguments, 1);
  9568. }
  9569. switch (directionValue) {
  9570. case 'to bottom':
  9571. gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
  9572. break;
  9573. case 'to right':
  9574. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
  9575. break;
  9576. case 'to bottom right':
  9577. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
  9578. break;
  9579. case 'to top right':
  9580. gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
  9581. break;
  9582. case 'ellipse':
  9583. case 'ellipse at center':
  9584. gradientType = 'radial';
  9585. gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
  9586. rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
  9587. break;
  9588. default:
  9589. throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' +
  9590. ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' };
  9591. }
  9592. returner = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 1 1\"><" + gradientType + "Gradient id=\"g\" " + gradientDirectionSvg + ">";
  9593. for (i = 0; i < stops.length; i += 1) {
  9594. if (stops[i] instanceof Expression) {
  9595. color = stops[i].value[0];
  9596. position = stops[i].value[1];
  9597. }
  9598. else {
  9599. color = stops[i];
  9600. position = undefined;
  9601. }
  9602. if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
  9603. throwArgumentDescriptor();
  9604. }
  9605. positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';
  9606. alpha = color.alpha;
  9607. returner += "<stop offset=\"" + positionValue + "\" stop-color=\"" + color.toRGB() + "\"" + (alpha < 1 ? " stop-opacity=\"" + alpha + "\"" : '') + "/>";
  9608. }
  9609. returner += "</" + gradientType + "Gradient><rect " + rectangleDimension + " fill=\"url(#g)\" /></svg>";
  9610. returner = encodeURIComponent(returner);
  9611. returner = "data:image/svg+xml," + returner;
  9612. return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  9613. } };
  9614. });
  9615. var isa = function (n, Type) { return (n instanceof Type) ? Keyword.True : Keyword.False; };
  9616. var isunit = function (n, unit) {
  9617. if (unit === undefined) {
  9618. throw { type: 'Argument', message: 'missing the required second argument to isunit.' };
  9619. }
  9620. unit = typeof unit.value === 'string' ? unit.value : unit;
  9621. if (typeof unit !== 'string') {
  9622. throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };
  9623. }
  9624. return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
  9625. };
  9626. var types = {
  9627. isruleset: function (n) {
  9628. return isa(n, DetachedRuleset);
  9629. },
  9630. iscolor: function (n) {
  9631. return isa(n, Color);
  9632. },
  9633. isnumber: function (n) {
  9634. return isa(n, Dimension);
  9635. },
  9636. isstring: function (n) {
  9637. return isa(n, Quoted);
  9638. },
  9639. iskeyword: function (n) {
  9640. return isa(n, Keyword);
  9641. },
  9642. isurl: function (n) {
  9643. return isa(n, URL);
  9644. },
  9645. ispixel: function (n) {
  9646. return isunit(n, 'px');
  9647. },
  9648. ispercentage: function (n) {
  9649. return isunit(n, '%');
  9650. },
  9651. isem: function (n) {
  9652. return isunit(n, 'em');
  9653. },
  9654. isunit: isunit,
  9655. unit: function (val, unit) {
  9656. if (!(val instanceof Dimension)) {
  9657. throw { type: 'Argument',
  9658. message: "the first argument to unit must be a number" + (val instanceof Operation ? '. Have you forgotten parenthesis?' : '') };
  9659. }
  9660. if (unit) {
  9661. if (unit instanceof Keyword) {
  9662. unit = unit.value;
  9663. }
  9664. else {
  9665. unit = unit.toCSS();
  9666. }
  9667. }
  9668. else {
  9669. unit = '';
  9670. }
  9671. return new Dimension(val.value, unit);
  9672. },
  9673. 'get-unit': function (n) {
  9674. return new Anonymous(n.unit);
  9675. }
  9676. };
  9677. var Functions = (function (environment) {
  9678. var functions = { functionRegistry: functionRegistry, functionCaller: functionCaller };
  9679. // register functions
  9680. functionRegistry.addMultiple(boolean$1);
  9681. functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc));
  9682. functionRegistry.addMultiple(color);
  9683. functionRegistry.addMultiple(colorBlend);
  9684. functionRegistry.addMultiple(dataUri(environment));
  9685. functionRegistry.addMultiple(list);
  9686. functionRegistry.addMultiple(mathFunctions);
  9687. functionRegistry.addMultiple(number$1);
  9688. functionRegistry.addMultiple(string);
  9689. functionRegistry.addMultiple(svg());
  9690. functionRegistry.addMultiple(types);
  9691. return functions;
  9692. });
  9693. var sourceMapOutput = (function (environment) {
  9694. var SourceMapOutput = /** @class */ (function () {
  9695. function SourceMapOutput(options) {
  9696. this._css = [];
  9697. this._rootNode = options.rootNode;
  9698. this._contentsMap = options.contentsMap;
  9699. this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;
  9700. if (options.sourceMapFilename) {
  9701. this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/');
  9702. }
  9703. this._outputFilename = options.outputFilename;
  9704. this.sourceMapURL = options.sourceMapURL;
  9705. if (options.sourceMapBasepath) {
  9706. this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/');
  9707. }
  9708. if (options.sourceMapRootpath) {
  9709. this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/');
  9710. if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {
  9711. this._sourceMapRootpath += '/';
  9712. }
  9713. }
  9714. else {
  9715. this._sourceMapRootpath = '';
  9716. }
  9717. this._outputSourceFiles = options.outputSourceFiles;
  9718. this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();
  9719. this._lineNumber = 0;
  9720. this._column = 0;
  9721. }
  9722. SourceMapOutput.prototype.removeBasepath = function (path) {
  9723. if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) {
  9724. path = path.substring(this._sourceMapBasepath.length);
  9725. if (path.charAt(0) === '\\' || path.charAt(0) === '/') {
  9726. path = path.substring(1);
  9727. }
  9728. }
  9729. return path;
  9730. };
  9731. SourceMapOutput.prototype.normalizeFilename = function (filename) {
  9732. filename = filename.replace(/\\/g, '/');
  9733. filename = this.removeBasepath(filename);
  9734. return (this._sourceMapRootpath || '') + filename;
  9735. };
  9736. SourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) {
  9737. // ignore adding empty strings
  9738. if (!chunk) {
  9739. return;
  9740. }
  9741. var lines;
  9742. var sourceLines;
  9743. var columns;
  9744. var sourceColumns;
  9745. var i;
  9746. if (fileInfo && fileInfo.filename) {
  9747. var inputSource = this._contentsMap[fileInfo.filename];
  9748. // remove vars/banner added to the top of the file
  9749. if (this._contentsIgnoredCharsMap[fileInfo.filename]) {
  9750. // adjust the index
  9751. index -= this._contentsIgnoredCharsMap[fileInfo.filename];
  9752. if (index < 0) {
  9753. index = 0;
  9754. }
  9755. // adjust the source
  9756. inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);
  9757. }
  9758. // ignore empty content
  9759. if (inputSource === undefined) {
  9760. return;
  9761. }
  9762. inputSource = inputSource.substring(0, index);
  9763. sourceLines = inputSource.split('\n');
  9764. sourceColumns = sourceLines[sourceLines.length - 1];
  9765. }
  9766. lines = chunk.split('\n');
  9767. columns = lines[lines.length - 1];
  9768. if (fileInfo && fileInfo.filename) {
  9769. if (!mapLines) {
  9770. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column },
  9771. original: { line: sourceLines.length, column: sourceColumns.length },
  9772. source: this.normalizeFilename(fileInfo.filename) });
  9773. }
  9774. else {
  9775. for (i = 0; i < lines.length; i++) {
  9776. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0 },
  9777. original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0 },
  9778. source: this.normalizeFilename(fileInfo.filename) });
  9779. }
  9780. }
  9781. }
  9782. if (lines.length === 1) {
  9783. this._column += columns.length;
  9784. }
  9785. else {
  9786. this._lineNumber += lines.length - 1;
  9787. this._column = columns.length;
  9788. }
  9789. this._css.push(chunk);
  9790. };
  9791. SourceMapOutput.prototype.isEmpty = function () {
  9792. return this._css.length === 0;
  9793. };
  9794. SourceMapOutput.prototype.toCSS = function (context) {
  9795. this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });
  9796. if (this._outputSourceFiles) {
  9797. for (var filename in this._contentsMap) {
  9798. if (this._contentsMap.hasOwnProperty(filename)) {
  9799. var source = this._contentsMap[filename];
  9800. if (this._contentsIgnoredCharsMap[filename]) {
  9801. source = source.slice(this._contentsIgnoredCharsMap[filename]);
  9802. }
  9803. this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);
  9804. }
  9805. }
  9806. }
  9807. this._rootNode.genCSS(context, this);
  9808. if (this._css.length > 0) {
  9809. var sourceMapURL = void 0;
  9810. var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());
  9811. if (this.sourceMapURL) {
  9812. sourceMapURL = this.sourceMapURL;
  9813. }
  9814. else if (this._sourceMapFilename) {
  9815. sourceMapURL = this._sourceMapFilename;
  9816. }
  9817. this.sourceMapURL = sourceMapURL;
  9818. this.sourceMap = sourceMapContent;
  9819. }
  9820. return this._css.join('');
  9821. };
  9822. return SourceMapOutput;
  9823. }());
  9824. return SourceMapOutput;
  9825. });
  9826. var sourceMapBuilder = (function (SourceMapOutput, environment) {
  9827. var SourceMapBuilder = /** @class */ (function () {
  9828. function SourceMapBuilder(options) {
  9829. this.options = options;
  9830. }
  9831. SourceMapBuilder.prototype.toCSS = function (rootNode, options, imports) {
  9832. var sourceMapOutput = new SourceMapOutput({
  9833. contentsIgnoredCharsMap: imports.contentsIgnoredChars,
  9834. rootNode: rootNode,
  9835. contentsMap: imports.contents,
  9836. sourceMapFilename: this.options.sourceMapFilename,
  9837. sourceMapURL: this.options.sourceMapURL,
  9838. outputFilename: this.options.sourceMapOutputFilename,
  9839. sourceMapBasepath: this.options.sourceMapBasepath,
  9840. sourceMapRootpath: this.options.sourceMapRootpath,
  9841. outputSourceFiles: this.options.outputSourceFiles,
  9842. sourceMapGenerator: this.options.sourceMapGenerator,
  9843. sourceMapFileInline: this.options.sourceMapFileInline
  9844. });
  9845. var css = sourceMapOutput.toCSS(options);
  9846. this.sourceMap = sourceMapOutput.sourceMap;
  9847. this.sourceMapURL = sourceMapOutput.sourceMapURL;
  9848. if (this.options.sourceMapInputFilename) {
  9849. this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);
  9850. }
  9851. if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) {
  9852. this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL);
  9853. }
  9854. return css + this.getCSSAppendage();
  9855. };
  9856. SourceMapBuilder.prototype.getCSSAppendage = function () {
  9857. var sourceMapURL = this.sourceMapURL;
  9858. if (this.options.sourceMapFileInline) {
  9859. if (this.sourceMap === undefined) {
  9860. return '';
  9861. }
  9862. sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap);
  9863. }
  9864. if (sourceMapURL) {
  9865. return "/*# sourceMappingURL=" + sourceMapURL + " */";
  9866. }
  9867. return '';
  9868. };
  9869. SourceMapBuilder.prototype.getExternalSourceMap = function () {
  9870. return this.sourceMap;
  9871. };
  9872. SourceMapBuilder.prototype.setExternalSourceMap = function (sourceMap) {
  9873. this.sourceMap = sourceMap;
  9874. };
  9875. SourceMapBuilder.prototype.isInline = function () {
  9876. return this.options.sourceMapFileInline;
  9877. };
  9878. SourceMapBuilder.prototype.getSourceMapURL = function () {
  9879. return this.sourceMapURL;
  9880. };
  9881. SourceMapBuilder.prototype.getOutputFilename = function () {
  9882. return this.options.sourceMapOutputFilename;
  9883. };
  9884. SourceMapBuilder.prototype.getInputFilename = function () {
  9885. return this.sourceMapInputFilename;
  9886. };
  9887. return SourceMapBuilder;
  9888. }());
  9889. return SourceMapBuilder;
  9890. });
  9891. var transformTree = (function (root, options) {
  9892. if (options === void 0) { options = {}; }
  9893. var evaldRoot;
  9894. var variables = options.variables;
  9895. var evalEnv = new contexts.Eval(options);
  9896. //
  9897. // Allows setting variables with a hash, so:
  9898. //
  9899. // `{ color: new tree.Color('#f01') }` will become:
  9900. //
  9901. // new tree.Declaration('@color',
  9902. // new tree.Value([
  9903. // new tree.Expression([
  9904. // new tree.Color('#f01')
  9905. // ])
  9906. // ])
  9907. // )
  9908. //
  9909. if (typeof variables === 'object' && !Array.isArray(variables)) {
  9910. variables = Object.keys(variables).map(function (k) {
  9911. var value = variables[k];
  9912. if (!(value instanceof tree.Value)) {
  9913. if (!(value instanceof tree.Expression)) {
  9914. value = new tree.Expression([value]);
  9915. }
  9916. value = new tree.Value([value]);
  9917. }
  9918. return new tree.Declaration("@" + k, value, false, null, 0);
  9919. });
  9920. evalEnv.frames = [new tree.Ruleset(null, variables)];
  9921. }
  9922. var visitors$1 = [
  9923. new visitors.JoinSelectorVisitor(),
  9924. new visitors.MarkVisibleSelectorsVisitor(true),
  9925. new visitors.ExtendVisitor(),
  9926. new visitors.ToCSSVisitor({ compress: Boolean(options.compress) })
  9927. ];
  9928. var preEvalVisitors = [];
  9929. var v;
  9930. var visitorIterator;
  9931. /**
  9932. * first() / get() allows visitors to be added while visiting
  9933. *
  9934. * @todo Add scoping for visitors just like functions for @plugin; right now they're global
  9935. */
  9936. if (options.pluginManager) {
  9937. visitorIterator = options.pluginManager.visitor();
  9938. for (var i = 0; i < 2; i++) {
  9939. visitorIterator.first();
  9940. while ((v = visitorIterator.get())) {
  9941. if (v.isPreEvalVisitor) {
  9942. if (i === 0 || preEvalVisitors.indexOf(v) === -1) {
  9943. preEvalVisitors.push(v);
  9944. v.run(root);
  9945. }
  9946. }
  9947. else {
  9948. if (i === 0 || visitors$1.indexOf(v) === -1) {
  9949. if (v.isPreVisitor) {
  9950. visitors$1.unshift(v);
  9951. }
  9952. else {
  9953. visitors$1.push(v);
  9954. }
  9955. }
  9956. }
  9957. }
  9958. }
  9959. }
  9960. evaldRoot = root.eval(evalEnv);
  9961. for (var i = 0; i < visitors$1.length; i++) {
  9962. visitors$1[i].run(evaldRoot);
  9963. }
  9964. // Run any remaining visitors added after eval pass
  9965. if (options.pluginManager) {
  9966. visitorIterator.first();
  9967. while ((v = visitorIterator.get())) {
  9968. if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) {
  9969. v.run(evaldRoot);
  9970. }
  9971. }
  9972. }
  9973. return evaldRoot;
  9974. });
  9975. var parseTree = (function (SourceMapBuilder) {
  9976. var ParseTree = /** @class */ (function () {
  9977. function ParseTree(root, imports) {
  9978. this.root = root;
  9979. this.imports = imports;
  9980. }
  9981. ParseTree.prototype.toCSS = function (options) {
  9982. var evaldRoot;
  9983. var result = {};
  9984. var sourceMapBuilder;
  9985. try {
  9986. evaldRoot = transformTree(this.root, options);
  9987. }
  9988. catch (e) {
  9989. throw new LessError(e, this.imports);
  9990. }
  9991. try {
  9992. var compress = Boolean(options.compress);
  9993. if (compress) {
  9994. logger.warn('The compress option has been deprecated. ' +
  9995. 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');
  9996. }
  9997. var toCSSOptions = {
  9998. compress: compress,
  9999. dumpLineNumbers: options.dumpLineNumbers,
  10000. strictUnits: Boolean(options.strictUnits),
  10001. numPrecision: 8
  10002. };
  10003. if (options.sourceMap) {
  10004. sourceMapBuilder = new SourceMapBuilder(options.sourceMap);
  10005. result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
  10006. }
  10007. else {
  10008. result.css = evaldRoot.toCSS(toCSSOptions);
  10009. }
  10010. }
  10011. catch (e) {
  10012. throw new LessError(e, this.imports);
  10013. }
  10014. if (options.pluginManager) {
  10015. var postProcessors = options.pluginManager.getPostProcessors();
  10016. for (var i_1 = 0; i_1 < postProcessors.length; i_1++) {
  10017. result.css = postProcessors[i_1].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports });
  10018. }
  10019. }
  10020. if (options.sourceMap) {
  10021. result.map = sourceMapBuilder.getExternalSourceMap();
  10022. }
  10023. result.imports = [];
  10024. for (var file_1 in this.imports.files) {
  10025. if (this.imports.files.hasOwnProperty(file_1) && file_1 !== this.imports.rootFilename) {
  10026. result.imports.push(file_1);
  10027. }
  10028. }
  10029. return result;
  10030. };
  10031. return ParseTree;
  10032. }());
  10033. return ParseTree;
  10034. });
  10035. var importManager = (function (environment) {
  10036. // FileInfo = {
  10037. // 'rewriteUrls' - option - whether to adjust URL's to be relative
  10038. // 'filename' - full resolved filename of current file
  10039. // 'rootpath' - path to append to normal URLs for this node
  10040. // 'currentDirectory' - path to the current file, absolute
  10041. // 'rootFilename' - filename of the base file
  10042. // 'entryPath' - absolute path to the entry file
  10043. // 'reference' - whether the file should not be output and only output parts that are referenced
  10044. var ImportManager = /** @class */ (function () {
  10045. function ImportManager(less, context, rootFileInfo) {
  10046. this.less = less;
  10047. this.rootFilename = rootFileInfo.filename;
  10048. this.paths = context.paths || []; // Search paths, when importing
  10049. this.contents = {}; // map - filename to contents of all the files
  10050. this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore
  10051. this.mime = context.mime;
  10052. this.error = null;
  10053. this.context = context;
  10054. // Deprecated? Unused outside of here, could be useful.
  10055. this.queue = []; // Files which haven't been imported yet
  10056. this.files = {}; // Holds the imported parse trees.
  10057. }
  10058. /**
  10059. * Add an import to be imported
  10060. * @param path - the raw path
  10061. * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension)
  10062. * @param currentFileInfo - the current file info (used for instance to work out relative paths)
  10063. * @param importOptions - import options
  10064. * @param callback - callback for when it is imported
  10065. */
  10066. ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) {
  10067. var importManager = this;
  10068. var pluginLoader = this.context.pluginManager.Loader;
  10069. this.queue.push(path);
  10070. var fileParsedFunc = function (e, root, fullPath) {
  10071. importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
  10072. var importedEqualsRoot = fullPath === importManager.rootFilename;
  10073. if (importOptions.optional && e) {
  10074. callback(null, { rules: [] }, false, null);
  10075. logger.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional.");
  10076. }
  10077. else {
  10078. // Inline imports aren't cached here.
  10079. // If we start to cache them, please make sure they won't conflict with non-inline imports of the
  10080. // same name as they used to do before this comment and the condition below have been added.
  10081. if (!importManager.files[fullPath] && !importOptions.inline) {
  10082. importManager.files[fullPath] = { root: root, options: importOptions };
  10083. }
  10084. if (e && !importManager.error) {
  10085. importManager.error = e;
  10086. }
  10087. callback(e, root, importedEqualsRoot, fullPath);
  10088. }
  10089. };
  10090. var newFileInfo = {
  10091. rewriteUrls: this.context.rewriteUrls,
  10092. entryPath: currentFileInfo.entryPath,
  10093. rootpath: currentFileInfo.rootpath,
  10094. rootFilename: currentFileInfo.rootFilename
  10095. };
  10096. var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
  10097. if (!fileManager) {
  10098. fileParsedFunc({ message: "Could not find a file-manager for " + path });
  10099. return;
  10100. }
  10101. var loadFileCallback = function (loadedFile) {
  10102. var plugin;
  10103. var resolvedFilename = loadedFile.filename;
  10104. var contents = loadedFile.contents.replace(/^\uFEFF/, '');
  10105. // Pass on an updated rootpath if path of imported file is relative and file
  10106. // is in a (sub|sup) directory
  10107. //
  10108. // Examples:
  10109. // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
  10110. // then rootpath should become 'less/module/nav/'
  10111. // - If path of imported file is '../mixins.less' and rootpath is 'less/',
  10112. // then rootpath should become 'less/../'
  10113. newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
  10114. if (newFileInfo.rewriteUrls) {
  10115. newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
  10116. if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
  10117. newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
  10118. }
  10119. }
  10120. newFileInfo.filename = resolvedFilename;
  10121. var newEnv = new contexts.Parse(importManager.context);
  10122. newEnv.processImports = false;
  10123. importManager.contents[resolvedFilename] = contents;
  10124. if (currentFileInfo.reference || importOptions.reference) {
  10125. newFileInfo.reference = true;
  10126. }
  10127. if (importOptions.isPlugin) {
  10128. plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo);
  10129. if (plugin instanceof LessError) {
  10130. fileParsedFunc(plugin, null, resolvedFilename);
  10131. }
  10132. else {
  10133. fileParsedFunc(null, plugin, resolvedFilename);
  10134. }
  10135. }
  10136. else if (importOptions.inline) {
  10137. fileParsedFunc(null, contents, resolvedFilename);
  10138. }
  10139. else {
  10140. // import (multiple) parse trees apparently get altered and can't be cached.
  10141. // TODO: investigate why this is
  10142. if (importManager.files[resolvedFilename]
  10143. && !importManager.files[resolvedFilename].options.multiple
  10144. && !importOptions.multiple) {
  10145. fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename);
  10146. }
  10147. else {
  10148. new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
  10149. fileParsedFunc(e, root, resolvedFilename);
  10150. });
  10151. }
  10152. }
  10153. };
  10154. var promise;
  10155. var context = clone(this.context);
  10156. if (tryAppendExtension) {
  10157. context.ext = importOptions.isPlugin ? '.js' : '.less';
  10158. }
  10159. if (importOptions.isPlugin) {
  10160. context.mime = 'application/javascript';
  10161. promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager);
  10162. }
  10163. else {
  10164. promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) {
  10165. if (err) {
  10166. fileParsedFunc(err);
  10167. }
  10168. else {
  10169. loadFileCallback(loadedFile);
  10170. }
  10171. });
  10172. }
  10173. if (promise) {
  10174. promise.then(loadFileCallback, fileParsedFunc);
  10175. }
  10176. };
  10177. return ImportManager;
  10178. }());
  10179. return ImportManager;
  10180. });
  10181. var Render = (function (environment, ParseTree, ImportManager) {
  10182. var render = function (input, options, callback) {
  10183. if (typeof options === 'function') {
  10184. callback = options;
  10185. options = copyOptions(this.options, {});
  10186. }
  10187. else {
  10188. options = copyOptions(this.options, options || {});
  10189. }
  10190. if (!callback) {
  10191. var self_1 = this;
  10192. return new Promise(function (resolve, reject) {
  10193. render.call(self_1, input, options, function (err, output) {
  10194. if (err) {
  10195. reject(err);
  10196. }
  10197. else {
  10198. resolve(output);
  10199. }
  10200. });
  10201. });
  10202. }
  10203. else {
  10204. this.parse(input, options, function (err, root, imports, options) {
  10205. if (err) {
  10206. return callback(err);
  10207. }
  10208. var result;
  10209. try {
  10210. var parseTree = new ParseTree(root, imports);
  10211. result = parseTree.toCSS(options);
  10212. }
  10213. catch (err) {
  10214. return callback(err);
  10215. }
  10216. callback(null, result);
  10217. });
  10218. }
  10219. };
  10220. return render;
  10221. });
  10222. /**
  10223. * Plugin Manager
  10224. */
  10225. var PluginManager = /** @class */ (function () {
  10226. function PluginManager(less) {
  10227. this.less = less;
  10228. this.visitors = [];
  10229. this.preProcessors = [];
  10230. this.postProcessors = [];
  10231. this.installedPlugins = [];
  10232. this.fileManagers = [];
  10233. this.iterator = -1;
  10234. this.pluginCache = {};
  10235. this.Loader = new less.PluginLoader(less);
  10236. }
  10237. /**
  10238. * Adds all the plugins in the array
  10239. * @param {Array} plugins
  10240. */
  10241. PluginManager.prototype.addPlugins = function (plugins) {
  10242. if (plugins) {
  10243. for (var i_1 = 0; i_1 < plugins.length; i_1++) {
  10244. this.addPlugin(plugins[i_1]);
  10245. }
  10246. }
  10247. };
  10248. /**
  10249. *
  10250. * @param plugin
  10251. * @param {String} filename
  10252. */
  10253. PluginManager.prototype.addPlugin = function (plugin, filename, functionRegistry) {
  10254. this.installedPlugins.push(plugin);
  10255. if (filename) {
  10256. this.pluginCache[filename] = plugin;
  10257. }
  10258. if (plugin.install) {
  10259. plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry);
  10260. }
  10261. };
  10262. /**
  10263. *
  10264. * @param filename
  10265. */
  10266. PluginManager.prototype.get = function (filename) {
  10267. return this.pluginCache[filename];
  10268. };
  10269. /**
  10270. * Adds a visitor. The visitor object has options on itself to determine
  10271. * when it should run.
  10272. * @param visitor
  10273. */
  10274. PluginManager.prototype.addVisitor = function (visitor) {
  10275. this.visitors.push(visitor);
  10276. };
  10277. /**
  10278. * Adds a pre processor object
  10279. * @param {object} preProcessor
  10280. * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import
  10281. */
  10282. PluginManager.prototype.addPreProcessor = function (preProcessor, priority) {
  10283. var indexToInsertAt;
  10284. for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {
  10285. if (this.preProcessors[indexToInsertAt].priority >= priority) {
  10286. break;
  10287. }
  10288. }
  10289. this.preProcessors.splice(indexToInsertAt, 0, { preProcessor: preProcessor, priority: priority });
  10290. };
  10291. /**
  10292. * Adds a post processor object
  10293. * @param {object} postProcessor
  10294. * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression
  10295. */
  10296. PluginManager.prototype.addPostProcessor = function (postProcessor, priority) {
  10297. var indexToInsertAt;
  10298. for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {
  10299. if (this.postProcessors[indexToInsertAt].priority >= priority) {
  10300. break;
  10301. }
  10302. }
  10303. this.postProcessors.splice(indexToInsertAt, 0, { postProcessor: postProcessor, priority: priority });
  10304. };
  10305. /**
  10306. *
  10307. * @param manager
  10308. */
  10309. PluginManager.prototype.addFileManager = function (manager) {
  10310. this.fileManagers.push(manager);
  10311. };
  10312. /**
  10313. *
  10314. * @returns {Array}
  10315. * @private
  10316. */
  10317. PluginManager.prototype.getPreProcessors = function () {
  10318. var preProcessors = [];
  10319. for (var i_2 = 0; i_2 < this.preProcessors.length; i_2++) {
  10320. preProcessors.push(this.preProcessors[i_2].preProcessor);
  10321. }
  10322. return preProcessors;
  10323. };
  10324. /**
  10325. *
  10326. * @returns {Array}
  10327. * @private
  10328. */
  10329. PluginManager.prototype.getPostProcessors = function () {
  10330. var postProcessors = [];
  10331. for (var i_3 = 0; i_3 < this.postProcessors.length; i_3++) {
  10332. postProcessors.push(this.postProcessors[i_3].postProcessor);
  10333. }
  10334. return postProcessors;
  10335. };
  10336. /**
  10337. *
  10338. * @returns {Array}
  10339. * @private
  10340. */
  10341. PluginManager.prototype.getVisitors = function () {
  10342. return this.visitors;
  10343. };
  10344. PluginManager.prototype.visitor = function () {
  10345. var self = this;
  10346. return {
  10347. first: function () {
  10348. self.iterator = -1;
  10349. return self.visitors[self.iterator];
  10350. },
  10351. get: function () {
  10352. self.iterator += 1;
  10353. return self.visitors[self.iterator];
  10354. }
  10355. };
  10356. };
  10357. /**
  10358. *
  10359. * @returns {Array}
  10360. * @private
  10361. */
  10362. PluginManager.prototype.getFileManagers = function () {
  10363. return this.fileManagers;
  10364. };
  10365. return PluginManager;
  10366. }());
  10367. var pm;
  10368. function PluginManagerFactory(less, newFactory) {
  10369. if (newFactory || !pm) {
  10370. pm = new PluginManager(less);
  10371. }
  10372. return pm;
  10373. }
  10374. var Parse = (function (environment, ParseTree, ImportManager) {
  10375. var parse = function (input, options, callback) {
  10376. if (typeof options === 'function') {
  10377. callback = options;
  10378. options = copyOptions(this.options, {});
  10379. }
  10380. else {
  10381. options = copyOptions(this.options, options || {});
  10382. }
  10383. if (!callback) {
  10384. var self_1 = this;
  10385. return new Promise(function (resolve, reject) {
  10386. parse.call(self_1, input, options, function (err, output) {
  10387. if (err) {
  10388. reject(err);
  10389. }
  10390. else {
  10391. resolve(output);
  10392. }
  10393. });
  10394. });
  10395. }
  10396. else {
  10397. var context_1;
  10398. var rootFileInfo = void 0;
  10399. var pluginManager_1 = new PluginManagerFactory(this, !options.reUsePluginManager);
  10400. options.pluginManager = pluginManager_1;
  10401. context_1 = new contexts.Parse(options);
  10402. if (options.rootFileInfo) {
  10403. rootFileInfo = options.rootFileInfo;
  10404. }
  10405. else {
  10406. var filename = options.filename || 'input';
  10407. var entryPath = filename.replace(/[^\/\\]*$/, '');
  10408. rootFileInfo = {
  10409. filename: filename,
  10410. rewriteUrls: context_1.rewriteUrls,
  10411. rootpath: context_1.rootpath || '',
  10412. currentDirectory: entryPath,
  10413. entryPath: entryPath,
  10414. rootFilename: filename
  10415. };
  10416. // add in a missing trailing slash
  10417. if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {
  10418. rootFileInfo.rootpath += '/';
  10419. }
  10420. }
  10421. var imports_1 = new ImportManager(this, context_1, rootFileInfo);
  10422. this.importManager = imports_1;
  10423. // TODO: allow the plugins to be just a list of paths or names
  10424. // Do an async plugin queue like lessc
  10425. if (options.plugins) {
  10426. options.plugins.forEach(function (plugin) {
  10427. var evalResult;
  10428. var contents;
  10429. if (plugin.fileContent) {
  10430. contents = plugin.fileContent.replace(/^\uFEFF/, '');
  10431. evalResult = pluginManager_1.Loader.evalPlugin(contents, context_1, imports_1, plugin.options, plugin.filename);
  10432. if (evalResult instanceof LessError) {
  10433. return callback(evalResult);
  10434. }
  10435. }
  10436. else {
  10437. pluginManager_1.addPlugin(plugin);
  10438. }
  10439. });
  10440. }
  10441. new Parser(context_1, imports_1, rootFileInfo)
  10442. .parse(input, function (e, root) {
  10443. if (e) {
  10444. return callback(e);
  10445. }
  10446. callback(null, root, imports_1, options);
  10447. }, options);
  10448. }
  10449. };
  10450. return parse;
  10451. });
  10452. var createFromEnvironment = (function (environment, fileManagers) {
  10453. /**
  10454. * @todo
  10455. * This original code could be improved quite a bit.
  10456. * Many classes / modules currently add side-effects / mutations to passed in objects,
  10457. * which makes it hard to refactor and reason about.
  10458. */
  10459. environment = new environment$1(environment, fileManagers);
  10460. var SourceMapOutput = sourceMapOutput(environment);
  10461. var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment);
  10462. var ParseTree = parseTree(SourceMapBuilder);
  10463. var ImportManager = importManager(environment);
  10464. var render = Render(environment, ParseTree);
  10465. var parse = Parse(environment, ParseTree, ImportManager);
  10466. var functions = Functions(environment);
  10467. /**
  10468. * @todo
  10469. * This root properties / methods need to be organized.
  10470. * It's not clear what should / must be public and why.
  10471. */
  10472. var initial = {
  10473. version: [3, 11, 1],
  10474. data: data,
  10475. tree: tree,
  10476. Environment: environment$1,
  10477. AbstractFileManager: AbstractFileManager,
  10478. AbstractPluginLoader: AbstractPluginLoader,
  10479. environment: environment,
  10480. visitors: visitors,
  10481. Parser: Parser,
  10482. functions: functions,
  10483. contexts: contexts,
  10484. SourceMapOutput: SourceMapOutput,
  10485. SourceMapBuilder: SourceMapBuilder,
  10486. ParseTree: ParseTree,
  10487. ImportManager: ImportManager,
  10488. render: render,
  10489. parse: parse,
  10490. LessError: LessError,
  10491. transformTree: transformTree,
  10492. utils: utils,
  10493. PluginManager: PluginManagerFactory,
  10494. logger: logger
  10495. };
  10496. // Create a public API
  10497. var ctor = function (t) { return function () {
  10498. var args = [];
  10499. for (var _i = 0; _i < arguments.length; _i++) {
  10500. args[_i] = arguments[_i];
  10501. }
  10502. return new (t.bind.apply(t, tslib.__spreadArrays([void 0], args)))();
  10503. }; };
  10504. var t;
  10505. var api = Object.create(initial);
  10506. for (var n in initial.tree) {
  10507. /* eslint guard-for-in: 0 */
  10508. t = initial.tree[n];
  10509. if (typeof t === 'function') {
  10510. api[n.toLowerCase()] = ctor(t);
  10511. }
  10512. else {
  10513. api[n] = Object.create(null);
  10514. for (var o in t) {
  10515. /* eslint guard-for-in: 0 */
  10516. api[n][o.toLowerCase()] = ctor(t[o]);
  10517. }
  10518. }
  10519. }
  10520. return api;
  10521. });
  10522. function createCommonjsModule(fn, module) {
  10523. return module = { exports: {} }, fn(module, module.exports), module.exports;
  10524. }
  10525. var lesscHelper = createCommonjsModule(function (module, exports) {
  10526. // lessc_helper.js
  10527. //
  10528. // helper functions for lessc
  10529. var lessc_helper = {
  10530. // Stylize a string
  10531. stylize: function (str, style) {
  10532. var styles = {
  10533. 'reset': [0, 0],
  10534. 'bold': [1, 22],
  10535. 'inverse': [7, 27],
  10536. 'underline': [4, 24],
  10537. 'yellow': [33, 39],
  10538. 'green': [32, 39],
  10539. 'red': [31, 39],
  10540. 'grey': [90, 39]
  10541. };
  10542. return "\u001B[" + styles[style][0] + "m" + str + "\u001B[" + styles[style][1] + "m";
  10543. },
  10544. // Print command line options
  10545. printUsage: function () {
  10546. console.log('usage: lessc [option option=parameter ...] <source> [destination]');
  10547. console.log('');
  10548. console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.');
  10549. console.log('');
  10550. console.log('options:');
  10551. console.log(' -h, --help Prints help (this message) and exit.');
  10552. console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.');
  10553. console.log(' -M, --depends Outputs a makefile import dependency list to stdout.');
  10554. console.log(' --no-color Disables colorized output.');
  10555. console.log(' --ie-compat Enables IE8 compatibility checks.');
  10556. console.log(' --js Enables inline JavaScript in less files');
  10557. console.log(' -l, --lint Syntax check only (lint).');
  10558. console.log(' -s, --silent Suppresses output of error messages.');
  10559. console.log(' --strict-imports Forces evaluation of imports.');
  10560. console.log(' --insecure Allows imports from insecure https hosts.');
  10561. console.log(' -v, --version Prints version number and exit.');
  10562. console.log(' --verbose Be verbose.');
  10563. console.log(' --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).');
  10564. console.log(' --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.');
  10565. console.log(' --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.');
  10566. console.log(' --source-map-include-source Puts the less files into the map instead of referencing them.');
  10567. console.log(' --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.');
  10568. console.log(' --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment');
  10569. console.log(' in generated CSS file.');
  10570. console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls');
  10571. console.log(' Works with or without the relative-urls option.');
  10572. console.log(' -ru=, --rewrite-urls= Rewrites URLs to make them relative to the base less file.');
  10573. console.log(' all|local|off \'all\' rewrites all URLs, \'local\' just those starting with a \'.\'');
  10574. console.log('');
  10575. console.log(' -m=, --math=');
  10576. console.log(' always Less will eagerly perform math operations always.');
  10577. console.log(' parens-division Math performed except for division (/) operator');
  10578. console.log(' parens | strict Math only performed inside parentheses');
  10579. console.log(' strict-legacy Parens required in very strict terms (legacy --strict-math)');
  10580. console.log('');
  10581. console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units');
  10582. console.log(' --strict-units=on|off that cannot be represented.');
  10583. console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.');
  10584. console.log(' --modify-var=\'VAR=VALUE\' Modifies a variable already declared in the file.');
  10585. console.log(' --url-args=\'QUERYSTRING\' Adds params into url tokens (e.g. 42, cb=42 or \'a=1&b=2\')');
  10586. console.log(' --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins');
  10587. console.log(' less-plugin. E.g. the clean css plugin is called less-plugin-clean-css');
  10588. console.log(' once installed (npm install less-plugin-clean-css), use either with');
  10589. console.log(' --plugin=less-plugin-clean-css or just --clean-css');
  10590. console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"');
  10591. console.log(' or --clean-css="advanced"');
  10592. console.log('');
  10593. console.log('-------------------------- Deprecated ----------------');
  10594. console.log(' -sm=on|off Legacy parens-only math. Use --math');
  10595. console.log(' --strict-math=on|off ');
  10596. console.log('');
  10597. console.log(' --line-numbers=TYPE Outputs filename and line numbers.');
  10598. console.log(' TYPE can be either \'comments\', which will output');
  10599. console.log(' the debug info within comments, \'mediaquery\'');
  10600. console.log(' that will output the information within a fake');
  10601. console.log(' media query which is compatible with the SASS');
  10602. console.log(' format, and \'all\' which will do both.');
  10603. console.log(' -x, --compress Compresses output by removing some whitespaces.');
  10604. console.log(' We recommend you use a dedicated minifer like less-plugin-clean-css');
  10605. console.log('');
  10606. console.log('Report bugs to: http://github.com/less/less.js/issues');
  10607. console.log('Home page: <http://lesscss.org/>');
  10608. }
  10609. };
  10610. // Exports helper functions
  10611. for (var h in lessc_helper) {
  10612. if (lessc_helper.hasOwnProperty(h)) {
  10613. exports[h] = lessc_helper[h];
  10614. }
  10615. }
  10616. });
  10617. /**
  10618. * Node Plugin Loader
  10619. */
  10620. var PluginLoader = /** @class */ (function (_super) {
  10621. tslib.__extends(PluginLoader, _super);
  10622. function PluginLoader(less) {
  10623. var _this = _super.call(this) || this;
  10624. _this.less = less;
  10625. _this.require = function (prefix) {
  10626. prefix = path.dirname(prefix);
  10627. return function (id) {
  10628. var str = id.substr(0, 2);
  10629. if (str === '..' || str === './') {
  10630. return require(path.join(prefix, id));
  10631. }
  10632. else {
  10633. return require(id);
  10634. }
  10635. };
  10636. };
  10637. return _this;
  10638. }
  10639. PluginLoader.prototype.loadPlugin = function (filename, basePath, context, environment, fileManager) {
  10640. var prefix = filename.slice(0, 1);
  10641. var explicit = prefix === '.' || prefix === '/' || filename.slice(-3).toLowerCase() === '.js';
  10642. if (!explicit) {
  10643. context.prefixes = ['less-plugin-', ''];
  10644. }
  10645. return new Promise(function (fulfill, reject) {
  10646. fileManager.loadFile(filename, basePath, context, environment).then(function (data) {
  10647. try {
  10648. fulfill(data);
  10649. }
  10650. catch (e) {
  10651. console.log(e);
  10652. reject(e);
  10653. }
  10654. }).catch(function (err) {
  10655. reject(err);
  10656. });
  10657. });
  10658. };
  10659. return PluginLoader;
  10660. }(AbstractPluginLoader));
  10661. // Export a new default each time
  10662. var defaultOptions = (function () { return ({
  10663. /* Inline Javascript - @plugin still allowed */
  10664. javascriptEnabled: false,
  10665. /* Outputs a makefile import dependency list to stdout. */
  10666. depends: false,
  10667. /* (DEPRECATED) Compress using less built-in compression.
  10668. * This does an okay job but does not utilise all the tricks of
  10669. * dedicated css compression. */
  10670. compress: false,
  10671. /* Runs the less parser and just reports errors without any output. */
  10672. lint: false,
  10673. /* Sets available include paths.
  10674. * If the file in an @import rule does not exist at that exact location,
  10675. * less will look for it at the location(s) passed to this option.
  10676. * You might use this for instance to specify a path to a library which
  10677. * you want to be referenced simply and relatively in the less files. */
  10678. paths: [],
  10679. /* color output in the terminal */
  10680. color: true,
  10681. /* The strictImports controls whether the compiler will allow an @import inside of either
  10682. * @media blocks or (a later addition) other selector blocks.
  10683. * See: https://github.com/less/less.js/issues/656 */
  10684. strictImports: false,
  10685. /* Allow Imports from Insecure HTTPS Hosts */
  10686. insecure: false,
  10687. /* Allows you to add a path to every generated import and url in your css.
  10688. * This does not affect less import statements that are processed, just ones
  10689. * that are left in the output css. */
  10690. rootpath: '',
  10691. /* By default URLs are kept as-is, so if you import a file in a sub-directory
  10692. * that references an image, exactly the same URL will be output in the css.
  10693. * This option allows you to re-write URL's in imported files so that the
  10694. * URL is always relative to the base imported file */
  10695. rewriteUrls: false,
  10696. /* How to process math
  10697. * 0 always - eagerly try to solve all operations
  10698. * 1 parens-division - require parens for division "/"
  10699. * 2 parens | strict - require parens for all operations
  10700. * 3 strict-legacy - legacy strict behavior (super-strict)
  10701. */
  10702. math: 0,
  10703. /* Without this option, less attempts to guess at the output unit when it does maths. */
  10704. strictUnits: false,
  10705. /* Effectively the declaration is put at the top of your base Less file,
  10706. * meaning it can be used but it also can be overridden if this variable
  10707. * is defined in the file. */
  10708. globalVars: null,
  10709. /* As opposed to the global variable option, this puts the declaration at the
  10710. * end of your base file, meaning it will override anything defined in your Less file. */
  10711. modifyVars: null,
  10712. /* This option allows you to specify a argument to go on to every URL. */
  10713. urlArgs: ''
  10714. }); });
  10715. var imageSize = (function (environment) {
  10716. function imageSize(functionContext, filePathNode) {
  10717. var filePath = filePathNode.value;
  10718. var currentFileInfo = functionContext.currentFileInfo;
  10719. var currentDirectory = currentFileInfo.rewriteUrls ?
  10720. currentFileInfo.currentDirectory : currentFileInfo.entryPath;
  10721. var fragmentStart = filePath.indexOf('#');
  10722. var fragment = '';
  10723. if (fragmentStart !== -1) {
  10724. fragment = filePath.slice(fragmentStart);
  10725. filePath = filePath.slice(0, fragmentStart);
  10726. }
  10727. var fileManager = environment.getFileManager(filePath, currentDirectory, functionContext.context, environment, true);
  10728. if (!fileManager) {
  10729. throw {
  10730. type: 'File',
  10731. message: "Can not set up FileManager for " + filePathNode
  10732. };
  10733. }
  10734. var fileSync = fileManager.loadFileSync(filePath, currentDirectory, functionContext.context, environment);
  10735. if (fileSync.error) {
  10736. throw fileSync.error;
  10737. }
  10738. var sizeOf = require('image-size');
  10739. return sizeOf(fileSync.filename);
  10740. }
  10741. var imageFunctions = {
  10742. 'image-size': function (filePathNode) {
  10743. var size = imageSize(this, filePathNode);
  10744. return new Expression([
  10745. new Dimension(size.width, 'px'),
  10746. new Dimension(size.height, 'px')
  10747. ]);
  10748. },
  10749. 'image-width': function (filePathNode) {
  10750. var size = imageSize(this, filePathNode);
  10751. return new Dimension(size.width, 'px');
  10752. },
  10753. 'image-height': function (filePathNode) {
  10754. var size = imageSize(this, filePathNode);
  10755. return new Dimension(size.height, 'px');
  10756. }
  10757. };
  10758. functionRegistry.addMultiple(imageFunctions);
  10759. });
  10760. var less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]);
  10761. // allow people to create less with their own environment
  10762. less.createFromEnvironment = createFromEnvironment;
  10763. less.lesscHelper = lesscHelper;
  10764. less.PluginLoader = PluginLoader;
  10765. less.fs = fs$1;
  10766. less.FileManager = FileManager;
  10767. less.UrlFileManager = UrlFileManager;
  10768. // Set up options
  10769. less.options = defaultOptions();
  10770. // provide image-size functionality
  10771. imageSize(less.environment);
  10772. var errno;
  10773. var mkdirp;
  10774. try {
  10775. errno = require('errno');
  10776. }
  10777. catch (err) {
  10778. errno = null;
  10779. }
  10780. var pluginManager = new less.PluginManager(less);
  10781. var fileManager = new less.FileManager();
  10782. var plugins = [];
  10783. var queuePlugins = [];
  10784. var args = process.argv.slice(1);
  10785. var silent = false;
  10786. var verbose = false;
  10787. var options = less.options;
  10788. options.plugins = plugins;
  10789. options.reUsePluginManager = true;
  10790. var sourceMapOptions = {};
  10791. var continueProcessing = true;
  10792. var checkArgFunc = function (arg, option) {
  10793. if (!option) {
  10794. console.error(arg + " option requires a parameter");
  10795. continueProcessing = false;
  10796. process.exitCode = 1;
  10797. return false;
  10798. }
  10799. return true;
  10800. };
  10801. var checkBooleanArg = function (arg) {
  10802. var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg);
  10803. if (!onOff) {
  10804. console.error(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no");
  10805. continueProcessing = false;
  10806. process.exitCode = 1;
  10807. return false;
  10808. }
  10809. return Boolean(onOff[2]);
  10810. };
  10811. var parseVariableOption = function (option, variables) {
  10812. var parts = option.split('=', 2);
  10813. variables[parts[0]] = parts[1];
  10814. };
  10815. var sourceMapFileInline = false;
  10816. function printUsage() {
  10817. less.lesscHelper.printUsage();
  10818. pluginManager.Loader.printUsage(plugins);
  10819. continueProcessing = false;
  10820. }
  10821. function render() {
  10822. if (!continueProcessing) {
  10823. return;
  10824. }
  10825. var input = args[1];
  10826. if (input && input != '-') {
  10827. input = path.resolve(process.cwd(), input);
  10828. }
  10829. var output = args[2];
  10830. var outputbase = args[2];
  10831. if (output) {
  10832. output = path.resolve(process.cwd(), output);
  10833. }
  10834. if (options.sourceMap) {
  10835. sourceMapOptions.sourceMapInputFilename = input;
  10836. if (!sourceMapOptions.sourceMapFullFilename) {
  10837. if (!output && !sourceMapFileInline) {
  10838. console.error('the sourcemap option only has an optional filename if the css filename is given');
  10839. console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css');
  10840. process.exitCode = 1;
  10841. return;
  10842. }
  10843. // its in the same directory, so always just the basename
  10844. if (output) {
  10845. sourceMapOptions.sourceMapOutputFilename = path.basename(output);
  10846. sourceMapOptions.sourceMapFullFilename = output + ".map";
  10847. }
  10848. // its in the same directory, so always just the basename
  10849. if ('sourceMapFullFilename' in sourceMapOptions) {
  10850. sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename);
  10851. }
  10852. }
  10853. else if (options.sourceMap && !sourceMapFileInline) {
  10854. var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename);
  10855. var mapDir = path.dirname(mapFilename);
  10856. var outputDir = path.dirname(output);
  10857. // find the path from the map to the output file
  10858. sourceMapOptions.sourceMapOutputFilename = path.join(path.relative(mapDir, outputDir), path.basename(output));
  10859. // make the sourcemap filename point to the sourcemap relative to the css file output directory
  10860. sourceMapOptions.sourceMapFilename = path.join(path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename));
  10861. }
  10862. }
  10863. if (sourceMapOptions.sourceMapBasepath === undefined) {
  10864. sourceMapOptions.sourceMapBasepath = input ? path.dirname(input) : process.cwd();
  10865. }
  10866. if (sourceMapOptions.sourceMapRootpath === undefined) {
  10867. var pathToMap = path.dirname((sourceMapFileInline ? output : sourceMapOptions.sourceMapFullFilename) || '.');
  10868. var pathToInput = path.dirname(sourceMapOptions.sourceMapInputFilename || '.');
  10869. sourceMapOptions.sourceMapRootpath = path.relative(pathToMap, pathToInput);
  10870. }
  10871. if (!input) {
  10872. console.error('lessc: no input files');
  10873. console.error('');
  10874. printUsage();
  10875. process.exitCode = 1;
  10876. return;
  10877. }
  10878. var ensureDirectory = function (filepath) {
  10879. var dir = path.dirname(filepath);
  10880. var cmd;
  10881. var existsSync = fs$1.existsSync || path.existsSync;
  10882. if (!existsSync(dir)) {
  10883. if (mkdirp === undefined) {
  10884. try {
  10885. mkdirp = require('mkdirp');
  10886. }
  10887. catch (e) {
  10888. mkdirp = null;
  10889. }
  10890. }
  10891. cmd = mkdirp && mkdirp.sync || fs$1.mkdirSync;
  10892. cmd(dir);
  10893. }
  10894. };
  10895. if (options.depends) {
  10896. if (!outputbase) {
  10897. console.error('option --depends requires an output path to be specified');
  10898. process.exitCode = 1;
  10899. return;
  10900. }
  10901. process.stdout.write(outputbase + ": ");
  10902. }
  10903. if (!sourceMapFileInline) {
  10904. var writeSourceMap = function (output, onDone) {
  10905. if (output === void 0) { output = ''; }
  10906. var filename = sourceMapOptions.sourceMapFullFilename;
  10907. ensureDirectory(filename);
  10908. fs$1.writeFile(filename, output, 'utf8', function (err) {
  10909. if (err) {
  10910. var description = 'Error: ';
  10911. if (errno && errno.errno[err.errno]) {
  10912. description += errno.errno[err.errno].description;
  10913. }
  10914. else {
  10915. description += err.code + " " + err.message;
  10916. }
  10917. console.error("lessc: failed to create file " + filename);
  10918. console.error(description);
  10919. process.exitCode = 1;
  10920. }
  10921. else {
  10922. less.logger.info("lessc: wrote " + filename);
  10923. }
  10924. onDone();
  10925. });
  10926. };
  10927. }
  10928. var writeSourceMapIfNeeded = function (output, onDone) {
  10929. if (options.sourceMap && !sourceMapFileInline) {
  10930. writeSourceMap(output, onDone);
  10931. }
  10932. else {
  10933. onDone();
  10934. }
  10935. };
  10936. var writeOutput = function (output, result, onSuccess) {
  10937. if (options.depends) {
  10938. onSuccess();
  10939. }
  10940. else if (output) {
  10941. ensureDirectory(output);
  10942. fs$1.writeFile(output, result.css, { encoding: 'utf8' }, function (err) {
  10943. if (err) {
  10944. var description = 'Error: ';
  10945. if (errno && errno.errno[err.errno]) {
  10946. description += errno.errno[err.errno].description;
  10947. }
  10948. else {
  10949. description += err.code + " " + err.message;
  10950. }
  10951. console.error("lessc: failed to create file " + output);
  10952. console.error(description);
  10953. process.exitCode = 1;
  10954. }
  10955. else {
  10956. less.logger.info("lessc: wrote " + output);
  10957. onSuccess();
  10958. }
  10959. });
  10960. }
  10961. else if (!options.depends) {
  10962. process.stdout.write(result.css);
  10963. onSuccess();
  10964. }
  10965. };
  10966. var logDependencies = function (options, result) {
  10967. if (options.depends) {
  10968. var depends = '';
  10969. for (var i_1 = 0; i_1 < result.imports.length; i_1++) {
  10970. depends += result.imports[i_1] + " ";
  10971. }
  10972. console.log(depends);
  10973. }
  10974. };
  10975. var parseLessFile = function (e, data) {
  10976. if (e) {
  10977. console.error("lessc: " + e.message);
  10978. process.exitCode = 1;
  10979. return;
  10980. }
  10981. data = data.replace(/^\uFEFF/, '');
  10982. options.paths = [path.dirname(input)].concat(options.paths);
  10983. options.filename = input;
  10984. if (options.lint) {
  10985. options.sourceMap = false;
  10986. }
  10987. sourceMapOptions.sourceMapFileInline = sourceMapFileInline;
  10988. if (options.sourceMap) {
  10989. options.sourceMap = sourceMapOptions;
  10990. }
  10991. less.logger.addListener({
  10992. info: function (msg) {
  10993. if (verbose) {
  10994. console.log(msg);
  10995. }
  10996. },
  10997. warn: function (msg) {
  10998. // do not show warning if the silent option is used
  10999. if (!silent) {
  11000. console.warn(msg);
  11001. }
  11002. },
  11003. error: function (msg) {
  11004. console.error(msg);
  11005. }
  11006. });
  11007. less.render(data, options)
  11008. .then(function (result) {
  11009. if (!options.lint) {
  11010. writeOutput(output, result, function () {
  11011. writeSourceMapIfNeeded(result.map, function () {
  11012. logDependencies(options, result);
  11013. });
  11014. });
  11015. }
  11016. }, function (err) {
  11017. if (!options.silent) {
  11018. console.error(err.toString({
  11019. stylize: options.color && less.lesscHelper.stylize
  11020. }));
  11021. }
  11022. process.exitCode = 1;
  11023. });
  11024. };
  11025. if (input != '-') {
  11026. fs$1.readFile(input, 'utf8', parseLessFile);
  11027. }
  11028. else {
  11029. process.stdin.resume();
  11030. process.stdin.setEncoding('utf8');
  11031. var buffer_1 = '';
  11032. process.stdin.on('data', function (data) {
  11033. buffer_1 += data;
  11034. });
  11035. process.stdin.on('end', function () {
  11036. parseLessFile(false, buffer_1);
  11037. });
  11038. }
  11039. }
  11040. function processPluginQueue() {
  11041. var x = 0;
  11042. function pluginError(name) {
  11043. console.error("Unable to load plugin " + name + " please make sure that it is installed under or at the same level as less");
  11044. process.exitCode = 1;
  11045. }
  11046. function pluginFinished(plugin) {
  11047. x++;
  11048. plugins.push(plugin);
  11049. if (x === queuePlugins.length) {
  11050. render();
  11051. }
  11052. }
  11053. queuePlugins.forEach(function (queue) {
  11054. var context = clone(options);
  11055. pluginManager.Loader.loadPlugin(queue.name, process.cwd(), context, less.environment, fileManager)
  11056. .then(function (data) {
  11057. pluginFinished({
  11058. fileContent: data.contents,
  11059. filename: data.filename,
  11060. options: queue.options
  11061. });
  11062. })
  11063. .catch(function () {
  11064. pluginError(queue.name);
  11065. });
  11066. });
  11067. }
  11068. // self executing function so we can return
  11069. (function () {
  11070. args = args.filter(function (arg) {
  11071. var match;
  11072. match = arg.match(/^-I(.+)$/);
  11073. if (match) {
  11074. options.paths.push(match[1]);
  11075. return false;
  11076. }
  11077. match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i);
  11078. if (match) {
  11079. arg = match[1];
  11080. }
  11081. else {
  11082. return arg;
  11083. }
  11084. switch (arg) {
  11085. case 'v':
  11086. case 'version':
  11087. console.log("lessc " + less.version.join('.') + " (Less Compiler) [JavaScript]");
  11088. continueProcessing = false;
  11089. break;
  11090. case 'verbose':
  11091. verbose = true;
  11092. break;
  11093. case 's':
  11094. case 'silent':
  11095. silent = true;
  11096. break;
  11097. case 'l':
  11098. case 'lint':
  11099. options.lint = true;
  11100. break;
  11101. case 'strict-imports':
  11102. options.strictImports = true;
  11103. break;
  11104. case 'h':
  11105. case 'help':
  11106. printUsage();
  11107. break;
  11108. case 'x':
  11109. case 'compress':
  11110. options.compress = true;
  11111. break;
  11112. case 'insecure':
  11113. options.insecure = true;
  11114. break;
  11115. case 'M':
  11116. case 'depends':
  11117. options.depends = true;
  11118. break;
  11119. case 'max-line-len':
  11120. if (checkArgFunc(arg, match[2])) {
  11121. options.maxLineLen = parseInt(match[2], 10);
  11122. if (options.maxLineLen <= 0) {
  11123. options.maxLineLen = -1;
  11124. }
  11125. }
  11126. break;
  11127. case 'no-color':
  11128. options.color = false;
  11129. break;
  11130. case 'js':
  11131. options.javascriptEnabled = true;
  11132. break;
  11133. case 'no-js':
  11134. console.error('The "--no-js" argument is deprecated, as inline JavaScript ' +
  11135. 'is disabled by default. Use "--js" to enable inline JavaScript (not recommended).');
  11136. break;
  11137. case 'include-path':
  11138. if (checkArgFunc(arg, match[2])) {
  11139. // ; supported on windows.
  11140. // : supported on windows and linux, excluding a drive letter like C:\ so C:\file:D:\file parses to 2
  11141. options.paths = match[2]
  11142. .split(os.type().match(/Windows/) ? /:(?!\\)|;/ : ':')
  11143. .map(function (p) {
  11144. if (p) {
  11145. return path.resolve(process.cwd(), p);
  11146. }
  11147. });
  11148. }
  11149. break;
  11150. case 'line-numbers':
  11151. if (checkArgFunc(arg, match[2])) {
  11152. options.dumpLineNumbers = match[2];
  11153. }
  11154. break;
  11155. case 'source-map':
  11156. options.sourceMap = true;
  11157. if (match[2]) {
  11158. sourceMapOptions.sourceMapFullFilename = match[2];
  11159. }
  11160. break;
  11161. case 'source-map-rootpath':
  11162. if (checkArgFunc(arg, match[2])) {
  11163. sourceMapOptions.sourceMapRootpath = match[2];
  11164. }
  11165. break;
  11166. case 'source-map-basepath':
  11167. if (checkArgFunc(arg, match[2])) {
  11168. sourceMapOptions.sourceMapBasepath = match[2];
  11169. }
  11170. break;
  11171. case 'source-map-inline':
  11172. case 'source-map-map-inline':
  11173. sourceMapFileInline = true;
  11174. options.sourceMap = true;
  11175. break;
  11176. case 'source-map-include-source':
  11177. case 'source-map-less-inline':
  11178. sourceMapOptions.outputSourceFiles = true;
  11179. break;
  11180. case 'source-map-url':
  11181. if (checkArgFunc(arg, match[2])) {
  11182. sourceMapOptions.sourceMapURL = match[2];
  11183. }
  11184. break;
  11185. case 'rp':
  11186. case 'rootpath':
  11187. if (checkArgFunc(arg, match[2])) {
  11188. options.rootpath = match[2].replace(/\\/g, '/');
  11189. }
  11190. break;
  11191. case 'relative-urls':
  11192. console.warn('The --relative-urls option has been deprecated. Use --rewrite-urls=all.');
  11193. options.rewriteUrls = RewriteUrls.ALL;
  11194. break;
  11195. case 'ru':
  11196. case 'rewrite-urls':
  11197. var m = match[2];
  11198. if (m) {
  11199. if (m === 'local') {
  11200. options.rewriteUrls = RewriteUrls.LOCAL;
  11201. }
  11202. else if (m === 'off') {
  11203. options.rewriteUrls = RewriteUrls.OFF;
  11204. }
  11205. else if (m === 'all') {
  11206. options.rewriteUrls = RewriteUrls.ALL;
  11207. }
  11208. else {
  11209. console.error("Unknown rewrite-urls argument " + m);
  11210. continueProcessing = false;
  11211. process.exitCode = 1;
  11212. }
  11213. }
  11214. else {
  11215. options.rewriteUrls = RewriteUrls.ALL;
  11216. }
  11217. break;
  11218. case 'sm':
  11219. case 'strict-math':
  11220. console.warn('The --strict-math option has been deprecated. Use --math=strict.');
  11221. if (checkArgFunc(arg, match[2])) {
  11222. if (checkBooleanArg(match[2])) {
  11223. options.math = Math$1.STRICT_LEGACY;
  11224. }
  11225. }
  11226. break;
  11227. case 'm':
  11228. case 'math':
  11229. if (checkArgFunc(arg, match[2])) {
  11230. options.math = match[2];
  11231. }
  11232. break;
  11233. case 'su':
  11234. case 'strict-units':
  11235. if (checkArgFunc(arg, match[2])) {
  11236. options.strictUnits = checkBooleanArg(match[2]);
  11237. }
  11238. break;
  11239. case 'global-var':
  11240. if (checkArgFunc(arg, match[2])) {
  11241. if (!options.globalVars) {
  11242. options.globalVars = {};
  11243. }
  11244. parseVariableOption(match[2], options.globalVars);
  11245. }
  11246. break;
  11247. case 'modify-var':
  11248. if (checkArgFunc(arg, match[2])) {
  11249. if (!options.modifyVars) {
  11250. options.modifyVars = {};
  11251. }
  11252. parseVariableOption(match[2], options.modifyVars);
  11253. }
  11254. break;
  11255. case 'url-args':
  11256. if (checkArgFunc(arg, match[2])) {
  11257. options.urlArgs = match[2];
  11258. }
  11259. break;
  11260. case 'plugin':
  11261. var splitupArg = match[2].match(/^([^=]+)(=(.*))?/);
  11262. var name_1 = splitupArg[1];
  11263. var pluginOptions = splitupArg[3];
  11264. queuePlugins.push({ name: name_1, options: pluginOptions });
  11265. break;
  11266. default:
  11267. queuePlugins.push({ name: arg, options: match[2], default: true });
  11268. break;
  11269. }
  11270. });
  11271. if (queuePlugins.length > 0) {
  11272. processPluginQueue();
  11273. }
  11274. else {
  11275. render();
  11276. }
  11277. })();