less.js 372 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835
  1. /*!
  2. * Less - Leaner CSS v2.7.3
  3. * http://lesscss.org
  4. *
  5. * Copyright (c) 2009-2017, Alexis Sellier <self@cloudhead.net>
  6. * Licensed under the Apache-2.0 License.
  7. *
  8. */
  9. /** * @license Apache-2.0
  10. */
  11. (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.less = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  12. var addDataAttr = require("./utils").addDataAttr,
  13. browser = require("./browser");
  14. module.exports = function(window, options) {
  15. // use options from the current script tag data attribues
  16. addDataAttr(options, browser.currentScript(window));
  17. if (options.isFileProtocol === undefined) {
  18. options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);
  19. }
  20. // Load styles asynchronously (default: false)
  21. //
  22. // This is set to `false` by default, so that the body
  23. // doesn't start loading before the stylesheets are parsed.
  24. // Setting this to `true` can result in flickering.
  25. //
  26. options.async = options.async || false;
  27. options.fileAsync = options.fileAsync || false;
  28. // Interval between watch polls
  29. options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);
  30. options.env = options.env || (window.location.hostname == '127.0.0.1' ||
  31. window.location.hostname == '0.0.0.0' ||
  32. window.location.hostname == 'localhost' ||
  33. (window.location.port &&
  34. window.location.port.length > 0) ||
  35. options.isFileProtocol ? 'development'
  36. : 'production');
  37. var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);
  38. if (dumpLineNumbers) {
  39. options.dumpLineNumbers = dumpLineNumbers[1];
  40. }
  41. if (options.useFileCache === undefined) {
  42. options.useFileCache = true;
  43. }
  44. if (options.onReady === undefined) {
  45. options.onReady = true;
  46. }
  47. };
  48. },{"./browser":3,"./utils":10}],2:[function(require,module,exports){
  49. /**
  50. * Kicks off less and compiles any stylesheets
  51. * used in the browser distributed version of less
  52. * to kick-start less using the browser api
  53. */
  54. /*global window, document */
  55. // shim Promise if required
  56. require('promise/polyfill.js');
  57. var options = window.less || {};
  58. require("./add-default-options")(window, options);
  59. var less = module.exports = require("./index")(window, options);
  60. window.less = less;
  61. var css, head, style;
  62. // Always restore page visibility
  63. function resolveOrReject(data) {
  64. if (data.filename) {
  65. console.warn(data);
  66. }
  67. if (!options.async) {
  68. head.removeChild(style);
  69. }
  70. }
  71. if (options.onReady) {
  72. if (/!watch/.test(window.location.hash)) {
  73. less.watch();
  74. }
  75. // Simulate synchronous stylesheet loading by blocking page rendering
  76. if (!options.async) {
  77. css = 'body { display: none !important }';
  78. head = document.head || document.getElementsByTagName('head')[0];
  79. style = document.createElement('style');
  80. style.type = 'text/css';
  81. if (style.styleSheet) {
  82. style.styleSheet.cssText = css;
  83. } else {
  84. style.appendChild(document.createTextNode(css));
  85. }
  86. head.appendChild(style);
  87. }
  88. less.registerStylesheetsImmediately();
  89. less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);
  90. }
  91. },{"./add-default-options":1,"./index":8,"promise/polyfill.js":97}],3:[function(require,module,exports){
  92. var utils = require("./utils");
  93. module.exports = {
  94. createCSS: function (document, styles, sheet) {
  95. // Strip the query-string
  96. var href = sheet.href || '';
  97. // If there is no title set, use the filename, minus the extension
  98. var id = 'less:' + (sheet.title || utils.extractId(href));
  99. // If this has already been inserted into the DOM, we may need to replace it
  100. var oldStyleNode = document.getElementById(id);
  101. var keepOldStyleNode = false;
  102. // Create a new stylesheet node for insertion or (if necessary) replacement
  103. var styleNode = document.createElement('style');
  104. styleNode.setAttribute('type', 'text/css');
  105. if (sheet.media) {
  106. styleNode.setAttribute('media', sheet.media);
  107. }
  108. styleNode.id = id;
  109. if (!styleNode.styleSheet) {
  110. styleNode.appendChild(document.createTextNode(styles));
  111. // If new contents match contents of oldStyleNode, don't replace oldStyleNode
  112. keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&
  113. oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);
  114. }
  115. var head = document.getElementsByTagName('head')[0];
  116. // If there is no oldStyleNode, just append; otherwise, only append if we need
  117. // to replace oldStyleNode with an updated stylesheet
  118. if (oldStyleNode === null || keepOldStyleNode === false) {
  119. var nextEl = sheet && sheet.nextSibling || null;
  120. if (nextEl) {
  121. nextEl.parentNode.insertBefore(styleNode, nextEl);
  122. } else {
  123. head.appendChild(styleNode);
  124. }
  125. }
  126. if (oldStyleNode && keepOldStyleNode === false) {
  127. oldStyleNode.parentNode.removeChild(oldStyleNode);
  128. }
  129. // For IE.
  130. // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
  131. // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
  132. if (styleNode.styleSheet) {
  133. try {
  134. styleNode.styleSheet.cssText = styles;
  135. } catch (e) {
  136. throw new Error("Couldn't reassign styleSheet.cssText.");
  137. }
  138. }
  139. },
  140. currentScript: function(window) {
  141. var document = window.document;
  142. return document.currentScript || (function() {
  143. var scripts = document.getElementsByTagName("script");
  144. return scripts[scripts.length - 1];
  145. })();
  146. }
  147. };
  148. },{"./utils":10}],4:[function(require,module,exports){
  149. // Cache system is a bit outdated and could do with work
  150. module.exports = function(window, options, logger) {
  151. var cache = null;
  152. if (options.env !== 'development') {
  153. try {
  154. cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;
  155. } catch (_) {}
  156. }
  157. return {
  158. setCSS: function(path, lastModified, modifyVars, styles) {
  159. if (cache) {
  160. logger.info('saving ' + path + ' to cache.');
  161. try {
  162. cache.setItem(path, styles);
  163. cache.setItem(path + ':timestamp', lastModified);
  164. if (modifyVars) {
  165. cache.setItem(path + ':vars', JSON.stringify(modifyVars));
  166. }
  167. } catch(e) {
  168. //TODO - could do with adding more robust error handling
  169. logger.error('failed to save "' + path + '" to local storage for caching.');
  170. }
  171. }
  172. },
  173. getCSS: function(path, webInfo, modifyVars) {
  174. var css = cache && cache.getItem(path),
  175. timestamp = cache && cache.getItem(path + ':timestamp'),
  176. vars = cache && cache.getItem(path + ':vars');
  177. modifyVars = modifyVars || {};
  178. if (timestamp && webInfo.lastModified &&
  179. (new Date(webInfo.lastModified).valueOf() ===
  180. new Date(timestamp).valueOf()) &&
  181. (!modifyVars && !vars || JSON.stringify(modifyVars) === vars)) {
  182. // Use local copy
  183. return css;
  184. }
  185. }
  186. };
  187. };
  188. },{}],5:[function(require,module,exports){
  189. var utils = require("./utils"),
  190. browser = require("./browser");
  191. module.exports = function(window, less, options) {
  192. function errorHTML(e, rootHref) {
  193. var id = 'less-error-message:' + utils.extractId(rootHref || "");
  194. var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
  195. var elem = window.document.createElement('div'), timer, content, errors = [];
  196. var filename = e.filename || rootHref;
  197. var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
  198. elem.id = id;
  199. elem.className = "less-error-message";
  200. content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
  201. '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
  202. var errorline = function (e, i, classname) {
  203. if (e.extract[i] !== undefined) {
  204. errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
  205. .replace(/\{class\}/, classname)
  206. .replace(/\{content\}/, e.extract[i]));
  207. }
  208. };
  209. if (e.extract) {
  210. errorline(e, 0, '');
  211. errorline(e, 1, 'line');
  212. errorline(e, 2, '');
  213. content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
  214. '<ul>' + errors.join('') + '</ul>';
  215. }
  216. if (e.stack && (e.extract || options.logLevel >= 4)) {
  217. content += '<br/>Stack Trace</br />' + e.stack.split('\n').slice(1).join('<br/>');
  218. }
  219. elem.innerHTML = content;
  220. // CSS for error messages
  221. browser.createCSS(window.document, [
  222. '.less-error-message ul, .less-error-message li {',
  223. 'list-style-type: none;',
  224. 'margin-right: 15px;',
  225. 'padding: 4px 0;',
  226. 'margin: 0;',
  227. '}',
  228. '.less-error-message label {',
  229. 'font-size: 12px;',
  230. 'margin-right: 15px;',
  231. 'padding: 4px 0;',
  232. 'color: #cc7777;',
  233. '}',
  234. '.less-error-message pre {',
  235. 'color: #dd6666;',
  236. 'padding: 4px 0;',
  237. 'margin: 0;',
  238. 'display: inline-block;',
  239. '}',
  240. '.less-error-message pre.line {',
  241. 'color: #ff0000;',
  242. '}',
  243. '.less-error-message h3 {',
  244. 'font-size: 20px;',
  245. 'font-weight: bold;',
  246. 'padding: 15px 0 5px 0;',
  247. 'margin: 0;',
  248. '}',
  249. '.less-error-message a {',
  250. 'color: #10a',
  251. '}',
  252. '.less-error-message .error {',
  253. 'color: red;',
  254. 'font-weight: bold;',
  255. 'padding-bottom: 2px;',
  256. 'border-bottom: 1px dashed red;',
  257. '}'
  258. ].join('\n'), { title: 'error-message' });
  259. elem.style.cssText = [
  260. "font-family: Arial, sans-serif",
  261. "border: 1px solid #e00",
  262. "background-color: #eee",
  263. "border-radius: 5px",
  264. "-webkit-border-radius: 5px",
  265. "-moz-border-radius: 5px",
  266. "color: #e00",
  267. "padding: 15px",
  268. "margin-bottom: 15px"
  269. ].join(';');
  270. if (options.env === 'development') {
  271. timer = setInterval(function () {
  272. var document = window.document,
  273. body = document.body;
  274. if (body) {
  275. if (document.getElementById(id)) {
  276. body.replaceChild(elem, document.getElementById(id));
  277. } else {
  278. body.insertBefore(elem, body.firstChild);
  279. }
  280. clearInterval(timer);
  281. }
  282. }, 10);
  283. }
  284. }
  285. function removeErrorHTML(path) {
  286. var node = window.document.getElementById('less-error-message:' + utils.extractId(path));
  287. if (node) {
  288. node.parentNode.removeChild(node);
  289. }
  290. }
  291. function removeErrorConsole(path) {
  292. //no action
  293. }
  294. function removeError(path) {
  295. if (!options.errorReporting || options.errorReporting === "html") {
  296. removeErrorHTML(path);
  297. } else if (options.errorReporting === "console") {
  298. removeErrorConsole(path);
  299. } else if (typeof options.errorReporting === 'function') {
  300. options.errorReporting("remove", path);
  301. }
  302. }
  303. function errorConsole(e, rootHref) {
  304. var template = '{line} {content}';
  305. var filename = e.filename || rootHref;
  306. var errors = [];
  307. var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
  308. " in " + filename + " ";
  309. var errorline = function (e, i, classname) {
  310. if (e.extract[i] !== undefined) {
  311. errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
  312. .replace(/\{class\}/, classname)
  313. .replace(/\{content\}/, e.extract[i]));
  314. }
  315. };
  316. if (e.extract) {
  317. errorline(e, 0, '');
  318. errorline(e, 1, 'line');
  319. errorline(e, 2, '');
  320. content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' +
  321. errors.join('\n');
  322. }
  323. if (e.stack && (e.extract || options.logLevel >= 4)) {
  324. content += '\nStack Trace\n' + e.stack;
  325. }
  326. less.logger.error(content);
  327. }
  328. function error(e, rootHref) {
  329. if (!options.errorReporting || options.errorReporting === "html") {
  330. errorHTML(e, rootHref);
  331. } else if (options.errorReporting === "console") {
  332. errorConsole(e, rootHref);
  333. } else if (typeof options.errorReporting === 'function') {
  334. options.errorReporting("add", e, rootHref);
  335. }
  336. }
  337. return {
  338. add: error,
  339. remove: removeError
  340. };
  341. };
  342. },{"./browser":3,"./utils":10}],6:[function(require,module,exports){
  343. /*global window, XMLHttpRequest */
  344. module.exports = function(options, logger) {
  345. var AbstractFileManager = require("../less/environment/abstract-file-manager.js");
  346. var fileCache = {};
  347. //TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load
  348. function getXMLHttpRequest() {
  349. if (window.XMLHttpRequest && (window.location.protocol !== "file:" || !("ActiveXObject" in window))) {
  350. return new XMLHttpRequest();
  351. } else {
  352. try {
  353. /*global ActiveXObject */
  354. return new ActiveXObject("Microsoft.XMLHTTP");
  355. } catch (e) {
  356. logger.error("browser doesn't support AJAX.");
  357. return null;
  358. }
  359. }
  360. }
  361. var FileManager = function() {
  362. };
  363. FileManager.prototype = new AbstractFileManager();
  364. FileManager.prototype.alwaysMakePathsAbsolute = function alwaysMakePathsAbsolute() {
  365. return true;
  366. };
  367. FileManager.prototype.join = function join(basePath, laterPath) {
  368. if (!basePath) {
  369. return laterPath;
  370. }
  371. return this.extractUrlParts(laterPath, basePath).path;
  372. };
  373. FileManager.prototype.doXHR = function doXHR(url, type, callback, errback) {
  374. var xhr = getXMLHttpRequest();
  375. var async = options.isFileProtocol ? options.fileAsync : true;
  376. if (typeof xhr.overrideMimeType === 'function') {
  377. xhr.overrideMimeType('text/css');
  378. }
  379. logger.debug("XHR: Getting '" + url + "'");
  380. xhr.open('GET', url, async);
  381. xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
  382. xhr.send(null);
  383. function handleResponse(xhr, callback, errback) {
  384. if (xhr.status >= 200 && xhr.status < 300) {
  385. callback(xhr.responseText,
  386. xhr.getResponseHeader("Last-Modified"));
  387. } else if (typeof errback === 'function') {
  388. errback(xhr.status, url);
  389. }
  390. }
  391. if (options.isFileProtocol && !options.fileAsync) {
  392. if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {
  393. callback(xhr.responseText);
  394. } else {
  395. errback(xhr.status, url);
  396. }
  397. } else if (async) {
  398. xhr.onreadystatechange = function () {
  399. if (xhr.readyState == 4) {
  400. handleResponse(xhr, callback, errback);
  401. }
  402. };
  403. } else {
  404. handleResponse(xhr, callback, errback);
  405. }
  406. };
  407. FileManager.prototype.supports = function(filename, currentDirectory, options, environment) {
  408. return true;
  409. };
  410. FileManager.prototype.clearFileCache = function() {
  411. fileCache = {};
  412. };
  413. FileManager.prototype.loadFile = function loadFile(filename, currentDirectory, options, environment, callback) {
  414. if (currentDirectory && !this.isPathAbsolute(filename)) {
  415. filename = currentDirectory + filename;
  416. }
  417. options = options || {};
  418. // sheet may be set to the stylesheet for the initial load or a collection of properties including
  419. // some context variables for imports
  420. var hrefParts = this.extractUrlParts(filename, window.location.href);
  421. var href = hrefParts.url;
  422. if (options.useFileCache && fileCache[href]) {
  423. try {
  424. var lessText = fileCache[href];
  425. callback(null, { contents: lessText, filename: href, webInfo: { lastModified: new Date() }});
  426. } catch (e) {
  427. callback({filename: href, message: "Error loading file " + href + " error was " + e.message});
  428. }
  429. return;
  430. }
  431. this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {
  432. // per file cache
  433. fileCache[href] = data;
  434. // Use remote copy (re-parse)
  435. callback(null, { contents: data, filename: href, webInfo: { lastModified: lastModified }});
  436. }, function doXHRError(status, url) {
  437. callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href });
  438. });
  439. };
  440. return FileManager;
  441. };
  442. },{"../less/environment/abstract-file-manager.js":15}],7:[function(require,module,exports){
  443. module.exports = function() {
  444. var functionRegistry = require("./../less/functions/function-registry");
  445. function imageSize() {
  446. throw {
  447. type: "Runtime",
  448. message: "Image size functions are not supported in browser version of less"
  449. };
  450. }
  451. var imageFunctions = {
  452. "image-size": function(filePathNode) {
  453. imageSize(this, filePathNode);
  454. return -1;
  455. },
  456. "image-width": function(filePathNode) {
  457. imageSize(this, filePathNode);
  458. return -1;
  459. },
  460. "image-height": function(filePathNode) {
  461. imageSize(this, filePathNode);
  462. return -1;
  463. }
  464. };
  465. functionRegistry.addMultiple(imageFunctions);
  466. };
  467. },{"./../less/functions/function-registry":22}],8:[function(require,module,exports){
  468. //
  469. // index.js
  470. // Should expose the additional browser functions on to the less object
  471. //
  472. var addDataAttr = require("./utils").addDataAttr,
  473. browser = require("./browser");
  474. module.exports = function(window, options) {
  475. var document = window.document;
  476. var less = require('../less')();
  477. //module.exports = less;
  478. less.options = options;
  479. var environment = less.environment,
  480. FileManager = require("./file-manager")(options, less.logger),
  481. fileManager = new FileManager();
  482. environment.addFileManager(fileManager);
  483. less.FileManager = FileManager;
  484. require("./log-listener")(less, options);
  485. var errors = require("./error-reporting")(window, less, options);
  486. var cache = less.cache = options.cache || require("./cache")(window, options, less.logger);
  487. require('./image-size')(less.environment);
  488. //Setup user functions
  489. if (options.functions) {
  490. less.functions.functionRegistry.addMultiple(options.functions);
  491. }
  492. var typePattern = /^text\/(x-)?less$/;
  493. function postProcessCSS(styles) { // deprecated, use a plugin for postprocesstasks
  494. if (options.postProcessor && typeof options.postProcessor === 'function') {
  495. styles = options.postProcessor.call(styles, styles) || styles;
  496. }
  497. return styles;
  498. }
  499. function clone(obj) {
  500. var cloned = {};
  501. for (var prop in obj) {
  502. if (obj.hasOwnProperty(prop)) {
  503. cloned[prop] = obj[prop];
  504. }
  505. }
  506. return cloned;
  507. }
  508. // only really needed for phantom
  509. function bind(func, thisArg) {
  510. var curryArgs = Array.prototype.slice.call(arguments, 2);
  511. return function() {
  512. var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));
  513. return func.apply(thisArg, args);
  514. };
  515. }
  516. function loadStyles(modifyVars) {
  517. var styles = document.getElementsByTagName('style'),
  518. style;
  519. for (var i = 0; i < styles.length; i++) {
  520. style = styles[i];
  521. if (style.type.match(typePattern)) {
  522. var instanceOptions = clone(options);
  523. instanceOptions.modifyVars = modifyVars;
  524. var lessText = style.innerHTML || '';
  525. instanceOptions.filename = document.location.href.replace(/#.*$/, '');
  526. /*jshint loopfunc:true */
  527. // use closure to store current style
  528. less.render(lessText, instanceOptions,
  529. bind(function(style, e, result) {
  530. if (e) {
  531. errors.add(e, "inline");
  532. } else {
  533. style.type = 'text/css';
  534. if (style.styleSheet) {
  535. style.styleSheet.cssText = result.css;
  536. } else {
  537. style.innerHTML = result.css;
  538. }
  539. }
  540. }, null, style));
  541. }
  542. }
  543. }
  544. function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
  545. var instanceOptions = clone(options);
  546. addDataAttr(instanceOptions, sheet);
  547. instanceOptions.mime = sheet.type;
  548. if (modifyVars) {
  549. instanceOptions.modifyVars = modifyVars;
  550. }
  551. function loadInitialFileCallback(loadedFile) {
  552. var data = loadedFile.contents,
  553. path = loadedFile.filename,
  554. webInfo = loadedFile.webInfo;
  555. var newFileInfo = {
  556. currentDirectory: fileManager.getPath(path),
  557. filename: path,
  558. rootFilename: path,
  559. relativeUrls: instanceOptions.relativeUrls};
  560. newFileInfo.entryPath = newFileInfo.currentDirectory;
  561. newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;
  562. if (webInfo) {
  563. webInfo.remaining = remaining;
  564. var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);
  565. if (!reload && css) {
  566. webInfo.local = true;
  567. callback(null, css, data, sheet, webInfo, path);
  568. return;
  569. }
  570. }
  571. //TODO add tests around how this behaves when reloading
  572. errors.remove(path);
  573. instanceOptions.rootFileInfo = newFileInfo;
  574. less.render(data, instanceOptions, function(e, result) {
  575. if (e) {
  576. e.href = path;
  577. callback(e);
  578. } else {
  579. result.css = postProcessCSS(result.css);
  580. cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);
  581. callback(null, result.css, data, sheet, webInfo, path);
  582. }
  583. });
  584. }
  585. fileManager.loadFile(sheet.href, null, instanceOptions, environment, function(e, loadedFile) {
  586. if (e) {
  587. callback(e);
  588. return;
  589. }
  590. loadInitialFileCallback(loadedFile);
  591. });
  592. }
  593. function loadStyleSheets(callback, reload, modifyVars) {
  594. for (var i = 0; i < less.sheets.length; i++) {
  595. loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);
  596. }
  597. }
  598. function initRunningMode() {
  599. if (less.env === 'development') {
  600. less.watchTimer = setInterval(function () {
  601. if (less.watchMode) {
  602. fileManager.clearFileCache();
  603. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  604. if (e) {
  605. errors.add(e, e.href || sheet.href);
  606. } else if (css) {
  607. browser.createCSS(window.document, css, sheet);
  608. }
  609. });
  610. }
  611. }, options.poll);
  612. }
  613. }
  614. //
  615. // Watch mode
  616. //
  617. less.watch = function () {
  618. if (!less.watchMode ) {
  619. less.env = 'development';
  620. initRunningMode();
  621. }
  622. this.watchMode = true;
  623. return true;
  624. };
  625. less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };
  626. //
  627. // Synchronously get all <link> tags with the 'rel' attribute set to
  628. // "stylesheet/less".
  629. //
  630. less.registerStylesheetsImmediately = function() {
  631. var links = document.getElementsByTagName('link');
  632. less.sheets = [];
  633. for (var i = 0; i < links.length; i++) {
  634. if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&
  635. (links[i].type.match(typePattern)))) {
  636. less.sheets.push(links[i]);
  637. }
  638. }
  639. };
  640. //
  641. // Asynchronously get all <link> tags with the 'rel' attribute set to
  642. // "stylesheet/less", returning a Promise.
  643. //
  644. less.registerStylesheets = function() {
  645. return new Promise(function(resolve, reject) {
  646. less.registerStylesheetsImmediately();
  647. resolve();
  648. });
  649. };
  650. //
  651. // With this function, it's possible to alter variables and re-render
  652. // CSS without reloading less-files
  653. //
  654. less.modifyVars = function(record) {
  655. return less.refresh(true, record, false);
  656. };
  657. less.refresh = function (reload, modifyVars, clearFileCache) {
  658. if ((reload || clearFileCache) && clearFileCache !== false) {
  659. fileManager.clearFileCache();
  660. }
  661. return new Promise(function (resolve, reject) {
  662. var startTime, endTime, totalMilliseconds, remainingSheets;
  663. startTime = endTime = new Date();
  664. // Set counter for remaining unprocessed sheets
  665. remainingSheets = less.sheets.length;
  666. if (remainingSheets === 0) {
  667. endTime = new Date();
  668. totalMilliseconds = endTime - startTime;
  669. less.logger.info("Less has finished and no sheets were loaded.");
  670. resolve({
  671. startTime: startTime,
  672. endTime: endTime,
  673. totalMilliseconds: totalMilliseconds,
  674. sheets: less.sheets.length
  675. });
  676. } else {
  677. // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array
  678. loadStyleSheets(function (e, css, _, sheet, webInfo) {
  679. if (e) {
  680. errors.add(e, e.href || sheet.href);
  681. reject(e);
  682. return;
  683. }
  684. if (webInfo.local) {
  685. less.logger.info("Loading " + sheet.href + " from cache.");
  686. } else {
  687. less.logger.info("Rendered " + sheet.href + " successfully.");
  688. }
  689. browser.createCSS(window.document, css, sheet);
  690. less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
  691. // Count completed sheet
  692. remainingSheets--;
  693. // Check if the last remaining sheet was processed and then call the promise
  694. if (remainingSheets === 0) {
  695. totalMilliseconds = new Date() - startTime;
  696. less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + 'ms');
  697. resolve({
  698. startTime: startTime,
  699. endTime: endTime,
  700. totalMilliseconds: totalMilliseconds,
  701. sheets: less.sheets.length
  702. });
  703. }
  704. endTime = new Date();
  705. }, reload, modifyVars);
  706. }
  707. loadStyles(modifyVars);
  708. });
  709. };
  710. less.refreshStyles = loadStyles;
  711. return less;
  712. };
  713. },{"../less":31,"./browser":3,"./cache":4,"./error-reporting":5,"./file-manager":6,"./image-size":7,"./log-listener":9,"./utils":10}],9:[function(require,module,exports){
  714. module.exports = function(less, options) {
  715. var logLevel_debug = 4,
  716. logLevel_info = 3,
  717. logLevel_warn = 2,
  718. logLevel_error = 1;
  719. // The amount of logging in the javascript console.
  720. // 3 - Debug, information and errors
  721. // 2 - Information and errors
  722. // 1 - Errors
  723. // 0 - None
  724. // Defaults to 2
  725. options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error);
  726. if (!options.loggers) {
  727. options.loggers = [{
  728. debug: function(msg) {
  729. if (options.logLevel >= logLevel_debug) {
  730. console.log(msg);
  731. }
  732. },
  733. info: function(msg) {
  734. if (options.logLevel >= logLevel_info) {
  735. console.log(msg);
  736. }
  737. },
  738. warn: function(msg) {
  739. if (options.logLevel >= logLevel_warn) {
  740. console.warn(msg);
  741. }
  742. },
  743. error: function(msg) {
  744. if (options.logLevel >= logLevel_error) {
  745. console.error(msg);
  746. }
  747. }
  748. }];
  749. }
  750. for (var i = 0; i < options.loggers.length; i++) {
  751. less.logger.addListener(options.loggers[i]);
  752. }
  753. };
  754. },{}],10:[function(require,module,exports){
  755. module.exports = {
  756. extractId: function(href) {
  757. return href.replace(/^[a-z-]+:\/+?[^\/]+/, '') // Remove protocol & domain
  758. .replace(/[\?\&]livereload=\w+/, '') // Remove LiveReload cachebuster
  759. .replace(/^\//, '') // Remove root /
  760. .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension
  761. .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
  762. .replace(/\./g, ':'); // Replace dots with colons(for valid id)
  763. },
  764. addDataAttr: function(options, tag) {
  765. for (var opt in tag.dataset) {
  766. if (tag.dataset.hasOwnProperty(opt)) {
  767. if (opt === "env" || opt === "dumpLineNumbers" || opt === "rootpath" || opt === "errorReporting") {
  768. options[opt] = tag.dataset[opt];
  769. } else {
  770. try {
  771. options[opt] = JSON.parse(tag.dataset[opt]);
  772. }
  773. catch(_) {}
  774. }
  775. }
  776. }
  777. }
  778. };
  779. },{}],11:[function(require,module,exports){
  780. var contexts = {};
  781. module.exports = contexts;
  782. var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {
  783. if (!original) { return; }
  784. for (var i = 0; i < propertiesToCopy.length; i++) {
  785. if (original.hasOwnProperty(propertiesToCopy[i])) {
  786. destination[propertiesToCopy[i]] = original[propertiesToCopy[i]];
  787. }
  788. }
  789. };
  790. /*
  791. parse is used whilst parsing
  792. */
  793. var parseCopyProperties = [
  794. // options
  795. 'paths', // option - unmodified - paths to search for imports on
  796. 'relativeUrls', // option - whether to adjust URL's to be relative
  797. 'rootpath', // option - rootpath to append to URL's
  798. 'strictImports', // option -
  799. 'insecure', // option - whether to allow imports from insecure ssl hosts
  800. 'dumpLineNumbers', // option - whether to dump line numbers
  801. 'compress', // option - whether to compress
  802. 'syncImport', // option - whether to import synchronously
  803. 'chunkInput', // option - whether to chunk input. more performant but causes parse issues.
  804. 'mime', // browser only - mime type for sheet import
  805. 'useFileCache', // browser only - whether to use the per file session cache
  806. // context
  807. 'processImports', // option & context - whether to process imports. if false then imports will not be imported.
  808. // Used by the import manager to stop multiple import visitors being created.
  809. 'pluginManager' // Used as the plugin manager for the session
  810. ];
  811. contexts.Parse = function(options) {
  812. copyFromOriginal(options, this, parseCopyProperties);
  813. if (typeof this.paths === "string") { this.paths = [this.paths]; }
  814. };
  815. var evalCopyProperties = [
  816. 'paths', // additional include paths
  817. 'compress', // whether to compress
  818. 'ieCompat', // whether to enforce IE compatibility (IE8 data-uri)
  819. 'strictMath', // whether math has to be within parenthesis
  820. 'strictUnits', // whether units need to evaluate correctly
  821. 'sourceMap', // whether to output a source map
  822. 'importMultiple', // whether we are currently importing multiple copies
  823. 'urlArgs', // whether to add args into url tokens
  824. 'javascriptEnabled',// option - whether JavaScript is enabled. if undefined, defaults to true
  825. 'pluginManager', // Used as the plugin manager for the session
  826. 'importantScope' // used to bubble up !important statements
  827. ];
  828. contexts.Eval = function(options, frames) {
  829. copyFromOriginal(options, this, evalCopyProperties);
  830. if (typeof this.paths === "string") { this.paths = [this.paths]; }
  831. this.frames = frames || [];
  832. this.importantScope = this.importantScope || [];
  833. };
  834. contexts.Eval.prototype.inParenthesis = function () {
  835. if (!this.parensStack) {
  836. this.parensStack = [];
  837. }
  838. this.parensStack.push(true);
  839. };
  840. contexts.Eval.prototype.outOfParenthesis = function () {
  841. this.parensStack.pop();
  842. };
  843. contexts.Eval.prototype.isMathOn = function () {
  844. return this.strictMath ? (this.parensStack && this.parensStack.length) : true;
  845. };
  846. contexts.Eval.prototype.isPathRelative = function (path) {
  847. return !/^(?:[a-z-]+:|\/|#)/i.test(path);
  848. };
  849. contexts.Eval.prototype.normalizePath = function( path ) {
  850. var
  851. segments = path.split("/").reverse(),
  852. segment;
  853. path = [];
  854. while (segments.length !== 0 ) {
  855. segment = segments.pop();
  856. switch( segment ) {
  857. case ".":
  858. break;
  859. case "..":
  860. if ((path.length === 0) || (path[path.length - 1] === "..")) {
  861. path.push( segment );
  862. } else {
  863. path.pop();
  864. }
  865. break;
  866. default:
  867. path.push( segment );
  868. break;
  869. }
  870. }
  871. return path.join("/");
  872. };
  873. //todo - do the same for the toCSS ?
  874. },{}],12:[function(require,module,exports){
  875. module.exports = {
  876. 'aliceblue':'#f0f8ff',
  877. 'antiquewhite':'#faebd7',
  878. 'aqua':'#00ffff',
  879. 'aquamarine':'#7fffd4',
  880. 'azure':'#f0ffff',
  881. 'beige':'#f5f5dc',
  882. 'bisque':'#ffe4c4',
  883. 'black':'#000000',
  884. 'blanchedalmond':'#ffebcd',
  885. 'blue':'#0000ff',
  886. 'blueviolet':'#8a2be2',
  887. 'brown':'#a52a2a',
  888. 'burlywood':'#deb887',
  889. 'cadetblue':'#5f9ea0',
  890. 'chartreuse':'#7fff00',
  891. 'chocolate':'#d2691e',
  892. 'coral':'#ff7f50',
  893. 'cornflowerblue':'#6495ed',
  894. 'cornsilk':'#fff8dc',
  895. 'crimson':'#dc143c',
  896. 'cyan':'#00ffff',
  897. 'darkblue':'#00008b',
  898. 'darkcyan':'#008b8b',
  899. 'darkgoldenrod':'#b8860b',
  900. 'darkgray':'#a9a9a9',
  901. 'darkgrey':'#a9a9a9',
  902. 'darkgreen':'#006400',
  903. 'darkkhaki':'#bdb76b',
  904. 'darkmagenta':'#8b008b',
  905. 'darkolivegreen':'#556b2f',
  906. 'darkorange':'#ff8c00',
  907. 'darkorchid':'#9932cc',
  908. 'darkred':'#8b0000',
  909. 'darksalmon':'#e9967a',
  910. 'darkseagreen':'#8fbc8f',
  911. 'darkslateblue':'#483d8b',
  912. 'darkslategray':'#2f4f4f',
  913. 'darkslategrey':'#2f4f4f',
  914. 'darkturquoise':'#00ced1',
  915. 'darkviolet':'#9400d3',
  916. 'deeppink':'#ff1493',
  917. 'deepskyblue':'#00bfff',
  918. 'dimgray':'#696969',
  919. 'dimgrey':'#696969',
  920. 'dodgerblue':'#1e90ff',
  921. 'firebrick':'#b22222',
  922. 'floralwhite':'#fffaf0',
  923. 'forestgreen':'#228b22',
  924. 'fuchsia':'#ff00ff',
  925. 'gainsboro':'#dcdcdc',
  926. 'ghostwhite':'#f8f8ff',
  927. 'gold':'#ffd700',
  928. 'goldenrod':'#daa520',
  929. 'gray':'#808080',
  930. 'grey':'#808080',
  931. 'green':'#008000',
  932. 'greenyellow':'#adff2f',
  933. 'honeydew':'#f0fff0',
  934. 'hotpink':'#ff69b4',
  935. 'indianred':'#cd5c5c',
  936. 'indigo':'#4b0082',
  937. 'ivory':'#fffff0',
  938. 'khaki':'#f0e68c',
  939. 'lavender':'#e6e6fa',
  940. 'lavenderblush':'#fff0f5',
  941. 'lawngreen':'#7cfc00',
  942. 'lemonchiffon':'#fffacd',
  943. 'lightblue':'#add8e6',
  944. 'lightcoral':'#f08080',
  945. 'lightcyan':'#e0ffff',
  946. 'lightgoldenrodyellow':'#fafad2',
  947. 'lightgray':'#d3d3d3',
  948. 'lightgrey':'#d3d3d3',
  949. 'lightgreen':'#90ee90',
  950. 'lightpink':'#ffb6c1',
  951. 'lightsalmon':'#ffa07a',
  952. 'lightseagreen':'#20b2aa',
  953. 'lightskyblue':'#87cefa',
  954. 'lightslategray':'#778899',
  955. 'lightslategrey':'#778899',
  956. 'lightsteelblue':'#b0c4de',
  957. 'lightyellow':'#ffffe0',
  958. 'lime':'#00ff00',
  959. 'limegreen':'#32cd32',
  960. 'linen':'#faf0e6',
  961. 'magenta':'#ff00ff',
  962. 'maroon':'#800000',
  963. 'mediumaquamarine':'#66cdaa',
  964. 'mediumblue':'#0000cd',
  965. 'mediumorchid':'#ba55d3',
  966. 'mediumpurple':'#9370d8',
  967. 'mediumseagreen':'#3cb371',
  968. 'mediumslateblue':'#7b68ee',
  969. 'mediumspringgreen':'#00fa9a',
  970. 'mediumturquoise':'#48d1cc',
  971. 'mediumvioletred':'#c71585',
  972. 'midnightblue':'#191970',
  973. 'mintcream':'#f5fffa',
  974. 'mistyrose':'#ffe4e1',
  975. 'moccasin':'#ffe4b5',
  976. 'navajowhite':'#ffdead',
  977. 'navy':'#000080',
  978. 'oldlace':'#fdf5e6',
  979. 'olive':'#808000',
  980. 'olivedrab':'#6b8e23',
  981. 'orange':'#ffa500',
  982. 'orangered':'#ff4500',
  983. 'orchid':'#da70d6',
  984. 'palegoldenrod':'#eee8aa',
  985. 'palegreen':'#98fb98',
  986. 'paleturquoise':'#afeeee',
  987. 'palevioletred':'#d87093',
  988. 'papayawhip':'#ffefd5',
  989. 'peachpuff':'#ffdab9',
  990. 'peru':'#cd853f',
  991. 'pink':'#ffc0cb',
  992. 'plum':'#dda0dd',
  993. 'powderblue':'#b0e0e6',
  994. 'purple':'#800080',
  995. 'rebeccapurple':'#663399',
  996. 'red':'#ff0000',
  997. 'rosybrown':'#bc8f8f',
  998. 'royalblue':'#4169e1',
  999. 'saddlebrown':'#8b4513',
  1000. 'salmon':'#fa8072',
  1001. 'sandybrown':'#f4a460',
  1002. 'seagreen':'#2e8b57',
  1003. 'seashell':'#fff5ee',
  1004. 'sienna':'#a0522d',
  1005. 'silver':'#c0c0c0',
  1006. 'skyblue':'#87ceeb',
  1007. 'slateblue':'#6a5acd',
  1008. 'slategray':'#708090',
  1009. 'slategrey':'#708090',
  1010. 'snow':'#fffafa',
  1011. 'springgreen':'#00ff7f',
  1012. 'steelblue':'#4682b4',
  1013. 'tan':'#d2b48c',
  1014. 'teal':'#008080',
  1015. 'thistle':'#d8bfd8',
  1016. 'tomato':'#ff6347',
  1017. 'turquoise':'#40e0d0',
  1018. 'violet':'#ee82ee',
  1019. 'wheat':'#f5deb3',
  1020. 'white':'#ffffff',
  1021. 'whitesmoke':'#f5f5f5',
  1022. 'yellow':'#ffff00',
  1023. 'yellowgreen':'#9acd32'
  1024. };
  1025. },{}],13:[function(require,module,exports){
  1026. module.exports = {
  1027. colors: require("./colors"),
  1028. unitConversions: require("./unit-conversions")
  1029. };
  1030. },{"./colors":12,"./unit-conversions":14}],14:[function(require,module,exports){
  1031. module.exports = {
  1032. length: {
  1033. 'm': 1,
  1034. 'cm': 0.01,
  1035. 'mm': 0.001,
  1036. 'in': 0.0254,
  1037. 'px': 0.0254 / 96,
  1038. 'pt': 0.0254 / 72,
  1039. 'pc': 0.0254 / 72 * 12
  1040. },
  1041. duration: {
  1042. 's': 1,
  1043. 'ms': 0.001
  1044. },
  1045. angle: {
  1046. 'rad': 1 / (2 * Math.PI),
  1047. 'deg': 1 / 360,
  1048. 'grad': 1 / 400,
  1049. 'turn': 1
  1050. }
  1051. };
  1052. },{}],15:[function(require,module,exports){
  1053. var abstractFileManager = function() {
  1054. };
  1055. abstractFileManager.prototype.getPath = function (filename) {
  1056. var j = filename.lastIndexOf('?');
  1057. if (j > 0) {
  1058. filename = filename.slice(0, j);
  1059. }
  1060. j = filename.lastIndexOf('/');
  1061. if (j < 0) {
  1062. j = filename.lastIndexOf('\\');
  1063. }
  1064. if (j < 0) {
  1065. return "";
  1066. }
  1067. return filename.slice(0, j + 1);
  1068. };
  1069. abstractFileManager.prototype.tryAppendExtension = function(path, ext) {
  1070. return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext;
  1071. };
  1072. abstractFileManager.prototype.tryAppendLessExtension = function(path) {
  1073. return this.tryAppendExtension(path, '.less');
  1074. };
  1075. abstractFileManager.prototype.supportsSync = function() {
  1076. return false;
  1077. };
  1078. abstractFileManager.prototype.alwaysMakePathsAbsolute = function() {
  1079. return false;
  1080. };
  1081. abstractFileManager.prototype.isPathAbsolute = function(filename) {
  1082. return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename);
  1083. };
  1084. abstractFileManager.prototype.join = function(basePath, laterPath) {
  1085. if (!basePath) {
  1086. return laterPath;
  1087. }
  1088. return basePath + laterPath;
  1089. };
  1090. abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {
  1091. // diff between two paths to create a relative path
  1092. var urlParts = this.extractUrlParts(url),
  1093. baseUrlParts = this.extractUrlParts(baseUrl),
  1094. i, max, urlDirectories, baseUrlDirectories, diff = "";
  1095. if (urlParts.hostPart !== baseUrlParts.hostPart) {
  1096. return "";
  1097. }
  1098. max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
  1099. for (i = 0; i < max; i++) {
  1100. if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }
  1101. }
  1102. baseUrlDirectories = baseUrlParts.directories.slice(i);
  1103. urlDirectories = urlParts.directories.slice(i);
  1104. for (i = 0; i < baseUrlDirectories.length - 1; i++) {
  1105. diff += "../";
  1106. }
  1107. for (i = 0; i < urlDirectories.length - 1; i++) {
  1108. diff += urlDirectories[i] + "/";
  1109. }
  1110. return diff;
  1111. };
  1112. // helper function, not part of API
  1113. abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, baseUrl) {
  1114. // urlParts[1] = protocol://hostname/ OR /
  1115. // urlParts[2] = / if path relative to host base
  1116. // urlParts[3] = directories
  1117. // urlParts[4] = filename
  1118. // urlParts[5] = parameters
  1119. var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
  1120. urlParts = url.match(urlPartsRegex),
  1121. returner = {}, directories = [], i, baseUrlParts;
  1122. if (!urlParts) {
  1123. throw new Error("Could not parse sheet href - '" + url + "'");
  1124. }
  1125. // Stylesheets in IE don't always return the full path
  1126. if (baseUrl && (!urlParts[1] || urlParts[2])) {
  1127. baseUrlParts = baseUrl.match(urlPartsRegex);
  1128. if (!baseUrlParts) {
  1129. throw new Error("Could not parse page url - '" + baseUrl + "'");
  1130. }
  1131. urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
  1132. if (!urlParts[2]) {
  1133. urlParts[3] = baseUrlParts[3] + urlParts[3];
  1134. }
  1135. }
  1136. if (urlParts[3]) {
  1137. directories = urlParts[3].replace(/\\/g, "/").split("/");
  1138. // extract out . before .. so .. doesn't absorb a non-directory
  1139. for (i = 0; i < directories.length; i++) {
  1140. if (directories[i] === ".") {
  1141. directories.splice(i, 1);
  1142. i -= 1;
  1143. }
  1144. }
  1145. for (i = 0; i < directories.length; i++) {
  1146. if (directories[i] === ".." && i > 0) {
  1147. directories.splice(i - 1, 2);
  1148. i -= 2;
  1149. }
  1150. }
  1151. }
  1152. returner.hostPart = urlParts[1];
  1153. returner.directories = directories;
  1154. returner.path = (urlParts[1] || "") + directories.join("/");
  1155. returner.fileUrl = returner.path + (urlParts[4] || "");
  1156. returner.url = returner.fileUrl + (urlParts[5] || "");
  1157. return returner;
  1158. };
  1159. module.exports = abstractFileManager;
  1160. },{}],16:[function(require,module,exports){
  1161. var logger = require("../logger");
  1162. var environment = function(externalEnvironment, fileManagers) {
  1163. this.fileManagers = fileManagers || [];
  1164. externalEnvironment = externalEnvironment || {};
  1165. var optionalFunctions = ["encodeBase64", "mimeLookup", "charsetLookup", "getSourceMapGenerator"],
  1166. requiredFunctions = [],
  1167. functions = requiredFunctions.concat(optionalFunctions);
  1168. for (var i = 0; i < functions.length; i++) {
  1169. var propName = functions[i],
  1170. environmentFunc = externalEnvironment[propName];
  1171. if (environmentFunc) {
  1172. this[propName] = environmentFunc.bind(externalEnvironment);
  1173. } else if (i < requiredFunctions.length) {
  1174. this.warn("missing required function in environment - " + propName);
  1175. }
  1176. }
  1177. };
  1178. environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
  1179. if (!filename) {
  1180. logger.warn("getFileManager called with no filename.. Please report this issue. continuing.");
  1181. }
  1182. if (currentDirectory == null) {
  1183. logger.warn("getFileManager called with null directory.. Please report this issue. continuing.");
  1184. }
  1185. var fileManagers = this.fileManagers;
  1186. if (options.pluginManager) {
  1187. fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());
  1188. }
  1189. for (var i = fileManagers.length - 1; i >= 0 ; i--) {
  1190. var fileManager = fileManagers[i];
  1191. if (fileManager[isSync ? "supportsSync" : "supports"](filename, currentDirectory, options, environment)) {
  1192. return fileManager;
  1193. }
  1194. }
  1195. return null;
  1196. };
  1197. environment.prototype.addFileManager = function (fileManager) {
  1198. this.fileManagers.push(fileManager);
  1199. };
  1200. environment.prototype.clearFileManagers = function () {
  1201. this.fileManagers = [];
  1202. };
  1203. module.exports = environment;
  1204. },{"../logger":33}],17:[function(require,module,exports){
  1205. var Color = require("../tree/color"),
  1206. functionRegistry = require("./function-registry");
  1207. // Color Blending
  1208. // ref: http://www.w3.org/TR/compositing-1
  1209. function colorBlend(mode, color1, color2) {
  1210. var ab = color1.alpha, cb, // backdrop
  1211. as = color2.alpha, cs, // source
  1212. ar, cr, r = []; // result
  1213. ar = as + ab * (1 - as);
  1214. for (var i = 0; i < 3; i++) {
  1215. cb = color1.rgb[i] / 255;
  1216. cs = color2.rgb[i] / 255;
  1217. cr = mode(cb, cs);
  1218. if (ar) {
  1219. cr = (as * cs + ab * (cb -
  1220. as * (cb + cs - cr))) / ar;
  1221. }
  1222. r[i] = cr * 255;
  1223. }
  1224. return new Color(r, ar);
  1225. }
  1226. var colorBlendModeFunctions = {
  1227. multiply: function(cb, cs) {
  1228. return cb * cs;
  1229. },
  1230. screen: function(cb, cs) {
  1231. return cb + cs - cb * cs;
  1232. },
  1233. overlay: function(cb, cs) {
  1234. cb *= 2;
  1235. return (cb <= 1) ?
  1236. colorBlendModeFunctions.multiply(cb, cs) :
  1237. colorBlendModeFunctions.screen(cb - 1, cs);
  1238. },
  1239. softlight: function(cb, cs) {
  1240. var d = 1, e = cb;
  1241. if (cs > 0.5) {
  1242. e = 1;
  1243. d = (cb > 0.25) ? Math.sqrt(cb)
  1244. : ((16 * cb - 12) * cb + 4) * cb;
  1245. }
  1246. return cb - (1 - 2 * cs) * e * (d - cb);
  1247. },
  1248. hardlight: function(cb, cs) {
  1249. return colorBlendModeFunctions.overlay(cs, cb);
  1250. },
  1251. difference: function(cb, cs) {
  1252. return Math.abs(cb - cs);
  1253. },
  1254. exclusion: function(cb, cs) {
  1255. return cb + cs - 2 * cb * cs;
  1256. },
  1257. // non-w3c functions:
  1258. average: function(cb, cs) {
  1259. return (cb + cs) / 2;
  1260. },
  1261. negation: function(cb, cs) {
  1262. return 1 - Math.abs(cb + cs - 1);
  1263. }
  1264. };
  1265. for (var f in colorBlendModeFunctions) {
  1266. if (colorBlendModeFunctions.hasOwnProperty(f)) {
  1267. colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]);
  1268. }
  1269. }
  1270. functionRegistry.addMultiple(colorBlend);
  1271. },{"../tree/color":50,"./function-registry":22}],18:[function(require,module,exports){
  1272. var Dimension = require("../tree/dimension"),
  1273. Color = require("../tree/color"),
  1274. Quoted = require("../tree/quoted"),
  1275. Anonymous = require("../tree/anonymous"),
  1276. functionRegistry = require("./function-registry"),
  1277. colorFunctions;
  1278. function clamp(val) {
  1279. return Math.min(1, Math.max(0, val));
  1280. }
  1281. function hsla(color) {
  1282. return colorFunctions.hsla(color.h, color.s, color.l, color.a);
  1283. }
  1284. function number(n) {
  1285. if (n instanceof Dimension) {
  1286. return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);
  1287. } else if (typeof n === 'number') {
  1288. return n;
  1289. } else {
  1290. throw {
  1291. type: "Argument",
  1292. message: "color functions take numbers as parameters"
  1293. };
  1294. }
  1295. }
  1296. function scaled(n, size) {
  1297. if (n instanceof Dimension && n.unit.is('%')) {
  1298. return parseFloat(n.value * size / 100);
  1299. } else {
  1300. return number(n);
  1301. }
  1302. }
  1303. colorFunctions = {
  1304. rgb: function (r, g, b) {
  1305. return colorFunctions.rgba(r, g, b, 1.0);
  1306. },
  1307. rgba: function (r, g, b, a) {
  1308. var rgb = [r, g, b].map(function (c) { return scaled(c, 255); });
  1309. a = number(a);
  1310. return new Color(rgb, a);
  1311. },
  1312. hsl: function (h, s, l) {
  1313. return colorFunctions.hsla(h, s, l, 1.0);
  1314. },
  1315. hsla: function (h, s, l, a) {
  1316. var m1, m2;
  1317. function hue(h) {
  1318. h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);
  1319. if (h * 6 < 1) {
  1320. return m1 + (m2 - m1) * h * 6;
  1321. }
  1322. else if (h * 2 < 1) {
  1323. return m2;
  1324. }
  1325. else if (h * 3 < 2) {
  1326. return m1 + (m2 - m1) * (2 / 3 - h) * 6;
  1327. }
  1328. else {
  1329. return m1;
  1330. }
  1331. }
  1332. h = (number(h) % 360) / 360;
  1333. s = clamp(number(s)); l = clamp(number(l)); a = clamp(number(a));
  1334. m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
  1335. m1 = l * 2 - m2;
  1336. return colorFunctions.rgba(hue(h + 1 / 3) * 255,
  1337. hue(h) * 255,
  1338. hue(h - 1 / 3) * 255,
  1339. a);
  1340. },
  1341. hsv: function(h, s, v) {
  1342. return colorFunctions.hsva(h, s, v, 1.0);
  1343. },
  1344. hsva: function(h, s, v, a) {
  1345. h = ((number(h) % 360) / 360) * 360;
  1346. s = number(s); v = number(v); a = number(a);
  1347. var i, f;
  1348. i = Math.floor((h / 60) % 6);
  1349. f = (h / 60) - i;
  1350. var vs = [v,
  1351. v * (1 - s),
  1352. v * (1 - f * s),
  1353. v * (1 - (1 - f) * s)];
  1354. var perm = [[0, 3, 1],
  1355. [2, 0, 1],
  1356. [1, 0, 3],
  1357. [1, 2, 0],
  1358. [3, 1, 0],
  1359. [0, 1, 2]];
  1360. return colorFunctions.rgba(vs[perm[i][0]] * 255,
  1361. vs[perm[i][1]] * 255,
  1362. vs[perm[i][2]] * 255,
  1363. a);
  1364. },
  1365. hue: function (color) {
  1366. return new Dimension(color.toHSL().h);
  1367. },
  1368. saturation: function (color) {
  1369. return new Dimension(color.toHSL().s * 100, '%');
  1370. },
  1371. lightness: function (color) {
  1372. return new Dimension(color.toHSL().l * 100, '%');
  1373. },
  1374. hsvhue: function(color) {
  1375. return new Dimension(color.toHSV().h);
  1376. },
  1377. hsvsaturation: function (color) {
  1378. return new Dimension(color.toHSV().s * 100, '%');
  1379. },
  1380. hsvvalue: function (color) {
  1381. return new Dimension(color.toHSV().v * 100, '%');
  1382. },
  1383. red: function (color) {
  1384. return new Dimension(color.rgb[0]);
  1385. },
  1386. green: function (color) {
  1387. return new Dimension(color.rgb[1]);
  1388. },
  1389. blue: function (color) {
  1390. return new Dimension(color.rgb[2]);
  1391. },
  1392. alpha: function (color) {
  1393. return new Dimension(color.toHSL().a);
  1394. },
  1395. luma: function (color) {
  1396. return new Dimension(color.luma() * color.alpha * 100, '%');
  1397. },
  1398. luminance: function (color) {
  1399. var luminance =
  1400. (0.2126 * color.rgb[0] / 255) +
  1401. (0.7152 * color.rgb[1] / 255) +
  1402. (0.0722 * color.rgb[2] / 255);
  1403. return new Dimension(luminance * color.alpha * 100, '%');
  1404. },
  1405. saturate: function (color, amount, method) {
  1406. // filter: saturate(3.2);
  1407. // should be kept as is, so check for color
  1408. if (!color.rgb) {
  1409. return null;
  1410. }
  1411. var hsl = color.toHSL();
  1412. if (typeof method !== "undefined" && method.value === "relative") {
  1413. hsl.s += hsl.s * amount.value / 100;
  1414. }
  1415. else {
  1416. hsl.s += amount.value / 100;
  1417. }
  1418. hsl.s = clamp(hsl.s);
  1419. return hsla(hsl);
  1420. },
  1421. desaturate: function (color, amount, method) {
  1422. var hsl = color.toHSL();
  1423. if (typeof method !== "undefined" && method.value === "relative") {
  1424. hsl.s -= hsl.s * amount.value / 100;
  1425. }
  1426. else {
  1427. hsl.s -= amount.value / 100;
  1428. }
  1429. hsl.s = clamp(hsl.s);
  1430. return hsla(hsl);
  1431. },
  1432. lighten: function (color, amount, method) {
  1433. var hsl = color.toHSL();
  1434. if (typeof method !== "undefined" && method.value === "relative") {
  1435. hsl.l += hsl.l * amount.value / 100;
  1436. }
  1437. else {
  1438. hsl.l += amount.value / 100;
  1439. }
  1440. hsl.l = clamp(hsl.l);
  1441. return hsla(hsl);
  1442. },
  1443. darken: function (color, amount, method) {
  1444. var hsl = color.toHSL();
  1445. if (typeof method !== "undefined" && method.value === "relative") {
  1446. hsl.l -= hsl.l * amount.value / 100;
  1447. }
  1448. else {
  1449. hsl.l -= amount.value / 100;
  1450. }
  1451. hsl.l = clamp(hsl.l);
  1452. return hsla(hsl);
  1453. },
  1454. fadein: function (color, amount, method) {
  1455. var hsl = color.toHSL();
  1456. if (typeof method !== "undefined" && method.value === "relative") {
  1457. hsl.a += hsl.a * amount.value / 100;
  1458. }
  1459. else {
  1460. hsl.a += amount.value / 100;
  1461. }
  1462. hsl.a = clamp(hsl.a);
  1463. return hsla(hsl);
  1464. },
  1465. fadeout: function (color, amount, method) {
  1466. var hsl = color.toHSL();
  1467. if (typeof method !== "undefined" && method.value === "relative") {
  1468. hsl.a -= hsl.a * amount.value / 100;
  1469. }
  1470. else {
  1471. hsl.a -= amount.value / 100;
  1472. }
  1473. hsl.a = clamp(hsl.a);
  1474. return hsla(hsl);
  1475. },
  1476. fade: function (color, amount) {
  1477. var hsl = color.toHSL();
  1478. hsl.a = amount.value / 100;
  1479. hsl.a = clamp(hsl.a);
  1480. return hsla(hsl);
  1481. },
  1482. spin: function (color, amount) {
  1483. var hsl = color.toHSL();
  1484. var hue = (hsl.h + amount.value) % 360;
  1485. hsl.h = hue < 0 ? 360 + hue : hue;
  1486. return hsla(hsl);
  1487. },
  1488. //
  1489. // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein
  1490. // http://sass-lang.com
  1491. //
  1492. mix: function (color1, color2, weight) {
  1493. if (!color1.toHSL || !color2.toHSL) {
  1494. console.log(color2.type);
  1495. console.dir(color2);
  1496. }
  1497. if (!weight) {
  1498. weight = new Dimension(50);
  1499. }
  1500. var p = weight.value / 100.0;
  1501. var w = p * 2 - 1;
  1502. var a = color1.toHSL().a - color2.toHSL().a;
  1503. var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;
  1504. var w2 = 1 - w1;
  1505. var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,
  1506. color1.rgb[1] * w1 + color2.rgb[1] * w2,
  1507. color1.rgb[2] * w1 + color2.rgb[2] * w2];
  1508. var alpha = color1.alpha * p + color2.alpha * (1 - p);
  1509. return new Color(rgb, alpha);
  1510. },
  1511. greyscale: function (color) {
  1512. return colorFunctions.desaturate(color, new Dimension(100));
  1513. },
  1514. contrast: function (color, dark, light, threshold) {
  1515. // filter: contrast(3.2);
  1516. // should be kept as is, so check for color
  1517. if (!color.rgb) {
  1518. return null;
  1519. }
  1520. if (typeof light === 'undefined') {
  1521. light = colorFunctions.rgba(255, 255, 255, 1.0);
  1522. }
  1523. if (typeof dark === 'undefined') {
  1524. dark = colorFunctions.rgba(0, 0, 0, 1.0);
  1525. }
  1526. //Figure out which is actually light and dark!
  1527. if (dark.luma() > light.luma()) {
  1528. var t = light;
  1529. light = dark;
  1530. dark = t;
  1531. }
  1532. if (typeof threshold === 'undefined') {
  1533. threshold = 0.43;
  1534. } else {
  1535. threshold = number(threshold);
  1536. }
  1537. if (color.luma() < threshold) {
  1538. return light;
  1539. } else {
  1540. return dark;
  1541. }
  1542. },
  1543. argb: function (color) {
  1544. return new Anonymous(color.toARGB());
  1545. },
  1546. color: function(c) {
  1547. if ((c instanceof Quoted) &&
  1548. (/^#([a-f0-9]{6}|[a-f0-9]{3})$/i.test(c.value))) {
  1549. return new Color(c.value.slice(1));
  1550. }
  1551. if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {
  1552. c.value = undefined;
  1553. return c;
  1554. }
  1555. throw {
  1556. type: "Argument",
  1557. message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF"
  1558. };
  1559. },
  1560. tint: function(color, amount) {
  1561. return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);
  1562. },
  1563. shade: function(color, amount) {
  1564. return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);
  1565. }
  1566. };
  1567. functionRegistry.addMultiple(colorFunctions);
  1568. },{"../tree/anonymous":46,"../tree/color":50,"../tree/dimension":56,"../tree/quoted":73,"./function-registry":22}],19:[function(require,module,exports){
  1569. module.exports = function(environment) {
  1570. var Quoted = require("../tree/quoted"),
  1571. URL = require("../tree/url"),
  1572. functionRegistry = require("./function-registry"),
  1573. fallback = function(functionThis, node) {
  1574. return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context);
  1575. },
  1576. logger = require('../logger');
  1577. functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {
  1578. if (!filePathNode) {
  1579. filePathNode = mimetypeNode;
  1580. mimetypeNode = null;
  1581. }
  1582. var mimetype = mimetypeNode && mimetypeNode.value;
  1583. var filePath = filePathNode.value;
  1584. var currentFileInfo = this.currentFileInfo;
  1585. var currentDirectory = currentFileInfo.relativeUrls ?
  1586. currentFileInfo.currentDirectory : currentFileInfo.entryPath;
  1587. var fragmentStart = filePath.indexOf('#');
  1588. var fragment = '';
  1589. if (fragmentStart !== -1) {
  1590. fragment = filePath.slice(fragmentStart);
  1591. filePath = filePath.slice(0, fragmentStart);
  1592. }
  1593. var fileManager = environment.getFileManager(filePath, currentDirectory, this.context, environment, true);
  1594. if (!fileManager) {
  1595. return fallback(this, filePathNode);
  1596. }
  1597. var useBase64 = false;
  1598. // detect the mimetype if not given
  1599. if (!mimetypeNode) {
  1600. mimetype = environment.mimeLookup(filePath);
  1601. if (mimetype === "image/svg+xml") {
  1602. useBase64 = false;
  1603. } else {
  1604. // use base 64 unless it's an ASCII or UTF-8 format
  1605. var charset = environment.charsetLookup(mimetype);
  1606. useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;
  1607. }
  1608. if (useBase64) { mimetype += ';base64'; }
  1609. }
  1610. else {
  1611. useBase64 = /;base64$/.test(mimetype);
  1612. }
  1613. var fileSync = fileManager.loadFileSync(filePath, currentDirectory, this.context, environment);
  1614. if (!fileSync.contents) {
  1615. logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
  1616. return fallback(this, filePathNode || mimetypeNode);
  1617. }
  1618. var buf = fileSync.contents;
  1619. if (useBase64 && !environment.encodeBase64) {
  1620. return fallback(this, filePathNode);
  1621. }
  1622. buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);
  1623. var uri = "data:" + mimetype + ',' + buf + fragment;
  1624. // IE8 cannot handle a data-uri larger than 32,768 characters. If this is exceeded
  1625. // and the --ieCompat flag is enabled, return a normal url() instead.
  1626. var DATA_URI_MAX = 32768;
  1627. if (uri.length >= DATA_URI_MAX) {
  1628. if (this.context.ieCompat !== false) {
  1629. logger.warn("Skipped data-uri embedding of " + filePath + " because its size (" + uri.length +
  1630. " characters) exceeds IE8-safe " + DATA_URI_MAX + " characters!");
  1631. return fallback(this, filePathNode || mimetypeNode);
  1632. }
  1633. }
  1634. return new URL(new Quoted('"' + uri + '"', uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  1635. });
  1636. };
  1637. },{"../logger":33,"../tree/quoted":73,"../tree/url":80,"./function-registry":22}],20:[function(require,module,exports){
  1638. var Keyword = require("../tree/keyword"),
  1639. functionRegistry = require("./function-registry");
  1640. var defaultFunc = {
  1641. eval: function () {
  1642. var v = this.value_, e = this.error_;
  1643. if (e) {
  1644. throw e;
  1645. }
  1646. if (v != null) {
  1647. return v ? Keyword.True : Keyword.False;
  1648. }
  1649. },
  1650. value: function (v) {
  1651. this.value_ = v;
  1652. },
  1653. error: function (e) {
  1654. this.error_ = e;
  1655. },
  1656. reset: function () {
  1657. this.value_ = this.error_ = null;
  1658. }
  1659. };
  1660. functionRegistry.add("default", defaultFunc.eval.bind(defaultFunc));
  1661. module.exports = defaultFunc;
  1662. },{"../tree/keyword":65,"./function-registry":22}],21:[function(require,module,exports){
  1663. var Expression = require("../tree/expression");
  1664. var functionCaller = function(name, context, index, currentFileInfo) {
  1665. this.name = name.toLowerCase();
  1666. this.index = index;
  1667. this.context = context;
  1668. this.currentFileInfo = currentFileInfo;
  1669. this.func = context.frames[0].functionRegistry.get(this.name);
  1670. };
  1671. functionCaller.prototype.isValid = function() {
  1672. return Boolean(this.func);
  1673. };
  1674. functionCaller.prototype.call = function(args) {
  1675. // This code is terrible and should be replaced as per this issue...
  1676. // https://github.com/less/less.js/issues/2477
  1677. if (Array.isArray(args)) {
  1678. args = args.filter(function (item) {
  1679. if (item.type === "Comment") {
  1680. return false;
  1681. }
  1682. return true;
  1683. })
  1684. .map(function(item) {
  1685. if (item.type === "Expression") {
  1686. var subNodes = item.value.filter(function (item) {
  1687. if (item.type === "Comment") {
  1688. return false;
  1689. }
  1690. return true;
  1691. });
  1692. if (subNodes.length === 1) {
  1693. return subNodes[0];
  1694. } else {
  1695. return new Expression(subNodes);
  1696. }
  1697. }
  1698. return item;
  1699. });
  1700. }
  1701. return this.func.apply(this, args);
  1702. };
  1703. module.exports = functionCaller;
  1704. },{"../tree/expression":59}],22:[function(require,module,exports){
  1705. function makeRegistry( base ) {
  1706. return {
  1707. _data: {},
  1708. add: function(name, func) {
  1709. // precautionary case conversion, as later querying of
  1710. // the registry by function-caller uses lower case as well.
  1711. name = name.toLowerCase();
  1712. if (this._data.hasOwnProperty(name)) {
  1713. //TODO warn
  1714. }
  1715. this._data[name] = func;
  1716. },
  1717. addMultiple: function(functions) {
  1718. Object.keys(functions).forEach(
  1719. function(name) {
  1720. this.add(name, functions[name]);
  1721. }.bind(this));
  1722. },
  1723. get: function(name) {
  1724. return this._data[name] || ( base && base.get( name ));
  1725. },
  1726. inherit : function() {
  1727. return makeRegistry( this );
  1728. }
  1729. };
  1730. }
  1731. module.exports = makeRegistry( null );
  1732. },{}],23:[function(require,module,exports){
  1733. module.exports = function(environment) {
  1734. var functions = {
  1735. functionRegistry: require("./function-registry"),
  1736. functionCaller: require("./function-caller")
  1737. };
  1738. //register functions
  1739. require("./default");
  1740. require("./color");
  1741. require("./color-blending");
  1742. require("./data-uri")(environment);
  1743. require("./math");
  1744. require("./number");
  1745. require("./string");
  1746. require("./svg")(environment);
  1747. require("./types");
  1748. return functions;
  1749. };
  1750. },{"./color":18,"./color-blending":17,"./data-uri":19,"./default":20,"./function-caller":21,"./function-registry":22,"./math":25,"./number":26,"./string":27,"./svg":28,"./types":29}],24:[function(require,module,exports){
  1751. var Dimension = require("../tree/dimension");
  1752. var MathHelper = function() {
  1753. };
  1754. MathHelper._math = function (fn, unit, n) {
  1755. if (!(n instanceof Dimension)) {
  1756. throw { type: "Argument", message: "argument must be a number" };
  1757. }
  1758. if (unit == null) {
  1759. unit = n.unit;
  1760. } else {
  1761. n = n.unify();
  1762. }
  1763. return new Dimension(fn(parseFloat(n.value)), unit);
  1764. };
  1765. module.exports = MathHelper;
  1766. },{"../tree/dimension":56}],25:[function(require,module,exports){
  1767. var functionRegistry = require("./function-registry"),
  1768. mathHelper = require("./math-helper.js");
  1769. var mathFunctions = {
  1770. // name, unit
  1771. ceil: null,
  1772. floor: null,
  1773. sqrt: null,
  1774. abs: null,
  1775. tan: "",
  1776. sin: "",
  1777. cos: "",
  1778. atan: "rad",
  1779. asin: "rad",
  1780. acos: "rad"
  1781. };
  1782. for (var f in mathFunctions) {
  1783. if (mathFunctions.hasOwnProperty(f)) {
  1784. mathFunctions[f] = mathHelper._math.bind(null, Math[f], mathFunctions[f]);
  1785. }
  1786. }
  1787. mathFunctions.round = function (n, f) {
  1788. var fraction = typeof f === "undefined" ? 0 : f.value;
  1789. return mathHelper._math(function(num) { return num.toFixed(fraction); }, null, n);
  1790. };
  1791. functionRegistry.addMultiple(mathFunctions);
  1792. },{"./function-registry":22,"./math-helper.js":24}],26:[function(require,module,exports){
  1793. var Dimension = require("../tree/dimension"),
  1794. Anonymous = require("../tree/anonymous"),
  1795. functionRegistry = require("./function-registry"),
  1796. mathHelper = require("./math-helper.js");
  1797. var minMax = function (isMin, args) {
  1798. args = Array.prototype.slice.call(args);
  1799. switch(args.length) {
  1800. case 0: throw { type: "Argument", message: "one or more arguments required" };
  1801. }
  1802. var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone,
  1803. order = [], // elems only contains original argument values.
  1804. values = {}; // key is the unit.toString() for unified Dimension values,
  1805. // value is the index into the order array.
  1806. for (i = 0; i < args.length; i++) {
  1807. current = args[i];
  1808. if (!(current instanceof Dimension)) {
  1809. if (Array.isArray(args[i].value)) {
  1810. Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));
  1811. }
  1812. continue;
  1813. }
  1814. currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
  1815. unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
  1816. unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic;
  1817. unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone;
  1818. j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit];
  1819. if (j === undefined) {
  1820. if (unitStatic !== undefined && unit !== unitStatic) {
  1821. throw{ type: "Argument", message: "incompatible types" };
  1822. }
  1823. values[unit] = order.length;
  1824. order.push(current);
  1825. continue;
  1826. }
  1827. referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
  1828. if ( isMin && currentUnified.value < referenceUnified.value ||
  1829. !isMin && currentUnified.value > referenceUnified.value) {
  1830. order[j] = current;
  1831. }
  1832. }
  1833. if (order.length == 1) {
  1834. return order[0];
  1835. }
  1836. args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? "," : ", ");
  1837. return new Anonymous((isMin ? "min" : "max") + "(" + args + ")");
  1838. };
  1839. functionRegistry.addMultiple({
  1840. min: function () {
  1841. return minMax(true, arguments);
  1842. },
  1843. max: function () {
  1844. return minMax(false, arguments);
  1845. },
  1846. convert: function (val, unit) {
  1847. return val.convertTo(unit.value);
  1848. },
  1849. pi: function () {
  1850. return new Dimension(Math.PI);
  1851. },
  1852. mod: function(a, b) {
  1853. return new Dimension(a.value % b.value, a.unit);
  1854. },
  1855. pow: function(x, y) {
  1856. if (typeof x === "number" && typeof y === "number") {
  1857. x = new Dimension(x);
  1858. y = new Dimension(y);
  1859. } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {
  1860. throw { type: "Argument", message: "arguments must be numbers" };
  1861. }
  1862. return new Dimension(Math.pow(x.value, y.value), x.unit);
  1863. },
  1864. percentage: function (n) {
  1865. var result = mathHelper._math(function(num) {
  1866. return num * 100;
  1867. }, '%', n);
  1868. return result;
  1869. }
  1870. });
  1871. },{"../tree/anonymous":46,"../tree/dimension":56,"./function-registry":22,"./math-helper.js":24}],27:[function(require,module,exports){
  1872. var Quoted = require("../tree/quoted"),
  1873. Anonymous = require("../tree/anonymous"),
  1874. JavaScript = require("../tree/javascript"),
  1875. functionRegistry = require("./function-registry");
  1876. functionRegistry.addMultiple({
  1877. e: function (str) {
  1878. return new Anonymous(str instanceof JavaScript ? str.evaluated : str.value);
  1879. },
  1880. escape: function (str) {
  1881. return new Anonymous(
  1882. encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B")
  1883. .replace(/\(/g, "%28").replace(/\)/g, "%29"));
  1884. },
  1885. replace: function (string, pattern, replacement, flags) {
  1886. var result = string.value;
  1887. replacement = (replacement.type === "Quoted") ?
  1888. replacement.value : replacement.toCSS();
  1889. result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
  1890. return new Quoted(string.quote || '', result, string.escaped);
  1891. },
  1892. '%': function (string /* arg, arg, ...*/) {
  1893. var args = Array.prototype.slice.call(arguments, 1),
  1894. result = string.value;
  1895. for (var i = 0; i < args.length; i++) {
  1896. /*jshint loopfunc:true */
  1897. result = result.replace(/%[sda]/i, function(token) {
  1898. var value = ((args[i].type === "Quoted") &&
  1899. token.match(/s/i)) ? args[i].value : args[i].toCSS();
  1900. return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
  1901. });
  1902. }
  1903. result = result.replace(/%%/g, '%');
  1904. return new Quoted(string.quote || '', result, string.escaped);
  1905. }
  1906. });
  1907. },{"../tree/anonymous":46,"../tree/javascript":63,"../tree/quoted":73,"./function-registry":22}],28:[function(require,module,exports){
  1908. module.exports = function(environment) {
  1909. var Dimension = require("../tree/dimension"),
  1910. Color = require("../tree/color"),
  1911. Expression = require("../tree/expression"),
  1912. Quoted = require("../tree/quoted"),
  1913. URL = require("../tree/url"),
  1914. functionRegistry = require("./function-registry");
  1915. functionRegistry.add("svg-gradient", function(direction) {
  1916. var stops,
  1917. gradientDirectionSvg,
  1918. gradientType = "linear",
  1919. rectangleDimension = 'x="0" y="0" width="1" height="1"',
  1920. renderEnv = {compress: false},
  1921. returner,
  1922. directionValue = direction.toCSS(renderEnv),
  1923. i, color, position, positionValue, alpha;
  1924. function throwArgumentDescriptor() {
  1925. throw { type: "Argument",
  1926. message: "svg-gradient expects direction, start_color [start_position], [color position,]...," +
  1927. " end_color [end_position] or direction, color list" };
  1928. }
  1929. if (arguments.length == 2) {
  1930. if (arguments[1].value.length < 2) {
  1931. throwArgumentDescriptor();
  1932. }
  1933. stops = arguments[1].value;
  1934. } else if (arguments.length < 3) {
  1935. throwArgumentDescriptor();
  1936. } else {
  1937. stops = Array.prototype.slice.call(arguments, 1);
  1938. }
  1939. switch (directionValue) {
  1940. case "to bottom":
  1941. gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
  1942. break;
  1943. case "to right":
  1944. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
  1945. break;
  1946. case "to bottom right":
  1947. gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
  1948. break;
  1949. case "to top right":
  1950. gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
  1951. break;
  1952. case "ellipse":
  1953. case "ellipse at center":
  1954. gradientType = "radial";
  1955. gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
  1956. rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
  1957. break;
  1958. default:
  1959. throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right'," +
  1960. " 'to bottom right', 'to top right' or 'ellipse at center'" };
  1961. }
  1962. returner = '<?xml version="1.0" ?>' +
  1963. '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' +
  1964. '<' + gradientType + 'Gradient id="gradient" gradientUnits="userSpaceOnUse" ' + gradientDirectionSvg + '>';
  1965. for (i = 0; i < stops.length; i+= 1) {
  1966. if (stops[i] instanceof Expression) {
  1967. color = stops[i].value[0];
  1968. position = stops[i].value[1];
  1969. } else {
  1970. color = stops[i];
  1971. position = undefined;
  1972. }
  1973. if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
  1974. throwArgumentDescriptor();
  1975. }
  1976. positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%";
  1977. alpha = color.alpha;
  1978. returner += '<stop offset="' + positionValue + '" stop-color="' + color.toRGB() + '"' + (alpha < 1 ? ' stop-opacity="' + alpha + '"' : '') + '/>';
  1979. }
  1980. returner += '</' + gradientType + 'Gradient>' +
  1981. '<rect ' + rectangleDimension + ' fill="url(#gradient)" /></svg>';
  1982. returner = encodeURIComponent(returner);
  1983. returner = "data:image/svg+xml," + returner;
  1984. return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
  1985. });
  1986. };
  1987. },{"../tree/color":50,"../tree/dimension":56,"../tree/expression":59,"../tree/quoted":73,"../tree/url":80,"./function-registry":22}],29:[function(require,module,exports){
  1988. var Keyword = require("../tree/keyword"),
  1989. DetachedRuleset = require("../tree/detached-ruleset"),
  1990. Dimension = require("../tree/dimension"),
  1991. Color = require("../tree/color"),
  1992. Quoted = require("../tree/quoted"),
  1993. Anonymous = require("../tree/anonymous"),
  1994. URL = require("../tree/url"),
  1995. Operation = require("../tree/operation"),
  1996. functionRegistry = require("./function-registry");
  1997. var isa = function (n, Type) {
  1998. return (n instanceof Type) ? Keyword.True : Keyword.False;
  1999. },
  2000. isunit = function (n, unit) {
  2001. if (unit === undefined) {
  2002. throw { type: "Argument", message: "missing the required second argument to isunit." };
  2003. }
  2004. unit = typeof unit.value === "string" ? unit.value : unit;
  2005. if (typeof unit !== "string") {
  2006. throw { type: "Argument", message: "Second argument to isunit should be a unit or a string." };
  2007. }
  2008. return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
  2009. },
  2010. getItemsFromNode = function(node) {
  2011. // handle non-array values as an array of length 1
  2012. // return 'undefined' if index is invalid
  2013. var items = Array.isArray(node.value) ?
  2014. node.value : Array(node);
  2015. return items;
  2016. };
  2017. functionRegistry.addMultiple({
  2018. isruleset: function (n) {
  2019. return isa(n, DetachedRuleset);
  2020. },
  2021. iscolor: function (n) {
  2022. return isa(n, Color);
  2023. },
  2024. isnumber: function (n) {
  2025. return isa(n, Dimension);
  2026. },
  2027. isstring: function (n) {
  2028. return isa(n, Quoted);
  2029. },
  2030. iskeyword: function (n) {
  2031. return isa(n, Keyword);
  2032. },
  2033. isurl: function (n) {
  2034. return isa(n, URL);
  2035. },
  2036. ispixel: function (n) {
  2037. return isunit(n, 'px');
  2038. },
  2039. ispercentage: function (n) {
  2040. return isunit(n, '%');
  2041. },
  2042. isem: function (n) {
  2043. return isunit(n, 'em');
  2044. },
  2045. isunit: isunit,
  2046. unit: function (val, unit) {
  2047. if (!(val instanceof Dimension)) {
  2048. throw { type: "Argument",
  2049. message: "the first argument to unit must be a number" +
  2050. (val instanceof Operation ? ". Have you forgotten parenthesis?" : "") };
  2051. }
  2052. if (unit) {
  2053. if (unit instanceof Keyword) {
  2054. unit = unit.value;
  2055. } else {
  2056. unit = unit.toCSS();
  2057. }
  2058. } else {
  2059. unit = "";
  2060. }
  2061. return new Dimension(val.value, unit);
  2062. },
  2063. "get-unit": function (n) {
  2064. return new Anonymous(n.unit);
  2065. },
  2066. extract: function(values, index) {
  2067. index = index.value - 1; // (1-based index)
  2068. return getItemsFromNode(values)[index];
  2069. },
  2070. length: function(values) {
  2071. return new Dimension(getItemsFromNode(values).length);
  2072. }
  2073. });
  2074. },{"../tree/anonymous":46,"../tree/color":50,"../tree/detached-ruleset":55,"../tree/dimension":56,"../tree/keyword":65,"../tree/operation":71,"../tree/quoted":73,"../tree/url":80,"./function-registry":22}],30:[function(require,module,exports){
  2075. var contexts = require("./contexts"),
  2076. Parser = require('./parser/parser'),
  2077. FunctionImporter = require('./plugins/function-importer');
  2078. module.exports = function(environment) {
  2079. // FileInfo = {
  2080. // 'relativeUrls' - option - whether to adjust URL's to be relative
  2081. // 'filename' - full resolved filename of current file
  2082. // 'rootpath' - path to append to normal URLs for this node
  2083. // 'currentDirectory' - path to the current file, absolute
  2084. // 'rootFilename' - filename of the base file
  2085. // 'entryPath' - absolute path to the entry file
  2086. // 'reference' - whether the file should not be output and only output parts that are referenced
  2087. var ImportManager = function(context, rootFileInfo) {
  2088. this.rootFilename = rootFileInfo.filename;
  2089. this.paths = context.paths || []; // Search paths, when importing
  2090. this.contents = {}; // map - filename to contents of all the files
  2091. this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore
  2092. this.mime = context.mime;
  2093. this.error = null;
  2094. this.context = context;
  2095. // Deprecated? Unused outside of here, could be useful.
  2096. this.queue = []; // Files which haven't been imported yet
  2097. this.files = {}; // Holds the imported parse trees.
  2098. };
  2099. /**
  2100. * Add an import to be imported
  2101. * @param path - the raw path
  2102. * @param tryAppendLessExtension - whether to try appending the less extension (if the path has no extension)
  2103. * @param currentFileInfo - the current file info (used for instance to work out relative paths)
  2104. * @param importOptions - import options
  2105. * @param callback - callback for when it is imported
  2106. */
  2107. ImportManager.prototype.push = function (path, tryAppendLessExtension, currentFileInfo, importOptions, callback) {
  2108. var importManager = this;
  2109. this.queue.push(path);
  2110. var fileParsedFunc = function (e, root, fullPath) {
  2111. importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue
  2112. var importedEqualsRoot = fullPath === importManager.rootFilename;
  2113. if (importOptions.optional && e) {
  2114. callback(null, {rules:[]}, false, null);
  2115. }
  2116. else {
  2117. importManager.files[fullPath] = root;
  2118. if (e && !importManager.error) { importManager.error = e; }
  2119. callback(e, root, importedEqualsRoot, fullPath);
  2120. }
  2121. };
  2122. var newFileInfo = {
  2123. relativeUrls: this.context.relativeUrls,
  2124. entryPath: currentFileInfo.entryPath,
  2125. rootpath: currentFileInfo.rootpath,
  2126. rootFilename: currentFileInfo.rootFilename
  2127. };
  2128. var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
  2129. if (!fileManager) {
  2130. fileParsedFunc({ message: "Could not find a file-manager for " + path });
  2131. return;
  2132. }
  2133. if (tryAppendLessExtension) {
  2134. path = fileManager.tryAppendExtension(path, importOptions.plugin ? ".js" : ".less");
  2135. }
  2136. var loadFileCallback = function(loadedFile) {
  2137. var resolvedFilename = loadedFile.filename,
  2138. contents = loadedFile.contents.replace(/^\uFEFF/, '');
  2139. // Pass on an updated rootpath if path of imported file is relative and file
  2140. // is in a (sub|sup) directory
  2141. //
  2142. // Examples:
  2143. // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',
  2144. // then rootpath should become 'less/module/nav/'
  2145. // - If path of imported file is '../mixins.less' and rootpath is 'less/',
  2146. // then rootpath should become 'less/../'
  2147. newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
  2148. if (newFileInfo.relativeUrls) {
  2149. newFileInfo.rootpath = fileManager.join(
  2150. (importManager.context.rootpath || ""),
  2151. fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
  2152. if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
  2153. newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);
  2154. }
  2155. }
  2156. newFileInfo.filename = resolvedFilename;
  2157. var newEnv = new contexts.Parse(importManager.context);
  2158. newEnv.processImports = false;
  2159. importManager.contents[resolvedFilename] = contents;
  2160. if (currentFileInfo.reference || importOptions.reference) {
  2161. newFileInfo.reference = true;
  2162. }
  2163. if (importOptions.plugin) {
  2164. new FunctionImporter(newEnv, newFileInfo).eval(contents, function (e, root) {
  2165. fileParsedFunc(e, root, resolvedFilename);
  2166. });
  2167. } else if (importOptions.inline) {
  2168. fileParsedFunc(null, contents, resolvedFilename);
  2169. } else {
  2170. new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) {
  2171. fileParsedFunc(e, root, resolvedFilename);
  2172. });
  2173. }
  2174. };
  2175. var promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, this.context, environment,
  2176. function(err, loadedFile) {
  2177. if (err) {
  2178. fileParsedFunc(err);
  2179. } else {
  2180. loadFileCallback(loadedFile);
  2181. }
  2182. });
  2183. if (promise) {
  2184. promise.then(loadFileCallback, fileParsedFunc);
  2185. }
  2186. };
  2187. return ImportManager;
  2188. };
  2189. },{"./contexts":11,"./parser/parser":38,"./plugins/function-importer":40}],31:[function(require,module,exports){
  2190. module.exports = function(environment, fileManagers) {
  2191. var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;
  2192. var less = {
  2193. version: [2, 7, 3],
  2194. data: require('./data'),
  2195. tree: require('./tree'),
  2196. Environment: (Environment = require("./environment/environment")),
  2197. AbstractFileManager: require("./environment/abstract-file-manager"),
  2198. environment: (environment = new Environment(environment, fileManagers)),
  2199. visitors: require('./visitors'),
  2200. Parser: require('./parser/parser'),
  2201. functions: require('./functions')(environment),
  2202. contexts: require("./contexts"),
  2203. SourceMapOutput: (SourceMapOutput = require('./source-map-output')(environment)),
  2204. SourceMapBuilder: (SourceMapBuilder = require('./source-map-builder')(SourceMapOutput, environment)),
  2205. ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)),
  2206. ImportManager: (ImportManager = require('./import-manager')(environment)),
  2207. render: require("./render")(environment, ParseTree, ImportManager),
  2208. parse: require("./parse")(environment, ParseTree, ImportManager),
  2209. LessError: require('./less-error'),
  2210. transformTree: require('./transform-tree'),
  2211. utils: require('./utils'),
  2212. PluginManager: require('./plugin-manager'),
  2213. logger: require('./logger')
  2214. };
  2215. return less;
  2216. };
  2217. },{"./contexts":11,"./data":13,"./environment/abstract-file-manager":15,"./environment/environment":16,"./functions":23,"./import-manager":30,"./less-error":32,"./logger":33,"./parse":35,"./parse-tree":34,"./parser/parser":38,"./plugin-manager":39,"./render":41,"./source-map-builder":42,"./source-map-output":43,"./transform-tree":44,"./tree":62,"./utils":83,"./visitors":87}],32:[function(require,module,exports){
  2218. var utils = require("./utils");
  2219. var LessError = module.exports = function LessError(e, importManager, currentFilename) {
  2220. Error.call(this);
  2221. var filename = e.filename || currentFilename;
  2222. if (importManager && filename) {
  2223. var input = importManager.contents[filename],
  2224. loc = utils.getLocation(e.index, input),
  2225. line = loc.line,
  2226. col = loc.column,
  2227. callLine = e.call && utils.getLocation(e.call, input).line,
  2228. lines = input.split('\n');
  2229. this.type = e.type || 'Syntax';
  2230. this.filename = filename;
  2231. this.index = e.index;
  2232. this.line = typeof line === 'number' ? line + 1 : null;
  2233. this.callLine = callLine + 1;
  2234. this.callExtract = lines[callLine];
  2235. this.column = col;
  2236. this.extract = [
  2237. lines[line - 1],
  2238. lines[line],
  2239. lines[line + 1]
  2240. ];
  2241. }
  2242. this.message = e.message;
  2243. this.stack = e.stack;
  2244. };
  2245. if (typeof Object.create === 'undefined') {
  2246. var F = function () {};
  2247. F.prototype = Error.prototype;
  2248. LessError.prototype = new F();
  2249. } else {
  2250. LessError.prototype = Object.create(Error.prototype);
  2251. }
  2252. LessError.prototype.constructor = LessError;
  2253. },{"./utils":83}],33:[function(require,module,exports){
  2254. module.exports = {
  2255. error: function(msg) {
  2256. this._fireEvent("error", msg);
  2257. },
  2258. warn: function(msg) {
  2259. this._fireEvent("warn", msg);
  2260. },
  2261. info: function(msg) {
  2262. this._fireEvent("info", msg);
  2263. },
  2264. debug: function(msg) {
  2265. this._fireEvent("debug", msg);
  2266. },
  2267. addListener: function(listener) {
  2268. this._listeners.push(listener);
  2269. },
  2270. removeListener: function(listener) {
  2271. for (var i = 0; i < this._listeners.length; i++) {
  2272. if (this._listeners[i] === listener) {
  2273. this._listeners.splice(i, 1);
  2274. return;
  2275. }
  2276. }
  2277. },
  2278. _fireEvent: function(type, msg) {
  2279. for (var i = 0; i < this._listeners.length; i++) {
  2280. var logFunction = this._listeners[i][type];
  2281. if (logFunction) {
  2282. logFunction(msg);
  2283. }
  2284. }
  2285. },
  2286. _listeners: []
  2287. };
  2288. },{}],34:[function(require,module,exports){
  2289. var LessError = require('./less-error'),
  2290. transformTree = require("./transform-tree"),
  2291. logger = require("./logger");
  2292. module.exports = function(SourceMapBuilder) {
  2293. var ParseTree = function(root, imports) {
  2294. this.root = root;
  2295. this.imports = imports;
  2296. };
  2297. ParseTree.prototype.toCSS = function(options) {
  2298. var evaldRoot, result = {}, sourceMapBuilder;
  2299. try {
  2300. evaldRoot = transformTree(this.root, options);
  2301. } catch (e) {
  2302. throw new LessError(e, this.imports);
  2303. }
  2304. try {
  2305. var compress = Boolean(options.compress);
  2306. if (compress) {
  2307. logger.warn("The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.");
  2308. }
  2309. var toCSSOptions = {
  2310. compress: compress,
  2311. dumpLineNumbers: options.dumpLineNumbers,
  2312. strictUnits: Boolean(options.strictUnits),
  2313. numPrecision: 8};
  2314. if (options.sourceMap) {
  2315. sourceMapBuilder = new SourceMapBuilder(options.sourceMap);
  2316. result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);
  2317. } else {
  2318. result.css = evaldRoot.toCSS(toCSSOptions);
  2319. }
  2320. } catch (e) {
  2321. throw new LessError(e, this.imports);
  2322. }
  2323. if (options.pluginManager) {
  2324. var postProcessors = options.pluginManager.getPostProcessors();
  2325. for (var i = 0; i < postProcessors.length; i++) {
  2326. result.css = postProcessors[i].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports });
  2327. }
  2328. }
  2329. if (options.sourceMap) {
  2330. result.map = sourceMapBuilder.getExternalSourceMap();
  2331. }
  2332. result.imports = [];
  2333. for (var file in this.imports.files) {
  2334. if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) {
  2335. result.imports.push(file);
  2336. }
  2337. }
  2338. return result;
  2339. };
  2340. return ParseTree;
  2341. };
  2342. },{"./less-error":32,"./logger":33,"./transform-tree":44}],35:[function(require,module,exports){
  2343. var PromiseConstructor,
  2344. contexts = require("./contexts"),
  2345. Parser = require('./parser/parser'),
  2346. PluginManager = require('./plugin-manager');
  2347. module.exports = function(environment, ParseTree, ImportManager) {
  2348. var parse = function (input, options, callback) {
  2349. options = options || {};
  2350. if (typeof options === 'function') {
  2351. callback = options;
  2352. options = {};
  2353. }
  2354. if (!callback) {
  2355. if (!PromiseConstructor) {
  2356. PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;
  2357. }
  2358. var self = this;
  2359. return new PromiseConstructor(function (resolve, reject) {
  2360. parse.call(self, input, options, function(err, output) {
  2361. if (err) {
  2362. reject(err);
  2363. } else {
  2364. resolve(output);
  2365. }
  2366. });
  2367. });
  2368. } else {
  2369. var context,
  2370. rootFileInfo,
  2371. pluginManager = new PluginManager(this);
  2372. pluginManager.addPlugins(options.plugins);
  2373. options.pluginManager = pluginManager;
  2374. context = new contexts.Parse(options);
  2375. if (options.rootFileInfo) {
  2376. rootFileInfo = options.rootFileInfo;
  2377. } else {
  2378. var filename = options.filename || "input";
  2379. var entryPath = filename.replace(/[^\/\\]*$/, "");
  2380. rootFileInfo = {
  2381. filename: filename,
  2382. relativeUrls: context.relativeUrls,
  2383. rootpath: context.rootpath || "",
  2384. currentDirectory: entryPath,
  2385. entryPath: entryPath,
  2386. rootFilename: filename
  2387. };
  2388. // add in a missing trailing slash
  2389. if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== "/") {
  2390. rootFileInfo.rootpath += "/";
  2391. }
  2392. }
  2393. var imports = new ImportManager(context, rootFileInfo);
  2394. new Parser(context, imports, rootFileInfo)
  2395. .parse(input, function (e, root) {
  2396. if (e) { return callback(e); }
  2397. callback(null, root, imports, options);
  2398. }, options);
  2399. }
  2400. };
  2401. return parse;
  2402. };
  2403. },{"./contexts":11,"./parser/parser":38,"./plugin-manager":39,"promise":undefined}],36:[function(require,module,exports){
  2404. // Split the input into chunks.
  2405. module.exports = function (input, fail) {
  2406. var len = input.length, level = 0, parenLevel = 0,
  2407. lastOpening, lastOpeningParen, lastMultiComment, lastMultiCommentEndBrace,
  2408. chunks = [], emitFrom = 0,
  2409. chunkerCurrentIndex, currentChunkStartIndex, cc, cc2, matched;
  2410. function emitChunk(force) {
  2411. var len = chunkerCurrentIndex - emitFrom;
  2412. if (((len < 512) && !force) || !len) {
  2413. return;
  2414. }
  2415. chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));
  2416. emitFrom = chunkerCurrentIndex + 1;
  2417. }
  2418. for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  2419. cc = input.charCodeAt(chunkerCurrentIndex);
  2420. if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {
  2421. // a-z or whitespace
  2422. continue;
  2423. }
  2424. switch (cc) {
  2425. case 40: // (
  2426. parenLevel++;
  2427. lastOpeningParen = chunkerCurrentIndex;
  2428. continue;
  2429. case 41: // )
  2430. if (--parenLevel < 0) {
  2431. return fail("missing opening `(`", chunkerCurrentIndex);
  2432. }
  2433. continue;
  2434. case 59: // ;
  2435. if (!parenLevel) { emitChunk(); }
  2436. continue;
  2437. case 123: // {
  2438. level++;
  2439. lastOpening = chunkerCurrentIndex;
  2440. continue;
  2441. case 125: // }
  2442. if (--level < 0) {
  2443. return fail("missing opening `{`", chunkerCurrentIndex);
  2444. }
  2445. if (!level && !parenLevel) { emitChunk(); }
  2446. continue;
  2447. case 92: // \
  2448. if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }
  2449. return fail("unescaped `\\`", chunkerCurrentIndex);
  2450. case 34:
  2451. case 39:
  2452. case 96: // ", ' and `
  2453. matched = 0;
  2454. currentChunkStartIndex = chunkerCurrentIndex;
  2455. for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  2456. cc2 = input.charCodeAt(chunkerCurrentIndex);
  2457. if (cc2 > 96) { continue; }
  2458. if (cc2 == cc) { matched = 1; break; }
  2459. if (cc2 == 92) { // \
  2460. if (chunkerCurrentIndex == len - 1) {
  2461. return fail("unescaped `\\`", chunkerCurrentIndex);
  2462. }
  2463. chunkerCurrentIndex++;
  2464. }
  2465. }
  2466. if (matched) { continue; }
  2467. return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
  2468. case 47: // /, check for comment
  2469. if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }
  2470. cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
  2471. if (cc2 == 47) {
  2472. // //, find lnfeed
  2473. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {
  2474. cc2 = input.charCodeAt(chunkerCurrentIndex);
  2475. if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }
  2476. }
  2477. } else if (cc2 == 42) {
  2478. // /*, find */
  2479. lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;
  2480. for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {
  2481. cc2 = input.charCodeAt(chunkerCurrentIndex);
  2482. if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }
  2483. if (cc2 != 42) { continue; }
  2484. if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }
  2485. }
  2486. if (chunkerCurrentIndex == len - 1) {
  2487. return fail("missing closing `*/`", currentChunkStartIndex);
  2488. }
  2489. chunkerCurrentIndex++;
  2490. }
  2491. continue;
  2492. case 42: // *, check for unmatched */
  2493. if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
  2494. return fail("unmatched `/*`", chunkerCurrentIndex);
  2495. }
  2496. continue;
  2497. }
  2498. }
  2499. if (level !== 0) {
  2500. if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
  2501. return fail("missing closing `}` or `*/`", lastOpening);
  2502. } else {
  2503. return fail("missing closing `}`", lastOpening);
  2504. }
  2505. } else if (parenLevel !== 0) {
  2506. return fail("missing closing `)`", lastOpeningParen);
  2507. }
  2508. emitChunk(true);
  2509. return chunks;
  2510. };
  2511. },{}],37:[function(require,module,exports){
  2512. var chunker = require('./chunker');
  2513. module.exports = function() {
  2514. var input, // LeSS input string
  2515. j, // current chunk
  2516. saveStack = [], // holds state for backtracking
  2517. furthest, // furthest index the parser has gone to
  2518. furthestPossibleErrorMessage,// if this is furthest we got to, this is the probably cause
  2519. chunks, // chunkified input
  2520. current, // current chunk
  2521. currentPos, // index of current chunk, in `input`
  2522. parserInput = {};
  2523. var CHARCODE_SPACE = 32,
  2524. CHARCODE_TAB = 9,
  2525. CHARCODE_LF = 10,
  2526. CHARCODE_CR = 13,
  2527. CHARCODE_PLUS = 43,
  2528. CHARCODE_COMMA = 44,
  2529. CHARCODE_FORWARD_SLASH = 47,
  2530. CHARCODE_9 = 57;
  2531. function skipWhitespace(length) {
  2532. var oldi = parserInput.i, oldj = j,
  2533. curr = parserInput.i - currentPos,
  2534. endIndex = parserInput.i + current.length - curr,
  2535. mem = (parserInput.i += length),
  2536. inp = input,
  2537. c, nextChar, comment;
  2538. for (; parserInput.i < endIndex; parserInput.i++) {
  2539. c = inp.charCodeAt(parserInput.i);
  2540. if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {
  2541. nextChar = inp.charAt(parserInput.i + 1);
  2542. if (nextChar === '/') {
  2543. comment = {index: parserInput.i, isLineComment: true};
  2544. var nextNewLine = inp.indexOf("\n", parserInput.i + 2);
  2545. if (nextNewLine < 0) {
  2546. nextNewLine = endIndex;
  2547. }
  2548. parserInput.i = nextNewLine;
  2549. comment.text = inp.substr(comment.index, parserInput.i - comment.index);
  2550. parserInput.commentStore.push(comment);
  2551. continue;
  2552. } else if (nextChar === '*') {
  2553. var nextStarSlash = inp.indexOf("*/", parserInput.i + 2);
  2554. if (nextStarSlash >= 0) {
  2555. comment = {
  2556. index: parserInput.i,
  2557. text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),
  2558. isLineComment: false
  2559. };
  2560. parserInput.i += comment.text.length - 1;
  2561. parserInput.commentStore.push(comment);
  2562. continue;
  2563. }
  2564. }
  2565. break;
  2566. }
  2567. if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {
  2568. break;
  2569. }
  2570. }
  2571. current = current.slice(length + parserInput.i - mem + curr);
  2572. currentPos = parserInput.i;
  2573. if (!current.length) {
  2574. if (j < chunks.length - 1) {
  2575. current = chunks[++j];
  2576. skipWhitespace(0); // skip space at the beginning of a chunk
  2577. return true; // things changed
  2578. }
  2579. parserInput.finished = true;
  2580. }
  2581. return oldi !== parserInput.i || oldj !== j;
  2582. }
  2583. parserInput.save = function() {
  2584. currentPos = parserInput.i;
  2585. saveStack.push( { current: current, i: parserInput.i, j: j });
  2586. };
  2587. parserInput.restore = function(possibleErrorMessage) {
  2588. if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {
  2589. furthest = parserInput.i;
  2590. furthestPossibleErrorMessage = possibleErrorMessage;
  2591. }
  2592. var state = saveStack.pop();
  2593. current = state.current;
  2594. currentPos = parserInput.i = state.i;
  2595. j = state.j;
  2596. };
  2597. parserInput.forget = function() {
  2598. saveStack.pop();
  2599. };
  2600. parserInput.isWhitespace = function (offset) {
  2601. var pos = parserInput.i + (offset || 0),
  2602. code = input.charCodeAt(pos);
  2603. return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);
  2604. };
  2605. // Specialization of $(tok)
  2606. parserInput.$re = function(tok) {
  2607. if (parserInput.i > currentPos) {
  2608. current = current.slice(parserInput.i - currentPos);
  2609. currentPos = parserInput.i;
  2610. }
  2611. var m = tok.exec(current);
  2612. if (!m) {
  2613. return null;
  2614. }
  2615. skipWhitespace(m[0].length);
  2616. if (typeof m === "string") {
  2617. return m;
  2618. }
  2619. return m.length === 1 ? m[0] : m;
  2620. };
  2621. parserInput.$char = function(tok) {
  2622. if (input.charAt(parserInput.i) !== tok) {
  2623. return null;
  2624. }
  2625. skipWhitespace(1);
  2626. return tok;
  2627. };
  2628. parserInput.$str = function(tok) {
  2629. var tokLength = tok.length;
  2630. // https://jsperf.com/string-startswith/21
  2631. for (var i = 0; i < tokLength; i++) {
  2632. if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {
  2633. return null;
  2634. }
  2635. }
  2636. skipWhitespace(tokLength);
  2637. return tok;
  2638. };
  2639. parserInput.$quoted = function() {
  2640. var startChar = input.charAt(parserInput.i);
  2641. if (startChar !== "'" && startChar !== '"') {
  2642. return;
  2643. }
  2644. var length = input.length,
  2645. currentPosition = parserInput.i;
  2646. for (var i = 1; i + currentPosition < length; i++) {
  2647. var nextChar = input.charAt(i + currentPosition);
  2648. switch(nextChar) {
  2649. case "\\":
  2650. i++;
  2651. continue;
  2652. case "\r":
  2653. case "\n":
  2654. break;
  2655. case startChar:
  2656. var str = input.substr(currentPosition, i + 1);
  2657. skipWhitespace(i + 1);
  2658. return str;
  2659. default:
  2660. }
  2661. }
  2662. return null;
  2663. };
  2664. parserInput.autoCommentAbsorb = true;
  2665. parserInput.commentStore = [];
  2666. parserInput.finished = false;
  2667. // Same as $(), but don't change the state of the parser,
  2668. // just return the match.
  2669. parserInput.peek = function(tok) {
  2670. if (typeof tok === 'string') {
  2671. // https://jsperf.com/string-startswith/21
  2672. for (var i = 0; i < tok.length; i++) {
  2673. if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {
  2674. return false;
  2675. }
  2676. }
  2677. return true;
  2678. } else {
  2679. return tok.test(current);
  2680. }
  2681. };
  2682. // Specialization of peek()
  2683. // TODO remove or change some currentChar calls to peekChar
  2684. parserInput.peekChar = function(tok) {
  2685. return input.charAt(parserInput.i) === tok;
  2686. };
  2687. parserInput.currentChar = function() {
  2688. return input.charAt(parserInput.i);
  2689. };
  2690. parserInput.getInput = function() {
  2691. return input;
  2692. };
  2693. parserInput.peekNotNumeric = function() {
  2694. var c = input.charCodeAt(parserInput.i);
  2695. //Is the first char of the dimension 0-9, '.', '+' or '-'
  2696. return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;
  2697. };
  2698. parserInput.start = function(str, chunkInput, failFunction) {
  2699. input = str;
  2700. parserInput.i = j = currentPos = furthest = 0;
  2701. // chunking apparently makes things quicker (but my tests indicate
  2702. // it might actually make things slower in node at least)
  2703. // and it is a non-perfect parse - it can't recognise
  2704. // unquoted urls, meaning it can't distinguish comments
  2705. // meaning comments with quotes or {}() in them get 'counted'
  2706. // and then lead to parse errors.
  2707. // In addition if the chunking chunks in the wrong place we might
  2708. // not be able to parse a parser statement in one go
  2709. // this is officially deprecated but can be switched on via an option
  2710. // in the case it causes too much performance issues.
  2711. if (chunkInput) {
  2712. chunks = chunker(str, failFunction);
  2713. } else {
  2714. chunks = [str];
  2715. }
  2716. current = chunks[0];
  2717. skipWhitespace(0);
  2718. };
  2719. parserInput.end = function() {
  2720. var message,
  2721. isFinished = parserInput.i >= input.length;
  2722. if (parserInput.i < furthest) {
  2723. message = furthestPossibleErrorMessage;
  2724. parserInput.i = furthest;
  2725. }
  2726. return {
  2727. isFinished: isFinished,
  2728. furthest: parserInput.i,
  2729. furthestPossibleErrorMessage: message,
  2730. furthestReachedEnd: parserInput.i >= input.length - 1,
  2731. furthestChar: input[parserInput.i]
  2732. };
  2733. };
  2734. return parserInput;
  2735. };
  2736. },{"./chunker":36}],38:[function(require,module,exports){
  2737. var LessError = require('../less-error'),
  2738. tree = require("../tree"),
  2739. visitors = require("../visitors"),
  2740. getParserInput = require("./parser-input"),
  2741. utils = require("../utils");
  2742. //
  2743. // less.js - parser
  2744. //
  2745. // A relatively straight-forward predictive parser.
  2746. // There is no tokenization/lexing stage, the input is parsed
  2747. // in one sweep.
  2748. //
  2749. // To make the parser fast enough to run in the browser, several
  2750. // optimization had to be made:
  2751. //
  2752. // - Matching and slicing on a huge input is often cause of slowdowns.
  2753. // The solution is to chunkify the input into smaller strings.
  2754. // The chunks are stored in the `chunks` var,
  2755. // `j` holds the current chunk index, and `currentPos` holds
  2756. // the index of the current chunk in relation to `input`.
  2757. // This gives us an almost 4x speed-up.
  2758. //
  2759. // - In many cases, we don't need to match individual tokens;
  2760. // for example, if a value doesn't hold any variables, operations
  2761. // or dynamic references, the parser can effectively 'skip' it,
  2762. // treating it as a literal.
  2763. // An example would be '1px solid #000' - which evaluates to itself,
  2764. // we don't need to know what the individual components are.
  2765. // The drawback, of course is that you don't get the benefits of
  2766. // syntax-checking on the CSS. This gives us a 50% speed-up in the parser,
  2767. // and a smaller speed-up in the code-gen.
  2768. //
  2769. //
  2770. // Token matching is done with the `$` function, which either takes
  2771. // a terminal string or regexp, or a non-terminal function to call.
  2772. // It also takes care of moving all the indices forwards.
  2773. //`
  2774. //
  2775. var Parser = function Parser(context, imports, fileInfo) {
  2776. var parsers,
  2777. parserInput = getParserInput();
  2778. function error(msg, type) {
  2779. throw new LessError(
  2780. {
  2781. index: parserInput.i,
  2782. filename: fileInfo.filename,
  2783. type: type || 'Syntax',
  2784. message: msg
  2785. },
  2786. imports
  2787. );
  2788. }
  2789. function expect(arg, msg, index) {
  2790. // some older browsers return typeof 'function' for RegExp
  2791. var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);
  2792. if (result) {
  2793. return result;
  2794. }
  2795. error(msg || (typeof arg === 'string' ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'"
  2796. : "unexpected token"));
  2797. }
  2798. // Specialization of expect()
  2799. function expectChar(arg, msg) {
  2800. if (parserInput.$char(arg)) {
  2801. return arg;
  2802. }
  2803. error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'");
  2804. }
  2805. function getDebugInfo(index) {
  2806. var filename = fileInfo.filename;
  2807. return {
  2808. lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1,
  2809. fileName: filename
  2810. };
  2811. }
  2812. //
  2813. // The Parser
  2814. //
  2815. return {
  2816. //
  2817. // Parse an input string into an abstract syntax tree,
  2818. // @param str A string containing 'less' markup
  2819. // @param callback call `callback` when done.
  2820. // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply
  2821. //
  2822. parse: function (str, callback, additionalData) {
  2823. var root, error = null, globalVars, modifyVars, ignored, preText = "";
  2824. globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + '\n' : '';
  2825. modifyVars = (additionalData && additionalData.modifyVars) ? '\n' + Parser.serializeVars(additionalData.modifyVars) : '';
  2826. if (context.pluginManager) {
  2827. var preProcessors = context.pluginManager.getPreProcessors();
  2828. for (var i = 0; i < preProcessors.length; i++) {
  2829. str = preProcessors[i].process(str, { context: context, imports: imports, fileInfo: fileInfo });
  2830. }
  2831. }
  2832. if (globalVars || (additionalData && additionalData.banner)) {
  2833. preText = ((additionalData && additionalData.banner) ? additionalData.banner : "") + globalVars;
  2834. ignored = imports.contentsIgnoredChars;
  2835. ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;
  2836. ignored[fileInfo.filename] += preText.length;
  2837. }
  2838. str = str.replace(/\r\n?/g, '\n');
  2839. // Remove potential UTF Byte Order Mark
  2840. str = preText + str.replace(/^\uFEFF/, '') + modifyVars;
  2841. imports.contents[fileInfo.filename] = str;
  2842. // Start with the primary rule.
  2843. // The whole syntax tree is held under a Ruleset node,
  2844. // with the `root` property set to true, so no `{}` are
  2845. // output. The callback is called when the input is parsed.
  2846. try {
  2847. parserInput.start(str, context.chunkInput, function fail(msg, index) {
  2848. throw new LessError({
  2849. index: index,
  2850. type: 'Parse',
  2851. message: msg,
  2852. filename: fileInfo.filename
  2853. }, imports);
  2854. });
  2855. root = new(tree.Ruleset)(null, this.parsers.primary());
  2856. root.root = true;
  2857. root.firstRoot = true;
  2858. } catch (e) {
  2859. return callback(new LessError(e, imports, fileInfo.filename));
  2860. }
  2861. // If `i` is smaller than the `input.length - 1`,
  2862. // it means the parser wasn't able to parse the whole
  2863. // string, so we've got a parsing error.
  2864. //
  2865. // We try to extract a \n delimited string,
  2866. // showing the line where the parse error occurred.
  2867. // We split it up into two parts (the part which parsed,
  2868. // and the part which didn't), so we can color them differently.
  2869. var endInfo = parserInput.end();
  2870. if (!endInfo.isFinished) {
  2871. var message = endInfo.furthestPossibleErrorMessage;
  2872. if (!message) {
  2873. message = "Unrecognised input";
  2874. if (endInfo.furthestChar === '}') {
  2875. message += ". Possibly missing opening '{'";
  2876. } else if (endInfo.furthestChar === ')') {
  2877. message += ". Possibly missing opening '('";
  2878. } else if (endInfo.furthestReachedEnd) {
  2879. message += ". Possibly missing something";
  2880. }
  2881. }
  2882. error = new LessError({
  2883. type: "Parse",
  2884. message: message,
  2885. index: endInfo.furthest,
  2886. filename: fileInfo.filename
  2887. }, imports);
  2888. }
  2889. var finish = function (e) {
  2890. e = error || e || imports.error;
  2891. if (e) {
  2892. if (!(e instanceof LessError)) {
  2893. e = new LessError(e, imports, fileInfo.filename);
  2894. }
  2895. return callback(e);
  2896. }
  2897. else {
  2898. return callback(null, root);
  2899. }
  2900. };
  2901. if (context.processImports !== false) {
  2902. new visitors.ImportVisitor(imports, finish)
  2903. .run(root);
  2904. } else {
  2905. return finish();
  2906. }
  2907. },
  2908. //
  2909. // Here in, the parsing rules/functions
  2910. //
  2911. // The basic structure of the syntax tree generated is as follows:
  2912. //
  2913. // Ruleset -> Rule -> Value -> Expression -> Entity
  2914. //
  2915. // Here's some Less code:
  2916. //
  2917. // .class {
  2918. // color: #fff;
  2919. // border: 1px solid #000;
  2920. // width: @w + 4px;
  2921. // > .child {...}
  2922. // }
  2923. //
  2924. // And here's what the parse tree might look like:
  2925. //
  2926. // Ruleset (Selector '.class', [
  2927. // Rule ("color", Value ([Expression [Color #fff]]))
  2928. // Rule ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]]))
  2929. // Rule ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]]))
  2930. // Ruleset (Selector [Element '>', '.child'], [...])
  2931. // ])
  2932. //
  2933. // In general, most rules will try to parse a token with the `$re()` function, and if the return
  2934. // value is truly, will return a new node, of the relevant type. Sometimes, we need to check
  2935. // first, before parsing, that's when we use `peek()`.
  2936. //
  2937. parsers: parsers = {
  2938. //
  2939. // The `primary` rule is the *entry* and *exit* point of the parser.
  2940. // The rules here can appear at any level of the parse tree.
  2941. //
  2942. // The recursive nature of the grammar is an interplay between the `block`
  2943. // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,
  2944. // as represented by this simplified grammar:
  2945. //
  2946. // primary → (ruleset | rule)+
  2947. // ruleset → selector+ block
  2948. // block → '{' primary '}'
  2949. //
  2950. // Only at one point is the primary rule not called from the
  2951. // block rule: at the root level.
  2952. //
  2953. primary: function () {
  2954. var mixin = this.mixin, root = [], node;
  2955. while (true) {
  2956. while (true) {
  2957. node = this.comment();
  2958. if (!node) { break; }
  2959. root.push(node);
  2960. }
  2961. // always process comments before deciding if finished
  2962. if (parserInput.finished) {
  2963. break;
  2964. }
  2965. if (parserInput.peek('}')) {
  2966. break;
  2967. }
  2968. node = this.extendRule();
  2969. if (node) {
  2970. root = root.concat(node);
  2971. continue;
  2972. }
  2973. node = mixin.definition() || this.rule() || this.ruleset() ||
  2974. mixin.call() || this.rulesetCall() || this.entities.call() || this.directive();
  2975. if (node) {
  2976. root.push(node);
  2977. } else {
  2978. var foundSemiColon = false;
  2979. while (parserInput.$char(";")) {
  2980. foundSemiColon = true;
  2981. }
  2982. if (!foundSemiColon) {
  2983. break;
  2984. }
  2985. }
  2986. }
  2987. return root;
  2988. },
  2989. // comments are collected by the main parsing mechanism and then assigned to nodes
  2990. // where the current structure allows it
  2991. comment: function () {
  2992. if (parserInput.commentStore.length) {
  2993. var comment = parserInput.commentStore.shift();
  2994. return new(tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);
  2995. }
  2996. },
  2997. //
  2998. // Entities are tokens which can be found inside an Expression
  2999. //
  3000. entities: {
  3001. //
  3002. // A string, which supports escaping " and '
  3003. //
  3004. // "milky way" 'he\'s the one!'
  3005. //
  3006. quoted: function () {
  3007. var str, index = parserInput.i, isEscaped = false;
  3008. parserInput.save();
  3009. if (parserInput.$char("~")) {
  3010. isEscaped = true;
  3011. }
  3012. str = parserInput.$quoted();
  3013. if (!str) {
  3014. parserInput.restore();
  3015. return;
  3016. }
  3017. parserInput.forget();
  3018. return new(tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);
  3019. },
  3020. //
  3021. // A catch-all word, such as:
  3022. //
  3023. // black border-collapse
  3024. //
  3025. keyword: function () {
  3026. var k = parserInput.$char("%") || parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]*/);
  3027. if (k) {
  3028. return tree.Color.fromKeyword(k) || new(tree.Keyword)(k);
  3029. }
  3030. },
  3031. //
  3032. // A function call
  3033. //
  3034. // rgb(255, 0, 255)
  3035. //
  3036. // We also try to catch IE's `alpha()`, but let the `alpha` parser
  3037. // deal with the details.
  3038. //
  3039. // The arguments are parsed with the `entities.arguments` parser.
  3040. //
  3041. call: function () {
  3042. var name, nameLC, args, alpha, index = parserInput.i;
  3043. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  3044. if (parserInput.peek(/^url\(/i)) {
  3045. return;
  3046. }
  3047. parserInput.save();
  3048. name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/);
  3049. if (!name) { parserInput.forget(); return; }
  3050. name = name[1];
  3051. nameLC = name.toLowerCase();
  3052. if (nameLC === 'alpha') {
  3053. alpha = parsers.alpha();
  3054. if (alpha) {
  3055. parserInput.forget();
  3056. return alpha;
  3057. }
  3058. }
  3059. args = this.arguments();
  3060. if (! parserInput.$char(')')) {
  3061. parserInput.restore("Could not parse call arguments or missing ')'");
  3062. return;
  3063. }
  3064. parserInput.forget();
  3065. return new(tree.Call)(name, args, index, fileInfo);
  3066. },
  3067. arguments: function () {
  3068. var argsSemiColon = [], argsComma = [],
  3069. expressions = [],
  3070. isSemiColonSeparated, value, arg;
  3071. parserInput.save();
  3072. while (true) {
  3073. arg = parsers.detachedRuleset() || this.assignment() || parsers.expression();
  3074. if (!arg) {
  3075. break;
  3076. }
  3077. value = arg;
  3078. if (arg.value && arg.value.length == 1) {
  3079. value = arg.value[0];
  3080. }
  3081. if (value) {
  3082. expressions.push(value);
  3083. }
  3084. argsComma.push(value);
  3085. if (parserInput.$char(',')) {
  3086. continue;
  3087. }
  3088. if (parserInput.$char(';') || isSemiColonSeparated) {
  3089. isSemiColonSeparated = true;
  3090. if (expressions.length > 1) {
  3091. value = new(tree.Value)(expressions);
  3092. }
  3093. argsSemiColon.push(value);
  3094. expressions = [];
  3095. }
  3096. }
  3097. parserInput.forget();
  3098. return isSemiColonSeparated ? argsSemiColon : argsComma;
  3099. },
  3100. literal: function () {
  3101. return this.dimension() ||
  3102. this.color() ||
  3103. this.quoted() ||
  3104. this.unicodeDescriptor();
  3105. },
  3106. // Assignments are argument entities for calls.
  3107. // They are present in ie filter properties as shown below.
  3108. //
  3109. // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )
  3110. //
  3111. assignment: function () {
  3112. var key, value;
  3113. parserInput.save();
  3114. key = parserInput.$re(/^\w+(?=\s?=)/i);
  3115. if (!key) {
  3116. parserInput.restore();
  3117. return;
  3118. }
  3119. if (!parserInput.$char('=')) {
  3120. parserInput.restore();
  3121. return;
  3122. }
  3123. value = parsers.entity();
  3124. if (value) {
  3125. parserInput.forget();
  3126. return new(tree.Assignment)(key, value);
  3127. } else {
  3128. parserInput.restore();
  3129. }
  3130. },
  3131. //
  3132. // Parse url() tokens
  3133. //
  3134. // We use a specific rule for urls, because they don't really behave like
  3135. // standard function calls. The difference is that the argument doesn't have
  3136. // to be enclosed within a string, so it can't be parsed as an Expression.
  3137. //
  3138. url: function () {
  3139. var value, index = parserInput.i;
  3140. parserInput.autoCommentAbsorb = false;
  3141. if (!parserInput.$str("url(")) {
  3142. parserInput.autoCommentAbsorb = true;
  3143. return;
  3144. }
  3145. value = this.quoted() || this.variable() ||
  3146. parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || "";
  3147. parserInput.autoCommentAbsorb = true;
  3148. expectChar(')');
  3149. return new(tree.URL)((value.value != null || value instanceof tree.Variable) ?
  3150. value : new(tree.Anonymous)(value), index, fileInfo);
  3151. },
  3152. //
  3153. // A Variable entity, such as `@fink`, in
  3154. //
  3155. // width: @fink + 2px
  3156. //
  3157. // We use a different parser for variable definitions,
  3158. // see `parsers.variable`.
  3159. //
  3160. variable: function () {
  3161. var name, index = parserInput.i;
  3162. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) {
  3163. return new(tree.Variable)(name, index, fileInfo);
  3164. }
  3165. },
  3166. // A variable entity using the protective {} e.g. @{var}
  3167. variableCurly: function () {
  3168. var curly, index = parserInput.i;
  3169. if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) {
  3170. return new(tree.Variable)("@" + curly[1], index, fileInfo);
  3171. }
  3172. },
  3173. //
  3174. // A Hexadecimal color
  3175. //
  3176. // #4F3C2F
  3177. //
  3178. // `rgb` and `hsl` colors are parsed through the `entities.call` parser.
  3179. //
  3180. color: function () {
  3181. var rgb;
  3182. if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
  3183. // strip colons, brackets, whitespaces and other characters that should not
  3184. // definitely be part of color string
  3185. var colorCandidateString = rgb.input.match(/^#([\w]+).*/);
  3186. colorCandidateString = colorCandidateString[1];
  3187. if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters
  3188. error("Invalid HEX color code");
  3189. }
  3190. return new(tree.Color)(rgb[1], undefined, '#' + colorCandidateString);
  3191. }
  3192. },
  3193. colorKeyword: function () {
  3194. parserInput.save();
  3195. var autoCommentAbsorb = parserInput.autoCommentAbsorb;
  3196. parserInput.autoCommentAbsorb = false;
  3197. var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);
  3198. parserInput.autoCommentAbsorb = autoCommentAbsorb;
  3199. if (!k) {
  3200. parserInput.forget();
  3201. return;
  3202. }
  3203. parserInput.restore();
  3204. var color = tree.Color.fromKeyword(k);
  3205. if (color) {
  3206. parserInput.$str(k);
  3207. return color;
  3208. }
  3209. },
  3210. //
  3211. // A Dimension, that is, a number and a unit
  3212. //
  3213. // 0.5em 95%
  3214. //
  3215. dimension: function () {
  3216. if (parserInput.peekNotNumeric()) {
  3217. return;
  3218. }
  3219. var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i);
  3220. if (value) {
  3221. return new(tree.Dimension)(value[1], value[2]);
  3222. }
  3223. },
  3224. //
  3225. // A unicode descriptor, as is used in unicode-range
  3226. //
  3227. // U+0?? or U+00A1-00A9
  3228. //
  3229. unicodeDescriptor: function () {
  3230. var ud;
  3231. ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/);
  3232. if (ud) {
  3233. return new(tree.UnicodeDescriptor)(ud[0]);
  3234. }
  3235. },
  3236. //
  3237. // JavaScript code to be evaluated
  3238. //
  3239. // `window.location.href`
  3240. //
  3241. javascript: function () {
  3242. var js, index = parserInput.i;
  3243. parserInput.save();
  3244. var escape = parserInput.$char("~");
  3245. var jsQuote = parserInput.$char("`");
  3246. if (!jsQuote) {
  3247. parserInput.restore();
  3248. return;
  3249. }
  3250. js = parserInput.$re(/^[^`]*`/);
  3251. if (js) {
  3252. parserInput.forget();
  3253. return new(tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);
  3254. }
  3255. parserInput.restore("invalid javascript definition");
  3256. }
  3257. },
  3258. //
  3259. // The variable part of a variable definition. Used in the `rule` parser
  3260. //
  3261. // @fink:
  3262. //
  3263. variable: function () {
  3264. var name;
  3265. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { return name[1]; }
  3266. },
  3267. //
  3268. // The variable part of a variable definition. Used in the `rule` parser
  3269. //
  3270. // @fink();
  3271. //
  3272. rulesetCall: function () {
  3273. var name;
  3274. if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\(\s*\)\s*;/))) {
  3275. return new tree.RulesetCall(name[1]);
  3276. }
  3277. },
  3278. //
  3279. // extend syntax - used to extend selectors
  3280. //
  3281. extend: function(isRule) {
  3282. var elements, e, index = parserInput.i, option, extendList, extend;
  3283. if (!parserInput.$str(isRule ? "&:extend(" : ":extend(")) {
  3284. return;
  3285. }
  3286. do {
  3287. option = null;
  3288. elements = null;
  3289. while (! (option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) {
  3290. e = this.element();
  3291. if (!e) {
  3292. break;
  3293. }
  3294. if (elements) {
  3295. elements.push(e);
  3296. } else {
  3297. elements = [ e ];
  3298. }
  3299. }
  3300. option = option && option[1];
  3301. if (!elements) {
  3302. error("Missing target selector for :extend().");
  3303. }
  3304. extend = new(tree.Extend)(new(tree.Selector)(elements), option, index, fileInfo);
  3305. if (extendList) {
  3306. extendList.push(extend);
  3307. } else {
  3308. extendList = [ extend ];
  3309. }
  3310. } while (parserInput.$char(","));
  3311. expect(/^\)/);
  3312. if (isRule) {
  3313. expect(/^;/);
  3314. }
  3315. return extendList;
  3316. },
  3317. //
  3318. // extendRule - used in a rule to extend all the parent selectors
  3319. //
  3320. extendRule: function() {
  3321. return this.extend(true);
  3322. },
  3323. //
  3324. // Mixins
  3325. //
  3326. mixin: {
  3327. //
  3328. // A Mixin call, with an optional argument list
  3329. //
  3330. // #mixins > .square(#fff);
  3331. // .rounded(4px, black);
  3332. // .button;
  3333. //
  3334. // The `while` loop is there because mixins can be
  3335. // namespaced, but we only support the child and descendant
  3336. // selector for now.
  3337. //
  3338. call: function () {
  3339. var s = parserInput.currentChar(), important = false, index = parserInput.i, elemIndex,
  3340. elements, elem, e, c, args;
  3341. if (s !== '.' && s !== '#') { return; }
  3342. parserInput.save(); // stop us absorbing part of an invalid selector
  3343. while (true) {
  3344. elemIndex = parserInput.i;
  3345. e = parserInput.$re(/^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/);
  3346. if (!e) {
  3347. break;
  3348. }
  3349. elem = new(tree.Element)(c, e, elemIndex, fileInfo);
  3350. if (elements) {
  3351. elements.push(elem);
  3352. } else {
  3353. elements = [ elem ];
  3354. }
  3355. c = parserInput.$char('>');
  3356. }
  3357. if (elements) {
  3358. if (parserInput.$char('(')) {
  3359. args = this.args(true).args;
  3360. expectChar(')');
  3361. }
  3362. if (parsers.important()) {
  3363. important = true;
  3364. }
  3365. if (parsers.end()) {
  3366. parserInput.forget();
  3367. return new(tree.mixin.Call)(elements, args, index, fileInfo, important);
  3368. }
  3369. }
  3370. parserInput.restore();
  3371. },
  3372. args: function (isCall) {
  3373. var entities = parsers.entities,
  3374. returner = { args:null, variadic: false },
  3375. expressions = [], argsSemiColon = [], argsComma = [],
  3376. isSemiColonSeparated, expressionContainsNamed, name, nameLoop,
  3377. value, arg, expand;
  3378. parserInput.save();
  3379. while (true) {
  3380. if (isCall) {
  3381. arg = parsers.detachedRuleset() || parsers.expression();
  3382. } else {
  3383. parserInput.commentStore.length = 0;
  3384. if (parserInput.$str("...")) {
  3385. returner.variadic = true;
  3386. if (parserInput.$char(";") && !isSemiColonSeparated) {
  3387. isSemiColonSeparated = true;
  3388. }
  3389. (isSemiColonSeparated ? argsSemiColon : argsComma)
  3390. .push({ variadic: true });
  3391. break;
  3392. }
  3393. arg = entities.variable() || entities.literal() || entities.keyword();
  3394. }
  3395. if (!arg) {
  3396. break;
  3397. }
  3398. nameLoop = null;
  3399. if (arg.throwAwayComments) {
  3400. arg.throwAwayComments();
  3401. }
  3402. value = arg;
  3403. var val = null;
  3404. if (isCall) {
  3405. // Variable
  3406. if (arg.value && arg.value.length == 1) {
  3407. val = arg.value[0];
  3408. }
  3409. } else {
  3410. val = arg;
  3411. }
  3412. if (val && val instanceof tree.Variable) {
  3413. if (parserInput.$char(':')) {
  3414. if (expressions.length > 0) {
  3415. if (isSemiColonSeparated) {
  3416. error("Cannot mix ; and , as delimiter types");
  3417. }
  3418. expressionContainsNamed = true;
  3419. }
  3420. value = parsers.detachedRuleset() || parsers.expression();
  3421. if (!value) {
  3422. if (isCall) {
  3423. error("could not understand value for named argument");
  3424. } else {
  3425. parserInput.restore();
  3426. returner.args = [];
  3427. return returner;
  3428. }
  3429. }
  3430. nameLoop = (name = val.name);
  3431. } else if (parserInput.$str("...")) {
  3432. if (!isCall) {
  3433. returner.variadic = true;
  3434. if (parserInput.$char(";") && !isSemiColonSeparated) {
  3435. isSemiColonSeparated = true;
  3436. }
  3437. (isSemiColonSeparated ? argsSemiColon : argsComma)
  3438. .push({ name: arg.name, variadic: true });
  3439. break;
  3440. } else {
  3441. expand = true;
  3442. }
  3443. } else if (!isCall) {
  3444. name = nameLoop = val.name;
  3445. value = null;
  3446. }
  3447. }
  3448. if (value) {
  3449. expressions.push(value);
  3450. }
  3451. argsComma.push({ name:nameLoop, value:value, expand:expand });
  3452. if (parserInput.$char(',')) {
  3453. continue;
  3454. }
  3455. if (parserInput.$char(';') || isSemiColonSeparated) {
  3456. if (expressionContainsNamed) {
  3457. error("Cannot mix ; and , as delimiter types");
  3458. }
  3459. isSemiColonSeparated = true;
  3460. if (expressions.length > 1) {
  3461. value = new(tree.Value)(expressions);
  3462. }
  3463. argsSemiColon.push({ name:name, value:value, expand:expand });
  3464. name = null;
  3465. expressions = [];
  3466. expressionContainsNamed = false;
  3467. }
  3468. }
  3469. parserInput.forget();
  3470. returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;
  3471. return returner;
  3472. },
  3473. //
  3474. // A Mixin definition, with a list of parameters
  3475. //
  3476. // .rounded (@radius: 2px, @color) {
  3477. // ...
  3478. // }
  3479. //
  3480. // Until we have a finer grained state-machine, we have to
  3481. // do a look-ahead, to make sure we don't have a mixin call.
  3482. // See the `rule` function for more information.
  3483. //
  3484. // We start by matching `.rounded (`, and then proceed on to
  3485. // the argument list, which has optional default values.
  3486. // We store the parameters in `params`, with a `value` key,
  3487. // if there is a value, such as in the case of `@radius`.
  3488. //
  3489. // Once we've got our params list, and a closing `)`, we parse
  3490. // the `{...}` block.
  3491. //
  3492. definition: function () {
  3493. var name, params = [], match, ruleset, cond, variadic = false;
  3494. if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||
  3495. parserInput.peek(/^[^{]*\}/)) {
  3496. return;
  3497. }
  3498. parserInput.save();
  3499. match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/);
  3500. if (match) {
  3501. name = match[1];
  3502. var argInfo = this.args(false);
  3503. params = argInfo.args;
  3504. variadic = argInfo.variadic;
  3505. // .mixincall("@{a}");
  3506. // looks a bit like a mixin definition..
  3507. // also
  3508. // .mixincall(@a: {rule: set;});
  3509. // so we have to be nice and restore
  3510. if (!parserInput.$char(')')) {
  3511. parserInput.restore("Missing closing ')'");
  3512. return;
  3513. }
  3514. parserInput.commentStore.length = 0;
  3515. if (parserInput.$str("when")) { // Guard
  3516. cond = expect(parsers.conditions, 'expected condition');
  3517. }
  3518. ruleset = parsers.block();
  3519. if (ruleset) {
  3520. parserInput.forget();
  3521. return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);
  3522. } else {
  3523. parserInput.restore();
  3524. }
  3525. } else {
  3526. parserInput.forget();
  3527. }
  3528. }
  3529. },
  3530. //
  3531. // Entities are the smallest recognized token,
  3532. // and can be found inside a rule's value.
  3533. //
  3534. entity: function () {
  3535. var entities = this.entities;
  3536. return this.comment() || entities.literal() || entities.variable() || entities.url() ||
  3537. entities.call() || entities.keyword() || entities.javascript();
  3538. },
  3539. //
  3540. // A Rule terminator. Note that we use `peek()` to check for '}',
  3541. // because the `block` rule will be expecting it, but we still need to make sure
  3542. // it's there, if ';' was omitted.
  3543. //
  3544. end: function () {
  3545. return parserInput.$char(';') || parserInput.peek('}');
  3546. },
  3547. //
  3548. // IE's alpha function
  3549. //
  3550. // alpha(opacity=88)
  3551. //
  3552. alpha: function () {
  3553. var value;
  3554. // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18
  3555. if (! parserInput.$re(/^opacity=/i)) { return; }
  3556. value = parserInput.$re(/^\d+/);
  3557. if (!value) {
  3558. value = expect(this.entities.variable, "Could not parse alpha");
  3559. }
  3560. expectChar(')');
  3561. return new(tree.Alpha)(value);
  3562. },
  3563. //
  3564. // A Selector Element
  3565. //
  3566. // div
  3567. // + h1
  3568. // #socks
  3569. // input[type="text"]
  3570. //
  3571. // Elements are the building blocks for Selectors,
  3572. // they are made out of a `Combinator` (see combinator rule),
  3573. // and an element name, such as a tag a class, or `*`.
  3574. //
  3575. element: function () {
  3576. var e, c, v, index = parserInput.i;
  3577. c = this.combinator();
  3578. e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) ||
  3579. parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||
  3580. parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||
  3581. parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) ||
  3582. this.entities.variableCurly();
  3583. if (! e) {
  3584. parserInput.save();
  3585. if (parserInput.$char('(')) {
  3586. if ((v = this.selector()) && parserInput.$char(')')) {
  3587. e = new(tree.Paren)(v);
  3588. parserInput.forget();
  3589. } else {
  3590. parserInput.restore("Missing closing ')'");
  3591. }
  3592. } else {
  3593. parserInput.forget();
  3594. }
  3595. }
  3596. if (e) { return new(tree.Element)(c, e, index, fileInfo); }
  3597. },
  3598. //
  3599. // Combinators combine elements together, in a Selector.
  3600. //
  3601. // Because our parser isn't white-space sensitive, special care
  3602. // has to be taken, when parsing the descendant combinator, ` `,
  3603. // as it's an empty space. We have to check the previous character
  3604. // in the input, to see if it's a ` ` character. More info on how
  3605. // we deal with this in *combinator.js*.
  3606. //
  3607. combinator: function () {
  3608. var c = parserInput.currentChar();
  3609. if (c === '/') {
  3610. parserInput.save();
  3611. var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i);
  3612. if (slashedCombinator) {
  3613. parserInput.forget();
  3614. return new(tree.Combinator)(slashedCombinator);
  3615. }
  3616. parserInput.restore();
  3617. }
  3618. if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {
  3619. parserInput.i++;
  3620. if (c === '^' && parserInput.currentChar() === '^') {
  3621. c = '^^';
  3622. parserInput.i++;
  3623. }
  3624. while (parserInput.isWhitespace()) { parserInput.i++; }
  3625. return new(tree.Combinator)(c);
  3626. } else if (parserInput.isWhitespace(-1)) {
  3627. return new(tree.Combinator)(" ");
  3628. } else {
  3629. return new(tree.Combinator)(null);
  3630. }
  3631. },
  3632. //
  3633. // A CSS selector (see selector below)
  3634. // with less extensions e.g. the ability to extend and guard
  3635. //
  3636. lessSelector: function () {
  3637. return this.selector(true);
  3638. },
  3639. //
  3640. // A CSS Selector
  3641. //
  3642. // .class > div + h1
  3643. // li a:hover
  3644. //
  3645. // Selectors are made out of one or more Elements, see above.
  3646. //
  3647. selector: function (isLess) {
  3648. var index = parserInput.i, elements, extendList, c, e, allExtends, when, condition;
  3649. while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str("when"))) || (e = this.element())) {
  3650. if (when) {
  3651. condition = expect(this.conditions, 'expected condition');
  3652. } else if (condition) {
  3653. error("CSS guard can only be used at the end of selector");
  3654. } else if (extendList) {
  3655. if (allExtends) {
  3656. allExtends = allExtends.concat(extendList);
  3657. } else {
  3658. allExtends = extendList;
  3659. }
  3660. } else {
  3661. if (allExtends) { error("Extend can only be used at the end of selector"); }
  3662. c = parserInput.currentChar();
  3663. if (elements) {
  3664. elements.push(e);
  3665. } else {
  3666. elements = [ e ];
  3667. }
  3668. e = null;
  3669. }
  3670. if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {
  3671. break;
  3672. }
  3673. }
  3674. if (elements) { return new(tree.Selector)(elements, allExtends, condition, index, fileInfo); }
  3675. if (allExtends) { error("Extend must be used to extend a selector, it cannot be used on its own"); }
  3676. },
  3677. attribute: function () {
  3678. if (! parserInput.$char('[')) { return; }
  3679. var entities = this.entities,
  3680. key, val, op;
  3681. if (!(key = entities.variableCurly())) {
  3682. key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/);
  3683. }
  3684. op = parserInput.$re(/^[|~*$^]?=/);
  3685. if (op) {
  3686. val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly();
  3687. }
  3688. expectChar(']');
  3689. return new(tree.Attribute)(key, op, val);
  3690. },
  3691. //
  3692. // The `block` rule is used by `ruleset` and `mixin.definition`.
  3693. // It's a wrapper around the `primary` rule, with added `{}`.
  3694. //
  3695. block: function () {
  3696. var content;
  3697. if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {
  3698. return content;
  3699. }
  3700. },
  3701. blockRuleset: function() {
  3702. var block = this.block();
  3703. if (block) {
  3704. block = new tree.Ruleset(null, block);
  3705. }
  3706. return block;
  3707. },
  3708. detachedRuleset: function() {
  3709. var blockRuleset = this.blockRuleset();
  3710. if (blockRuleset) {
  3711. return new tree.DetachedRuleset(blockRuleset);
  3712. }
  3713. },
  3714. //
  3715. // div, .class, body > p {...}
  3716. //
  3717. ruleset: function () {
  3718. var selectors, s, rules, debugInfo;
  3719. parserInput.save();
  3720. if (context.dumpLineNumbers) {
  3721. debugInfo = getDebugInfo(parserInput.i);
  3722. }
  3723. while (true) {
  3724. s = this.lessSelector();
  3725. if (!s) {
  3726. break;
  3727. }
  3728. if (selectors) {
  3729. selectors.push(s);
  3730. } else {
  3731. selectors = [ s ];
  3732. }
  3733. parserInput.commentStore.length = 0;
  3734. if (s.condition && selectors.length > 1) {
  3735. error("Guards are only currently allowed on a single selector.");
  3736. }
  3737. if (! parserInput.$char(',')) { break; }
  3738. if (s.condition) {
  3739. error("Guards are only currently allowed on a single selector.");
  3740. }
  3741. parserInput.commentStore.length = 0;
  3742. }
  3743. if (selectors && (rules = this.block())) {
  3744. parserInput.forget();
  3745. var ruleset = new(tree.Ruleset)(selectors, rules, context.strictImports);
  3746. if (context.dumpLineNumbers) {
  3747. ruleset.debugInfo = debugInfo;
  3748. }
  3749. return ruleset;
  3750. } else {
  3751. parserInput.restore();
  3752. }
  3753. },
  3754. rule: function (tryAnonymous) {
  3755. var name, value, startOfRule = parserInput.i, c = parserInput.currentChar(), important, merge, isVariable;
  3756. if (c === '.' || c === '#' || c === '&' || c === ':') { return; }
  3757. parserInput.save();
  3758. name = this.variable() || this.ruleProperty();
  3759. if (name) {
  3760. isVariable = typeof name === "string";
  3761. if (isVariable) {
  3762. value = this.detachedRuleset();
  3763. }
  3764. parserInput.commentStore.length = 0;
  3765. if (!value) {
  3766. // a name returned by this.ruleProperty() is always an array of the form:
  3767. // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"]
  3768. // where each item is a tree.Keyword or tree.Variable
  3769. merge = !isVariable && name.length > 1 && name.pop().value;
  3770. // prefer to try to parse first if its a variable or we are compressing
  3771. // but always fallback on the other one
  3772. var tryValueFirst = !tryAnonymous && (context.compress || isVariable);
  3773. if (tryValueFirst) {
  3774. value = this.value();
  3775. }
  3776. if (!value) {
  3777. value = this.anonymousValue();
  3778. if (value) {
  3779. parserInput.forget();
  3780. // anonymous values absorb the end ';' which is required for them to work
  3781. return new (tree.Rule)(name, value, false, merge, startOfRule, fileInfo);
  3782. }
  3783. }
  3784. if (!tryValueFirst && !value) {
  3785. value = this.value();
  3786. }
  3787. important = this.important();
  3788. }
  3789. if (value && this.end()) {
  3790. parserInput.forget();
  3791. return new (tree.Rule)(name, value, important, merge, startOfRule, fileInfo);
  3792. } else {
  3793. parserInput.restore();
  3794. if (value && !tryAnonymous) {
  3795. return this.rule(true);
  3796. }
  3797. }
  3798. } else {
  3799. parserInput.forget();
  3800. }
  3801. },
  3802. anonymousValue: function () {
  3803. var match = parserInput.$re(/^([^@+\/'"*`(;{}-]*);/);
  3804. if (match) {
  3805. return new(tree.Anonymous)(match[1]);
  3806. }
  3807. },
  3808. //
  3809. // An @import directive
  3810. //
  3811. // @import "lib";
  3812. //
  3813. // Depending on our environment, importing is done differently:
  3814. // In the browser, it's an XHR request, in Node, it would be a
  3815. // file-system operation. The function used for importing is
  3816. // stored in `import`, which we pass to the Import constructor.
  3817. //
  3818. "import": function () {
  3819. var path, features, index = parserInput.i;
  3820. var dir = parserInput.$re(/^@import?\s+/);
  3821. if (dir) {
  3822. var options = (dir ? this.importOptions() : null) || {};
  3823. if ((path = this.entities.quoted() || this.entities.url())) {
  3824. features = this.mediaFeatures();
  3825. if (!parserInput.$char(';')) {
  3826. parserInput.i = index;
  3827. error("missing semi-colon or unrecognised media features on import");
  3828. }
  3829. features = features && new(tree.Value)(features);
  3830. return new(tree.Import)(path, features, options, index, fileInfo);
  3831. }
  3832. else {
  3833. parserInput.i = index;
  3834. error("malformed import statement");
  3835. }
  3836. }
  3837. },
  3838. importOptions: function() {
  3839. var o, options = {}, optionName, value;
  3840. // list of options, surrounded by parens
  3841. if (! parserInput.$char('(')) { return null; }
  3842. do {
  3843. o = this.importOption();
  3844. if (o) {
  3845. optionName = o;
  3846. value = true;
  3847. switch(optionName) {
  3848. case "css":
  3849. optionName = "less";
  3850. value = false;
  3851. break;
  3852. case "once":
  3853. optionName = "multiple";
  3854. value = false;
  3855. break;
  3856. }
  3857. options[optionName] = value;
  3858. if (! parserInput.$char(',')) { break; }
  3859. }
  3860. } while (o);
  3861. expectChar(')');
  3862. return options;
  3863. },
  3864. importOption: function() {
  3865. var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);
  3866. if (opt) {
  3867. return opt[1];
  3868. }
  3869. },
  3870. mediaFeature: function () {
  3871. var entities = this.entities, nodes = [], e, p;
  3872. parserInput.save();
  3873. do {
  3874. e = entities.keyword() || entities.variable();
  3875. if (e) {
  3876. nodes.push(e);
  3877. } else if (parserInput.$char('(')) {
  3878. p = this.property();
  3879. e = this.value();
  3880. if (parserInput.$char(')')) {
  3881. if (p && e) {
  3882. nodes.push(new(tree.Paren)(new(tree.Rule)(p, e, null, null, parserInput.i, fileInfo, true)));
  3883. } else if (e) {
  3884. nodes.push(new(tree.Paren)(e));
  3885. } else {
  3886. error("badly formed media feature definition");
  3887. }
  3888. } else {
  3889. error("Missing closing ')'", "Parse");
  3890. }
  3891. }
  3892. } while (e);
  3893. parserInput.forget();
  3894. if (nodes.length > 0) {
  3895. return new(tree.Expression)(nodes);
  3896. }
  3897. },
  3898. mediaFeatures: function () {
  3899. var entities = this.entities, features = [], e;
  3900. do {
  3901. e = this.mediaFeature();
  3902. if (e) {
  3903. features.push(e);
  3904. if (! parserInput.$char(',')) { break; }
  3905. } else {
  3906. e = entities.variable();
  3907. if (e) {
  3908. features.push(e);
  3909. if (! parserInput.$char(',')) { break; }
  3910. }
  3911. }
  3912. } while (e);
  3913. return features.length > 0 ? features : null;
  3914. },
  3915. media: function () {
  3916. var features, rules, media, debugInfo, index = parserInput.i;
  3917. if (context.dumpLineNumbers) {
  3918. debugInfo = getDebugInfo(index);
  3919. }
  3920. parserInput.save();
  3921. if (parserInput.$str("@media")) {
  3922. features = this.mediaFeatures();
  3923. rules = this.block();
  3924. if (!rules) {
  3925. error("media definitions require block statements after any features");
  3926. }
  3927. parserInput.forget();
  3928. media = new(tree.Media)(rules, features, index, fileInfo);
  3929. if (context.dumpLineNumbers) {
  3930. media.debugInfo = debugInfo;
  3931. }
  3932. return media;
  3933. }
  3934. parserInput.restore();
  3935. },
  3936. //
  3937. // A @plugin directive, used to import compiler extensions dynamically.
  3938. //
  3939. // @plugin "lib";
  3940. //
  3941. // Depending on our environment, importing is done differently:
  3942. // In the browser, it's an XHR request, in Node, it would be a
  3943. // file-system operation. The function used for importing is
  3944. // stored in `import`, which we pass to the Import constructor.
  3945. //
  3946. plugin: function () {
  3947. var path,
  3948. index = parserInput.i,
  3949. dir = parserInput.$re(/^@plugin?\s+/);
  3950. if (dir) {
  3951. var options = { plugin : true };
  3952. if ((path = this.entities.quoted() || this.entities.url())) {
  3953. if (!parserInput.$char(';')) {
  3954. parserInput.i = index;
  3955. error("missing semi-colon on plugin");
  3956. }
  3957. return new(tree.Import)(path, null, options, index, fileInfo);
  3958. }
  3959. else {
  3960. parserInput.i = index;
  3961. error("malformed plugin statement");
  3962. }
  3963. }
  3964. },
  3965. //
  3966. // A CSS Directive
  3967. //
  3968. // @charset "utf-8";
  3969. //
  3970. directive: function () {
  3971. var index = parserInput.i, name, value, rules, nonVendorSpecificName,
  3972. hasIdentifier, hasExpression, hasUnknown, hasBlock = true, isRooted = true;
  3973. if (parserInput.currentChar() !== '@') { return; }
  3974. value = this['import']() || this.plugin() || this.media();
  3975. if (value) {
  3976. return value;
  3977. }
  3978. parserInput.save();
  3979. name = parserInput.$re(/^@[a-z-]+/);
  3980. if (!name) { return; }
  3981. nonVendorSpecificName = name;
  3982. if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {
  3983. nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1);
  3984. }
  3985. switch(nonVendorSpecificName) {
  3986. case "@charset":
  3987. hasIdentifier = true;
  3988. hasBlock = false;
  3989. break;
  3990. case "@namespace":
  3991. hasExpression = true;
  3992. hasBlock = false;
  3993. break;
  3994. case "@keyframes":
  3995. case "@counter-style":
  3996. hasIdentifier = true;
  3997. break;
  3998. case "@document":
  3999. case "@supports":
  4000. hasUnknown = true;
  4001. isRooted = false;
  4002. break;
  4003. default:
  4004. hasUnknown = true;
  4005. break;
  4006. }
  4007. parserInput.commentStore.length = 0;
  4008. if (hasIdentifier) {
  4009. value = this.entity();
  4010. if (!value) {
  4011. error("expected " + name + " identifier");
  4012. }
  4013. } else if (hasExpression) {
  4014. value = this.expression();
  4015. if (!value) {
  4016. error("expected " + name + " expression");
  4017. }
  4018. } else if (hasUnknown) {
  4019. value = (parserInput.$re(/^[^{;]+/) || '').trim();
  4020. hasBlock = (parserInput.currentChar() == '{');
  4021. if (value) {
  4022. value = new(tree.Anonymous)(value);
  4023. }
  4024. }
  4025. if (hasBlock) {
  4026. rules = this.blockRuleset();
  4027. }
  4028. if (rules || (!hasBlock && value && parserInput.$char(';'))) {
  4029. parserInput.forget();
  4030. return new (tree.Directive)(name, value, rules, index, fileInfo,
  4031. context.dumpLineNumbers ? getDebugInfo(index) : null,
  4032. isRooted
  4033. );
  4034. }
  4035. parserInput.restore("directive options not recognised");
  4036. },
  4037. //
  4038. // A Value is a comma-delimited list of Expressions
  4039. //
  4040. // font-family: Baskerville, Georgia, serif;
  4041. //
  4042. // In a Rule, a Value represents everything after the `:`,
  4043. // and before the `;`.
  4044. //
  4045. value: function () {
  4046. var e, expressions = [];
  4047. do {
  4048. e = this.expression();
  4049. if (e) {
  4050. expressions.push(e);
  4051. if (! parserInput.$char(',')) { break; }
  4052. }
  4053. } while (e);
  4054. if (expressions.length > 0) {
  4055. return new(tree.Value)(expressions);
  4056. }
  4057. },
  4058. important: function () {
  4059. if (parserInput.currentChar() === '!') {
  4060. return parserInput.$re(/^! *important/);
  4061. }
  4062. },
  4063. sub: function () {
  4064. var a, e;
  4065. parserInput.save();
  4066. if (parserInput.$char('(')) {
  4067. a = this.addition();
  4068. if (a && parserInput.$char(')')) {
  4069. parserInput.forget();
  4070. e = new(tree.Expression)([a]);
  4071. e.parens = true;
  4072. return e;
  4073. }
  4074. parserInput.restore("Expected ')'");
  4075. return;
  4076. }
  4077. parserInput.restore();
  4078. },
  4079. multiplication: function () {
  4080. var m, a, op, operation, isSpaced;
  4081. m = this.operand();
  4082. if (m) {
  4083. isSpaced = parserInput.isWhitespace(-1);
  4084. while (true) {
  4085. if (parserInput.peek(/^\/[*\/]/)) {
  4086. break;
  4087. }
  4088. parserInput.save();
  4089. op = parserInput.$char('/') || parserInput.$char('*');
  4090. if (!op) { parserInput.forget(); break; }
  4091. a = this.operand();
  4092. if (!a) { parserInput.restore(); break; }
  4093. parserInput.forget();
  4094. m.parensInOp = true;
  4095. a.parensInOp = true;
  4096. operation = new(tree.Operation)(op, [operation || m, a], isSpaced);
  4097. isSpaced = parserInput.isWhitespace(-1);
  4098. }
  4099. return operation || m;
  4100. }
  4101. },
  4102. addition: function () {
  4103. var m, a, op, operation, isSpaced;
  4104. m = this.multiplication();
  4105. if (m) {
  4106. isSpaced = parserInput.isWhitespace(-1);
  4107. while (true) {
  4108. op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));
  4109. if (!op) {
  4110. break;
  4111. }
  4112. a = this.multiplication();
  4113. if (!a) {
  4114. break;
  4115. }
  4116. m.parensInOp = true;
  4117. a.parensInOp = true;
  4118. operation = new(tree.Operation)(op, [operation || m, a], isSpaced);
  4119. isSpaced = parserInput.isWhitespace(-1);
  4120. }
  4121. return operation || m;
  4122. }
  4123. },
  4124. conditions: function () {
  4125. var a, b, index = parserInput.i, condition;
  4126. a = this.condition();
  4127. if (a) {
  4128. while (true) {
  4129. if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) {
  4130. break;
  4131. }
  4132. b = this.condition();
  4133. if (!b) {
  4134. break;
  4135. }
  4136. condition = new(tree.Condition)('or', condition || a, b, index);
  4137. }
  4138. return condition || a;
  4139. }
  4140. },
  4141. condition: function () {
  4142. var result, logical, next;
  4143. function or() {
  4144. return parserInput.$str("or");
  4145. }
  4146. result = this.conditionAnd(this);
  4147. if (!result) {
  4148. return ;
  4149. }
  4150. logical = or();
  4151. if (logical) {
  4152. next = this.condition();
  4153. if (next) {
  4154. result = new(tree.Condition)(logical, result, next);
  4155. } else {
  4156. return ;
  4157. }
  4158. }
  4159. return result;
  4160. },
  4161. conditionAnd: function () {
  4162. var result, logical, next;
  4163. function insideCondition(me) {
  4164. return me.negatedCondition() || me.parenthesisCondition();
  4165. }
  4166. function and() {
  4167. return parserInput.$str("and");
  4168. }
  4169. result = insideCondition(this);
  4170. if (!result) {
  4171. return ;
  4172. }
  4173. logical = and();
  4174. if (logical) {
  4175. next = this.conditionAnd();
  4176. if (next) {
  4177. result = new(tree.Condition)(logical, result, next);
  4178. } else {
  4179. return ;
  4180. }
  4181. }
  4182. return result;
  4183. },
  4184. negatedCondition: function () {
  4185. if (parserInput.$str("not")) {
  4186. var result = this.parenthesisCondition();
  4187. if (result) {
  4188. result.negate = !result.negate;
  4189. }
  4190. return result;
  4191. }
  4192. },
  4193. parenthesisCondition: function () {
  4194. function tryConditionFollowedByParenthesis(me) {
  4195. var body;
  4196. parserInput.save();
  4197. body = me.condition();
  4198. if (!body) {
  4199. parserInput.restore();
  4200. return ;
  4201. }
  4202. if (!parserInput.$char(')')) {
  4203. parserInput.restore();
  4204. return ;
  4205. }
  4206. parserInput.forget();
  4207. return body;
  4208. }
  4209. var body;
  4210. parserInput.save();
  4211. if (!parserInput.$str("(")) {
  4212. parserInput.restore();
  4213. return ;
  4214. }
  4215. body = tryConditionFollowedByParenthesis(this);
  4216. if (body) {
  4217. parserInput.forget();
  4218. return body;
  4219. }
  4220. body = this.atomicCondition();
  4221. if (!body) {
  4222. parserInput.restore();
  4223. return ;
  4224. }
  4225. if (!parserInput.$char(')')) {
  4226. parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'");
  4227. return ;
  4228. }
  4229. parserInput.forget();
  4230. return body;
  4231. },
  4232. atomicCondition: function () {
  4233. var entities = this.entities, index = parserInput.i, a, b, c, op;
  4234. a = this.addition() || entities.keyword() || entities.quoted();
  4235. if (a) {
  4236. if (parserInput.$char('>')) {
  4237. if (parserInput.$char('=')) {
  4238. op = ">=";
  4239. } else {
  4240. op = '>';
  4241. }
  4242. } else
  4243. if (parserInput.$char('<')) {
  4244. if (parserInput.$char('=')) {
  4245. op = "<=";
  4246. } else {
  4247. op = '<';
  4248. }
  4249. } else
  4250. if (parserInput.$char('=')) {
  4251. if (parserInput.$char('>')) {
  4252. op = "=>";
  4253. } else if (parserInput.$char('<')) {
  4254. op = '=<';
  4255. } else {
  4256. op = '=';
  4257. }
  4258. }
  4259. if (op) {
  4260. b = this.addition() || entities.keyword() || entities.quoted();
  4261. if (b) {
  4262. c = new(tree.Condition)(op, a, b, index, false);
  4263. } else {
  4264. error('expected expression');
  4265. }
  4266. } else {
  4267. c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, false);
  4268. }
  4269. return c;
  4270. }
  4271. },
  4272. //
  4273. // An operand is anything that can be part of an operation,
  4274. // such as a Color, or a Variable
  4275. //
  4276. operand: function () {
  4277. var entities = this.entities, negate;
  4278. if (parserInput.peek(/^-[@\(]/)) {
  4279. negate = parserInput.$char('-');
  4280. }
  4281. var o = this.sub() || entities.dimension() ||
  4282. entities.color() || entities.variable() ||
  4283. entities.call() || entities.colorKeyword();
  4284. if (negate) {
  4285. o.parensInOp = true;
  4286. o = new(tree.Negative)(o);
  4287. }
  4288. return o;
  4289. },
  4290. //
  4291. // Expressions either represent mathematical operations,
  4292. // or white-space delimited Entities.
  4293. //
  4294. // 1px solid black
  4295. // @var * 2
  4296. //
  4297. expression: function () {
  4298. var entities = [], e, delim;
  4299. do {
  4300. e = this.comment();
  4301. if (e) {
  4302. entities.push(e);
  4303. continue;
  4304. }
  4305. e = this.addition() || this.entity();
  4306. if (e) {
  4307. entities.push(e);
  4308. // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here
  4309. if (!parserInput.peek(/^\/[\/*]/)) {
  4310. delim = parserInput.$char('/');
  4311. if (delim) {
  4312. entities.push(new(tree.Anonymous)(delim));
  4313. }
  4314. }
  4315. }
  4316. } while (e);
  4317. if (entities.length > 0) {
  4318. return new(tree.Expression)(entities);
  4319. }
  4320. },
  4321. property: function () {
  4322. var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);
  4323. if (name) {
  4324. return name[1];
  4325. }
  4326. },
  4327. ruleProperty: function () {
  4328. var name = [], index = [], s, k;
  4329. parserInput.save();
  4330. var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/);
  4331. if (simpleProperty) {
  4332. name = [new(tree.Keyword)(simpleProperty[1])];
  4333. parserInput.forget();
  4334. return name;
  4335. }
  4336. function match(re) {
  4337. var i = parserInput.i,
  4338. chunk = parserInput.$re(re);
  4339. if (chunk) {
  4340. index.push(i);
  4341. return name.push(chunk[1]);
  4342. }
  4343. }
  4344. match(/^(\*?)/);
  4345. while (true) {
  4346. if (!match(/^((?:[\w-]+)|(?:@\{[\w-]+\}))/)) {
  4347. break;
  4348. }
  4349. }
  4350. if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) {
  4351. parserInput.forget();
  4352. // at last, we have the complete match now. move forward,
  4353. // convert name particles to tree objects and return:
  4354. if (name[0] === '') {
  4355. name.shift();
  4356. index.shift();
  4357. }
  4358. for (k = 0; k < name.length; k++) {
  4359. s = name[k];
  4360. name[k] = (s.charAt(0) !== '@') ?
  4361. new(tree.Keyword)(s) :
  4362. new(tree.Variable)('@' + s.slice(2, -1),
  4363. index[k], fileInfo);
  4364. }
  4365. return name;
  4366. }
  4367. parserInput.restore();
  4368. }
  4369. }
  4370. };
  4371. };
  4372. Parser.serializeVars = function(vars) {
  4373. var s = '';
  4374. for (var name in vars) {
  4375. if (Object.hasOwnProperty.call(vars, name)) {
  4376. var value = vars[name];
  4377. s += ((name[0] === '@') ? '' : '@') + name + ': ' + value +
  4378. ((String(value).slice(-1) === ';') ? '' : ';');
  4379. }
  4380. }
  4381. return s;
  4382. };
  4383. module.exports = Parser;
  4384. },{"../less-error":32,"../tree":62,"../utils":83,"../visitors":87,"./parser-input":37}],39:[function(require,module,exports){
  4385. /**
  4386. * Plugin Manager
  4387. */
  4388. var PluginManager = function(less) {
  4389. this.less = less;
  4390. this.visitors = [];
  4391. this.preProcessors = [];
  4392. this.postProcessors = [];
  4393. this.installedPlugins = [];
  4394. this.fileManagers = [];
  4395. };
  4396. /**
  4397. * Adds all the plugins in the array
  4398. * @param {Array} plugins
  4399. */
  4400. PluginManager.prototype.addPlugins = function(plugins) {
  4401. if (plugins) {
  4402. for (var i = 0; i < plugins.length; i++) {
  4403. this.addPlugin(plugins[i]);
  4404. }
  4405. }
  4406. };
  4407. /**
  4408. *
  4409. * @param plugin
  4410. */
  4411. PluginManager.prototype.addPlugin = function(plugin) {
  4412. this.installedPlugins.push(plugin);
  4413. plugin.install(this.less, this);
  4414. };
  4415. /**
  4416. * Adds a visitor. The visitor object has options on itself to determine
  4417. * when it should run.
  4418. * @param visitor
  4419. */
  4420. PluginManager.prototype.addVisitor = function(visitor) {
  4421. this.visitors.push(visitor);
  4422. };
  4423. /**
  4424. * Adds a pre processor object
  4425. * @param {object} preProcessor
  4426. * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import
  4427. */
  4428. PluginManager.prototype.addPreProcessor = function(preProcessor, priority) {
  4429. var indexToInsertAt;
  4430. for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {
  4431. if (this.preProcessors[indexToInsertAt].priority >= priority) {
  4432. break;
  4433. }
  4434. }
  4435. this.preProcessors.splice(indexToInsertAt, 0, {preProcessor: preProcessor, priority: priority});
  4436. };
  4437. /**
  4438. * Adds a post processor object
  4439. * @param {object} postProcessor
  4440. * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression
  4441. */
  4442. PluginManager.prototype.addPostProcessor = function(postProcessor, priority) {
  4443. var indexToInsertAt;
  4444. for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {
  4445. if (this.postProcessors[indexToInsertAt].priority >= priority) {
  4446. break;
  4447. }
  4448. }
  4449. this.postProcessors.splice(indexToInsertAt, 0, {postProcessor: postProcessor, priority: priority});
  4450. };
  4451. /**
  4452. *
  4453. * @param manager
  4454. */
  4455. PluginManager.prototype.addFileManager = function(manager) {
  4456. this.fileManagers.push(manager);
  4457. };
  4458. /**
  4459. *
  4460. * @returns {Array}
  4461. * @private
  4462. */
  4463. PluginManager.prototype.getPreProcessors = function() {
  4464. var preProcessors = [];
  4465. for (var i = 0; i < this.preProcessors.length; i++) {
  4466. preProcessors.push(this.preProcessors[i].preProcessor);
  4467. }
  4468. return preProcessors;
  4469. };
  4470. /**
  4471. *
  4472. * @returns {Array}
  4473. * @private
  4474. */
  4475. PluginManager.prototype.getPostProcessors = function() {
  4476. var postProcessors = [];
  4477. for (var i = 0; i < this.postProcessors.length; i++) {
  4478. postProcessors.push(this.postProcessors[i].postProcessor);
  4479. }
  4480. return postProcessors;
  4481. };
  4482. /**
  4483. *
  4484. * @returns {Array}
  4485. * @private
  4486. */
  4487. PluginManager.prototype.getVisitors = function() {
  4488. return this.visitors;
  4489. };
  4490. /**
  4491. *
  4492. * @returns {Array}
  4493. * @private
  4494. */
  4495. PluginManager.prototype.getFileManagers = function() {
  4496. return this.fileManagers;
  4497. };
  4498. module.exports = PluginManager;
  4499. },{}],40:[function(require,module,exports){
  4500. var LessError = require('../less-error'),
  4501. tree = require("../tree");
  4502. var FunctionImporter = module.exports = function FunctionImporter(context, fileInfo) {
  4503. this.fileInfo = fileInfo;
  4504. };
  4505. FunctionImporter.prototype.eval = function(contents, callback) {
  4506. var loaded = {},
  4507. loader,
  4508. registry;
  4509. registry = {
  4510. add: function(name, func) {
  4511. loaded[name] = func;
  4512. },
  4513. addMultiple: function(functions) {
  4514. Object.keys(functions).forEach(function(name) {
  4515. loaded[name] = functions[name];
  4516. });
  4517. }
  4518. };
  4519. try {
  4520. loader = new Function("functions", "tree", "fileInfo", contents);
  4521. loader(registry, tree, this.fileInfo);
  4522. } catch(e) {
  4523. callback(new LessError({
  4524. message: "Plugin evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" ,
  4525. filename: this.fileInfo.filename
  4526. }), null );
  4527. }
  4528. callback(null, { functions: loaded });
  4529. };
  4530. },{"../less-error":32,"../tree":62}],41:[function(require,module,exports){
  4531. var PromiseConstructor;
  4532. module.exports = function(environment, ParseTree, ImportManager) {
  4533. var render = function (input, options, callback) {
  4534. if (typeof options === 'function') {
  4535. callback = options;
  4536. options = {};
  4537. }
  4538. if (!callback) {
  4539. if (!PromiseConstructor) {
  4540. PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise;
  4541. }
  4542. var self = this;
  4543. return new PromiseConstructor(function (resolve, reject) {
  4544. render.call(self, input, options, function(err, output) {
  4545. if (err) {
  4546. reject(err);
  4547. } else {
  4548. resolve(output);
  4549. }
  4550. });
  4551. });
  4552. } else {
  4553. this.parse(input, options, function(err, root, imports, options) {
  4554. if (err) { return callback(err); }
  4555. var result;
  4556. try {
  4557. var parseTree = new ParseTree(root, imports);
  4558. result = parseTree.toCSS(options);
  4559. }
  4560. catch (err) { return callback(err); }
  4561. callback(null, result);
  4562. });
  4563. }
  4564. };
  4565. return render;
  4566. };
  4567. },{"promise":undefined}],42:[function(require,module,exports){
  4568. module.exports = function (SourceMapOutput, environment) {
  4569. var SourceMapBuilder = function (options) {
  4570. this.options = options;
  4571. };
  4572. SourceMapBuilder.prototype.toCSS = function(rootNode, options, imports) {
  4573. var sourceMapOutput = new SourceMapOutput(
  4574. {
  4575. contentsIgnoredCharsMap: imports.contentsIgnoredChars,
  4576. rootNode: rootNode,
  4577. contentsMap: imports.contents,
  4578. sourceMapFilename: this.options.sourceMapFilename,
  4579. sourceMapURL: this.options.sourceMapURL,
  4580. outputFilename: this.options.sourceMapOutputFilename,
  4581. sourceMapBasepath: this.options.sourceMapBasepath,
  4582. sourceMapRootpath: this.options.sourceMapRootpath,
  4583. outputSourceFiles: this.options.outputSourceFiles,
  4584. sourceMapGenerator: this.options.sourceMapGenerator,
  4585. sourceMapFileInline: this.options.sourceMapFileInline
  4586. });
  4587. var css = sourceMapOutput.toCSS(options);
  4588. this.sourceMap = sourceMapOutput.sourceMap;
  4589. this.sourceMapURL = sourceMapOutput.sourceMapURL;
  4590. if (this.options.sourceMapInputFilename) {
  4591. this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);
  4592. }
  4593. return css + this.getCSSAppendage();
  4594. };
  4595. SourceMapBuilder.prototype.getCSSAppendage = function() {
  4596. var sourceMapURL = this.sourceMapURL;
  4597. if (this.options.sourceMapFileInline) {
  4598. if (this.sourceMap === undefined) {
  4599. return "";
  4600. }
  4601. sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap);
  4602. }
  4603. if (sourceMapURL) {
  4604. return "/*# sourceMappingURL=" + sourceMapURL + " */";
  4605. }
  4606. return "";
  4607. };
  4608. SourceMapBuilder.prototype.getExternalSourceMap = function() {
  4609. return this.sourceMap;
  4610. };
  4611. SourceMapBuilder.prototype.setExternalSourceMap = function(sourceMap) {
  4612. this.sourceMap = sourceMap;
  4613. };
  4614. SourceMapBuilder.prototype.isInline = function() {
  4615. return this.options.sourceMapFileInline;
  4616. };
  4617. SourceMapBuilder.prototype.getSourceMapURL = function() {
  4618. return this.sourceMapURL;
  4619. };
  4620. SourceMapBuilder.prototype.getOutputFilename = function() {
  4621. return this.options.sourceMapOutputFilename;
  4622. };
  4623. SourceMapBuilder.prototype.getInputFilename = function() {
  4624. return this.sourceMapInputFilename;
  4625. };
  4626. return SourceMapBuilder;
  4627. };
  4628. },{}],43:[function(require,module,exports){
  4629. module.exports = function (environment) {
  4630. var SourceMapOutput = function (options) {
  4631. this._css = [];
  4632. this._rootNode = options.rootNode;
  4633. this._contentsMap = options.contentsMap;
  4634. this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;
  4635. if (options.sourceMapFilename) {
  4636. this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/');
  4637. }
  4638. this._outputFilename = options.outputFilename;
  4639. this.sourceMapURL = options.sourceMapURL;
  4640. if (options.sourceMapBasepath) {
  4641. this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/');
  4642. }
  4643. if (options.sourceMapRootpath) {
  4644. this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/');
  4645. if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {
  4646. this._sourceMapRootpath += '/';
  4647. }
  4648. } else {
  4649. this._sourceMapRootpath = "";
  4650. }
  4651. this._outputSourceFiles = options.outputSourceFiles;
  4652. this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();
  4653. this._lineNumber = 0;
  4654. this._column = 0;
  4655. };
  4656. SourceMapOutput.prototype.normalizeFilename = function(filename) {
  4657. filename = filename.replace(/\\/g, '/');
  4658. if (this._sourceMapBasepath && filename.indexOf(this._sourceMapBasepath) === 0) {
  4659. filename = filename.substring(this._sourceMapBasepath.length);
  4660. if (filename.charAt(0) === '\\' || filename.charAt(0) === '/') {
  4661. filename = filename.substring(1);
  4662. }
  4663. }
  4664. return (this._sourceMapRootpath || "") + filename;
  4665. };
  4666. SourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) {
  4667. //ignore adding empty strings
  4668. if (!chunk) {
  4669. return;
  4670. }
  4671. var lines,
  4672. sourceLines,
  4673. columns,
  4674. sourceColumns,
  4675. i;
  4676. if (fileInfo) {
  4677. var inputSource = this._contentsMap[fileInfo.filename];
  4678. // remove vars/banner added to the top of the file
  4679. if (this._contentsIgnoredCharsMap[fileInfo.filename]) {
  4680. // adjust the index
  4681. index -= this._contentsIgnoredCharsMap[fileInfo.filename];
  4682. if (index < 0) { index = 0; }
  4683. // adjust the source
  4684. inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);
  4685. }
  4686. inputSource = inputSource.substring(0, index);
  4687. sourceLines = inputSource.split("\n");
  4688. sourceColumns = sourceLines[sourceLines.length - 1];
  4689. }
  4690. lines = chunk.split("\n");
  4691. columns = lines[lines.length - 1];
  4692. if (fileInfo) {
  4693. if (!mapLines) {
  4694. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column},
  4695. original: { line: sourceLines.length, column: sourceColumns.length},
  4696. source: this.normalizeFilename(fileInfo.filename)});
  4697. } else {
  4698. for (i = 0; i < lines.length; i++) {
  4699. this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0},
  4700. original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0},
  4701. source: this.normalizeFilename(fileInfo.filename)});
  4702. }
  4703. }
  4704. }
  4705. if (lines.length === 1) {
  4706. this._column += columns.length;
  4707. } else {
  4708. this._lineNumber += lines.length - 1;
  4709. this._column = columns.length;
  4710. }
  4711. this._css.push(chunk);
  4712. };
  4713. SourceMapOutput.prototype.isEmpty = function() {
  4714. return this._css.length === 0;
  4715. };
  4716. SourceMapOutput.prototype.toCSS = function(context) {
  4717. this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });
  4718. if (this._outputSourceFiles) {
  4719. for (var filename in this._contentsMap) {
  4720. if (this._contentsMap.hasOwnProperty(filename)) {
  4721. var source = this._contentsMap[filename];
  4722. if (this._contentsIgnoredCharsMap[filename]) {
  4723. source = source.slice(this._contentsIgnoredCharsMap[filename]);
  4724. }
  4725. this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);
  4726. }
  4727. }
  4728. }
  4729. this._rootNode.genCSS(context, this);
  4730. if (this._css.length > 0) {
  4731. var sourceMapURL,
  4732. sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());
  4733. if (this.sourceMapURL) {
  4734. sourceMapURL = this.sourceMapURL;
  4735. } else if (this._sourceMapFilename) {
  4736. sourceMapURL = this._sourceMapFilename;
  4737. }
  4738. this.sourceMapURL = sourceMapURL;
  4739. this.sourceMap = sourceMapContent;
  4740. }
  4741. return this._css.join('');
  4742. };
  4743. return SourceMapOutput;
  4744. };
  4745. },{}],44:[function(require,module,exports){
  4746. var contexts = require("./contexts"),
  4747. visitor = require("./visitors"),
  4748. tree = require("./tree");
  4749. module.exports = function(root, options) {
  4750. options = options || {};
  4751. var evaldRoot,
  4752. variables = options.variables,
  4753. evalEnv = new contexts.Eval(options);
  4754. //
  4755. // Allows setting variables with a hash, so:
  4756. //
  4757. // `{ color: new tree.Color('#f01') }` will become:
  4758. //
  4759. // new tree.Rule('@color',
  4760. // new tree.Value([
  4761. // new tree.Expression([
  4762. // new tree.Color('#f01')
  4763. // ])
  4764. // ])
  4765. // )
  4766. //
  4767. if (typeof variables === 'object' && !Array.isArray(variables)) {
  4768. variables = Object.keys(variables).map(function (k) {
  4769. var value = variables[k];
  4770. if (! (value instanceof tree.Value)) {
  4771. if (! (value instanceof tree.Expression)) {
  4772. value = new tree.Expression([value]);
  4773. }
  4774. value = new tree.Value([value]);
  4775. }
  4776. return new tree.Rule('@' + k, value, false, null, 0);
  4777. });
  4778. evalEnv.frames = [new tree.Ruleset(null, variables)];
  4779. }
  4780. var preEvalVisitors = [],
  4781. visitors = [
  4782. new visitor.JoinSelectorVisitor(),
  4783. new visitor.MarkVisibleSelectorsVisitor(true),
  4784. new visitor.ExtendVisitor(),
  4785. new visitor.ToCSSVisitor({compress: Boolean(options.compress)})
  4786. ], i;
  4787. if (options.pluginManager) {
  4788. var pluginVisitors = options.pluginManager.getVisitors();
  4789. for (i = 0; i < pluginVisitors.length; i++) {
  4790. var pluginVisitor = pluginVisitors[i];
  4791. if (pluginVisitor.isPreEvalVisitor) {
  4792. preEvalVisitors.push(pluginVisitor);
  4793. } else {
  4794. if (pluginVisitor.isPreVisitor) {
  4795. visitors.splice(0, 0, pluginVisitor);
  4796. } else {
  4797. visitors.push(pluginVisitor);
  4798. }
  4799. }
  4800. }
  4801. }
  4802. for (i = 0; i < preEvalVisitors.length; i++) {
  4803. preEvalVisitors[i].run(root);
  4804. }
  4805. evaldRoot = root.eval(evalEnv);
  4806. for (i = 0; i < visitors.length; i++) {
  4807. visitors[i].run(evaldRoot);
  4808. }
  4809. return evaldRoot;
  4810. };
  4811. },{"./contexts":11,"./tree":62,"./visitors":87}],45:[function(require,module,exports){
  4812. var Node = require("./node");
  4813. var Alpha = function (val) {
  4814. this.value = val;
  4815. };
  4816. Alpha.prototype = new Node();
  4817. Alpha.prototype.type = "Alpha";
  4818. Alpha.prototype.accept = function (visitor) {
  4819. this.value = visitor.visit(this.value);
  4820. };
  4821. Alpha.prototype.eval = function (context) {
  4822. if (this.value.eval) { return new Alpha(this.value.eval(context)); }
  4823. return this;
  4824. };
  4825. Alpha.prototype.genCSS = function (context, output) {
  4826. output.add("alpha(opacity=");
  4827. if (this.value.genCSS) {
  4828. this.value.genCSS(context, output);
  4829. } else {
  4830. output.add(this.value);
  4831. }
  4832. output.add(")");
  4833. };
  4834. module.exports = Alpha;
  4835. },{"./node":70}],46:[function(require,module,exports){
  4836. var Node = require("./node");
  4837. var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
  4838. this.value = value;
  4839. this.index = index;
  4840. this.mapLines = mapLines;
  4841. this.currentFileInfo = currentFileInfo;
  4842. this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;
  4843. this.allowRoot = true;
  4844. this.copyVisibilityInfo(visibilityInfo);
  4845. };
  4846. Anonymous.prototype = new Node();
  4847. Anonymous.prototype.type = "Anonymous";
  4848. Anonymous.prototype.eval = function () {
  4849. return new Anonymous(this.value, this.index, this.currentFileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
  4850. };
  4851. Anonymous.prototype.compare = function (other) {
  4852. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  4853. };
  4854. Anonymous.prototype.isRulesetLike = function() {
  4855. return this.rulesetLike;
  4856. };
  4857. Anonymous.prototype.genCSS = function (context, output) {
  4858. output.add(this.value, this.currentFileInfo, this.index, this.mapLines);
  4859. };
  4860. module.exports = Anonymous;
  4861. },{"./node":70}],47:[function(require,module,exports){
  4862. var Node = require("./node");
  4863. var Assignment = function (key, val) {
  4864. this.key = key;
  4865. this.value = val;
  4866. };
  4867. Assignment.prototype = new Node();
  4868. Assignment.prototype.type = "Assignment";
  4869. Assignment.prototype.accept = function (visitor) {
  4870. this.value = visitor.visit(this.value);
  4871. };
  4872. Assignment.prototype.eval = function (context) {
  4873. if (this.value.eval) {
  4874. return new Assignment(this.key, this.value.eval(context));
  4875. }
  4876. return this;
  4877. };
  4878. Assignment.prototype.genCSS = function (context, output) {
  4879. output.add(this.key + '=');
  4880. if (this.value.genCSS) {
  4881. this.value.genCSS(context, output);
  4882. } else {
  4883. output.add(this.value);
  4884. }
  4885. };
  4886. module.exports = Assignment;
  4887. },{"./node":70}],48:[function(require,module,exports){
  4888. var Node = require("./node");
  4889. var Attribute = function (key, op, value) {
  4890. this.key = key;
  4891. this.op = op;
  4892. this.value = value;
  4893. };
  4894. Attribute.prototype = new Node();
  4895. Attribute.prototype.type = "Attribute";
  4896. Attribute.prototype.eval = function (context) {
  4897. return new Attribute(this.key.eval ? this.key.eval(context) : this.key,
  4898. this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);
  4899. };
  4900. Attribute.prototype.genCSS = function (context, output) {
  4901. output.add(this.toCSS(context));
  4902. };
  4903. Attribute.prototype.toCSS = function (context) {
  4904. var value = this.key.toCSS ? this.key.toCSS(context) : this.key;
  4905. if (this.op) {
  4906. value += this.op;
  4907. value += (this.value.toCSS ? this.value.toCSS(context) : this.value);
  4908. }
  4909. return '[' + value + ']';
  4910. };
  4911. module.exports = Attribute;
  4912. },{"./node":70}],49:[function(require,module,exports){
  4913. var Node = require("./node"),
  4914. FunctionCaller = require("../functions/function-caller");
  4915. //
  4916. // A function call node.
  4917. //
  4918. var Call = function (name, args, index, currentFileInfo) {
  4919. this.name = name;
  4920. this.args = args;
  4921. this.index = index;
  4922. this.currentFileInfo = currentFileInfo;
  4923. };
  4924. Call.prototype = new Node();
  4925. Call.prototype.type = "Call";
  4926. Call.prototype.accept = function (visitor) {
  4927. if (this.args) {
  4928. this.args = visitor.visitArray(this.args);
  4929. }
  4930. };
  4931. //
  4932. // When evaluating a function call,
  4933. // we either find the function in the functionRegistry,
  4934. // in which case we call it, passing the evaluated arguments,
  4935. // if this returns null or we cannot find the function, we
  4936. // simply print it out as it appeared originally [2].
  4937. //
  4938. // The reason why we evaluate the arguments, is in the case where
  4939. // we try to pass a variable to a function, like: `saturate(@color)`.
  4940. // The function should receive the value, not the variable.
  4941. //
  4942. Call.prototype.eval = function (context) {
  4943. var args = this.args.map(function (a) { return a.eval(context); }),
  4944. result, funcCaller = new FunctionCaller(this.name, context, this.index, this.currentFileInfo);
  4945. if (funcCaller.isValid()) {
  4946. try {
  4947. result = funcCaller.call(args);
  4948. } catch (e) {
  4949. throw { type: e.type || "Runtime",
  4950. message: "error evaluating function `" + this.name + "`" +
  4951. (e.message ? ': ' + e.message : ''),
  4952. index: this.index, filename: this.currentFileInfo.filename };
  4953. }
  4954. if (result != null) {
  4955. result.index = this.index;
  4956. result.currentFileInfo = this.currentFileInfo;
  4957. return result;
  4958. }
  4959. }
  4960. return new Call(this.name, args, this.index, this.currentFileInfo);
  4961. };
  4962. Call.prototype.genCSS = function (context, output) {
  4963. output.add(this.name + "(", this.currentFileInfo, this.index);
  4964. for (var i = 0; i < this.args.length; i++) {
  4965. this.args[i].genCSS(context, output);
  4966. if (i + 1 < this.args.length) {
  4967. output.add(", ");
  4968. }
  4969. }
  4970. output.add(")");
  4971. };
  4972. module.exports = Call;
  4973. },{"../functions/function-caller":21,"./node":70}],50:[function(require,module,exports){
  4974. var Node = require("./node"),
  4975. colors = require("../data/colors");
  4976. //
  4977. // RGB Colors - #ff0014, #eee
  4978. //
  4979. var Color = function (rgb, a, originalForm) {
  4980. //
  4981. // The end goal here, is to parse the arguments
  4982. // into an integer triplet, such as `128, 255, 0`
  4983. //
  4984. // This facilitates operations and conversions.
  4985. //
  4986. if (Array.isArray(rgb)) {
  4987. this.rgb = rgb;
  4988. } else if (rgb.length == 6) {
  4989. this.rgb = rgb.match(/.{2}/g).map(function (c) {
  4990. return parseInt(c, 16);
  4991. });
  4992. } else {
  4993. this.rgb = rgb.split('').map(function (c) {
  4994. return parseInt(c + c, 16);
  4995. });
  4996. }
  4997. this.alpha = typeof a === 'number' ? a : 1;
  4998. if (typeof originalForm !== 'undefined') {
  4999. this.value = originalForm;
  5000. }
  5001. };
  5002. Color.prototype = new Node();
  5003. Color.prototype.type = "Color";
  5004. function clamp(v, max) {
  5005. return Math.min(Math.max(v, 0), max);
  5006. }
  5007. function toHex(v) {
  5008. return '#' + v.map(function (c) {
  5009. c = clamp(Math.round(c), 255);
  5010. return (c < 16 ? '0' : '') + c.toString(16);
  5011. }).join('');
  5012. }
  5013. Color.prototype.luma = function () {
  5014. var r = this.rgb[0] / 255,
  5015. g = this.rgb[1] / 255,
  5016. b = this.rgb[2] / 255;
  5017. r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);
  5018. g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);
  5019. b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);
  5020. return 0.2126 * r + 0.7152 * g + 0.0722 * b;
  5021. };
  5022. Color.prototype.genCSS = function (context, output) {
  5023. output.add(this.toCSS(context));
  5024. };
  5025. Color.prototype.toCSS = function (context, doNotCompress) {
  5026. var compress = context && context.compress && !doNotCompress, color, alpha;
  5027. // `value` is set if this color was originally
  5028. // converted from a named color string so we need
  5029. // to respect this and try to output named color too.
  5030. if (this.value) {
  5031. return this.value;
  5032. }
  5033. // If we have some transparency, the only way to represent it
  5034. // is via `rgba`. Otherwise, we use the hex representation,
  5035. // which has better compatibility with older browsers.
  5036. // Values are capped between `0` and `255`, rounded and zero-padded.
  5037. alpha = this.fround(context, this.alpha);
  5038. if (alpha < 1) {
  5039. return "rgba(" + this.rgb.map(function (c) {
  5040. return clamp(Math.round(c), 255);
  5041. }).concat(clamp(alpha, 1))
  5042. .join(',' + (compress ? '' : ' ')) + ")";
  5043. }
  5044. color = this.toRGB();
  5045. if (compress) {
  5046. var splitcolor = color.split('');
  5047. // Convert color to short format
  5048. if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {
  5049. color = '#' + splitcolor[1] + splitcolor[3] + splitcolor[5];
  5050. }
  5051. }
  5052. return color;
  5053. };
  5054. //
  5055. // Operations have to be done per-channel, if not,
  5056. // channels will spill onto each other. Once we have
  5057. // our result, in the form of an integer triplet,
  5058. // we create a new Color node to hold the result.
  5059. //
  5060. Color.prototype.operate = function (context, op, other) {
  5061. var rgb = [];
  5062. var alpha = this.alpha * (1 - other.alpha) + other.alpha;
  5063. for (var c = 0; c < 3; c++) {
  5064. rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);
  5065. }
  5066. return new Color(rgb, alpha);
  5067. };
  5068. Color.prototype.toRGB = function () {
  5069. return toHex(this.rgb);
  5070. };
  5071. Color.prototype.toHSL = function () {
  5072. var r = this.rgb[0] / 255,
  5073. g = this.rgb[1] / 255,
  5074. b = this.rgb[2] / 255,
  5075. a = this.alpha;
  5076. var max = Math.max(r, g, b), min = Math.min(r, g, b);
  5077. var h, s, l = (max + min) / 2, d = max - min;
  5078. if (max === min) {
  5079. h = s = 0;
  5080. } else {
  5081. s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
  5082. switch (max) {
  5083. case r: h = (g - b) / d + (g < b ? 6 : 0); break;
  5084. case g: h = (b - r) / d + 2; break;
  5085. case b: h = (r - g) / d + 4; break;
  5086. }
  5087. h /= 6;
  5088. }
  5089. return { h: h * 360, s: s, l: l, a: a };
  5090. };
  5091. //Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
  5092. Color.prototype.toHSV = function () {
  5093. var r = this.rgb[0] / 255,
  5094. g = this.rgb[1] / 255,
  5095. b = this.rgb[2] / 255,
  5096. a = this.alpha;
  5097. var max = Math.max(r, g, b), min = Math.min(r, g, b);
  5098. var h, s, v = max;
  5099. var d = max - min;
  5100. if (max === 0) {
  5101. s = 0;
  5102. } else {
  5103. s = d / max;
  5104. }
  5105. if (max === min) {
  5106. h = 0;
  5107. } else {
  5108. switch(max) {
  5109. case r: h = (g - b) / d + (g < b ? 6 : 0); break;
  5110. case g: h = (b - r) / d + 2; break;
  5111. case b: h = (r - g) / d + 4; break;
  5112. }
  5113. h /= 6;
  5114. }
  5115. return { h: h * 360, s: s, v: v, a: a };
  5116. };
  5117. Color.prototype.toARGB = function () {
  5118. return toHex([this.alpha * 255].concat(this.rgb));
  5119. };
  5120. Color.prototype.compare = function (x) {
  5121. return (x.rgb &&
  5122. x.rgb[0] === this.rgb[0] &&
  5123. x.rgb[1] === this.rgb[1] &&
  5124. x.rgb[2] === this.rgb[2] &&
  5125. x.alpha === this.alpha) ? 0 : undefined;
  5126. };
  5127. Color.fromKeyword = function(keyword) {
  5128. var c, key = keyword.toLowerCase();
  5129. if (colors.hasOwnProperty(key)) {
  5130. c = new Color(colors[key].slice(1));
  5131. }
  5132. else if (key === "transparent") {
  5133. c = new Color([0, 0, 0], 0);
  5134. }
  5135. if (c) {
  5136. c.value = keyword;
  5137. return c;
  5138. }
  5139. };
  5140. module.exports = Color;
  5141. },{"../data/colors":12,"./node":70}],51:[function(require,module,exports){
  5142. var Node = require("./node");
  5143. var Combinator = function (value) {
  5144. if (value === ' ') {
  5145. this.value = ' ';
  5146. this.emptyOrWhitespace = true;
  5147. } else {
  5148. this.value = value ? value.trim() : "";
  5149. this.emptyOrWhitespace = this.value === "";
  5150. }
  5151. };
  5152. Combinator.prototype = new Node();
  5153. Combinator.prototype.type = "Combinator";
  5154. var _noSpaceCombinators = {
  5155. '': true,
  5156. ' ': true,
  5157. '|': true
  5158. };
  5159. Combinator.prototype.genCSS = function (context, output) {
  5160. var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';
  5161. output.add(spaceOrEmpty + this.value + spaceOrEmpty);
  5162. };
  5163. module.exports = Combinator;
  5164. },{"./node":70}],52:[function(require,module,exports){
  5165. var Node = require("./node"),
  5166. getDebugInfo = require("./debug-info");
  5167. var Comment = function (value, isLineComment, index, currentFileInfo) {
  5168. this.value = value;
  5169. this.isLineComment = isLineComment;
  5170. this.index = index;
  5171. this.currentFileInfo = currentFileInfo;
  5172. this.allowRoot = true;
  5173. };
  5174. Comment.prototype = new Node();
  5175. Comment.prototype.type = "Comment";
  5176. Comment.prototype.genCSS = function (context, output) {
  5177. if (this.debugInfo) {
  5178. output.add(getDebugInfo(context, this), this.currentFileInfo, this.index);
  5179. }
  5180. output.add(this.value);
  5181. };
  5182. Comment.prototype.isSilent = function(context) {
  5183. var isCompressed = context.compress && this.value[2] !== "!";
  5184. return this.isLineComment || isCompressed;
  5185. };
  5186. module.exports = Comment;
  5187. },{"./debug-info":54,"./node":70}],53:[function(require,module,exports){
  5188. var Node = require("./node");
  5189. var Condition = function (op, l, r, i, negate) {
  5190. this.op = op.trim();
  5191. this.lvalue = l;
  5192. this.rvalue = r;
  5193. this.index = i;
  5194. this.negate = negate;
  5195. };
  5196. Condition.prototype = new Node();
  5197. Condition.prototype.type = "Condition";
  5198. Condition.prototype.accept = function (visitor) {
  5199. this.lvalue = visitor.visit(this.lvalue);
  5200. this.rvalue = visitor.visit(this.rvalue);
  5201. };
  5202. Condition.prototype.eval = function (context) {
  5203. var result = (function (op, a, b) {
  5204. switch (op) {
  5205. case 'and': return a && b;
  5206. case 'or': return a || b;
  5207. default:
  5208. switch (Node.compare(a, b)) {
  5209. case -1:
  5210. return op === '<' || op === '=<' || op === '<=';
  5211. case 0:
  5212. return op === '=' || op === '>=' || op === '=<' || op === '<=';
  5213. case 1:
  5214. return op === '>' || op === '>=';
  5215. default:
  5216. return false;
  5217. }
  5218. }
  5219. })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));
  5220. return this.negate ? !result : result;
  5221. };
  5222. module.exports = Condition;
  5223. },{"./node":70}],54:[function(require,module,exports){
  5224. var debugInfo = function(context, ctx, lineSeparator) {
  5225. var result = "";
  5226. if (context.dumpLineNumbers && !context.compress) {
  5227. switch(context.dumpLineNumbers) {
  5228. case 'comments':
  5229. result = debugInfo.asComment(ctx);
  5230. break;
  5231. case 'mediaquery':
  5232. result = debugInfo.asMediaQuery(ctx);
  5233. break;
  5234. case 'all':
  5235. result = debugInfo.asComment(ctx) + (lineSeparator || "") + debugInfo.asMediaQuery(ctx);
  5236. break;
  5237. }
  5238. }
  5239. return result;
  5240. };
  5241. debugInfo.asComment = function(ctx) {
  5242. return '/* line ' + ctx.debugInfo.lineNumber + ', ' + ctx.debugInfo.fileName + ' */\n';
  5243. };
  5244. debugInfo.asMediaQuery = function(ctx) {
  5245. var filenameWithProtocol = ctx.debugInfo.fileName;
  5246. if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) {
  5247. filenameWithProtocol = 'file://' + filenameWithProtocol;
  5248. }
  5249. return '@media -sass-debug-info{filename{font-family:' +
  5250. filenameWithProtocol.replace(/([.:\/\\])/g, function (a) {
  5251. if (a == '\\') {
  5252. a = '\/';
  5253. }
  5254. return '\\' + a;
  5255. }) +
  5256. '}line{font-family:\\00003' + ctx.debugInfo.lineNumber + '}}\n';
  5257. };
  5258. module.exports = debugInfo;
  5259. },{}],55:[function(require,module,exports){
  5260. var Node = require("./node"),
  5261. contexts = require("../contexts");
  5262. var DetachedRuleset = function (ruleset, frames) {
  5263. this.ruleset = ruleset;
  5264. this.frames = frames;
  5265. };
  5266. DetachedRuleset.prototype = new Node();
  5267. DetachedRuleset.prototype.type = "DetachedRuleset";
  5268. DetachedRuleset.prototype.evalFirst = true;
  5269. DetachedRuleset.prototype.accept = function (visitor) {
  5270. this.ruleset = visitor.visit(this.ruleset);
  5271. };
  5272. DetachedRuleset.prototype.eval = function (context) {
  5273. var frames = this.frames || context.frames.slice(0);
  5274. return new DetachedRuleset(this.ruleset, frames);
  5275. };
  5276. DetachedRuleset.prototype.callEval = function (context) {
  5277. return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);
  5278. };
  5279. module.exports = DetachedRuleset;
  5280. },{"../contexts":11,"./node":70}],56:[function(require,module,exports){
  5281. var Node = require("./node"),
  5282. unitConversions = require("../data/unit-conversions"),
  5283. Unit = require("./unit"),
  5284. Color = require("./color");
  5285. //
  5286. // A number with a unit
  5287. //
  5288. var Dimension = function (value, unit) {
  5289. this.value = parseFloat(value);
  5290. this.unit = (unit && unit instanceof Unit) ? unit :
  5291. new Unit(unit ? [unit] : undefined);
  5292. };
  5293. Dimension.prototype = new Node();
  5294. Dimension.prototype.type = "Dimension";
  5295. Dimension.prototype.accept = function (visitor) {
  5296. this.unit = visitor.visit(this.unit);
  5297. };
  5298. Dimension.prototype.eval = function (context) {
  5299. return this;
  5300. };
  5301. Dimension.prototype.toColor = function () {
  5302. return new Color([this.value, this.value, this.value]);
  5303. };
  5304. Dimension.prototype.genCSS = function (context, output) {
  5305. if ((context && context.strictUnits) && !this.unit.isSingular()) {
  5306. throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString());
  5307. }
  5308. var value = this.fround(context, this.value),
  5309. strValue = String(value);
  5310. if (value !== 0 && value < 0.000001 && value > -0.000001) {
  5311. // would be output 1e-6 etc.
  5312. strValue = value.toFixed(20).replace(/0+$/, "");
  5313. }
  5314. if (context && context.compress) {
  5315. // Zero values doesn't need a unit
  5316. if (value === 0 && this.unit.isLength()) {
  5317. output.add(strValue);
  5318. return;
  5319. }
  5320. // Float values doesn't need a leading zero
  5321. if (value > 0 && value < 1) {
  5322. strValue = (strValue).substr(1);
  5323. }
  5324. }
  5325. output.add(strValue);
  5326. this.unit.genCSS(context, output);
  5327. };
  5328. // In an operation between two Dimensions,
  5329. // we default to the first Dimension's unit,
  5330. // so `1px + 2` will yield `3px`.
  5331. Dimension.prototype.operate = function (context, op, other) {
  5332. /*jshint noempty:false */
  5333. var value = this._operate(context, op, this.value, other.value),
  5334. unit = this.unit.clone();
  5335. if (op === '+' || op === '-') {
  5336. if (unit.numerator.length === 0 && unit.denominator.length === 0) {
  5337. unit = other.unit.clone();
  5338. if (this.unit.backupUnit) {
  5339. unit.backupUnit = this.unit.backupUnit;
  5340. }
  5341. } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {
  5342. // do nothing
  5343. } else {
  5344. other = other.convertTo(this.unit.usedUnits());
  5345. if (context.strictUnits && other.unit.toString() !== unit.toString()) {
  5346. throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() +
  5347. "' and '" + other.unit.toString() + "'.");
  5348. }
  5349. value = this._operate(context, op, this.value, other.value);
  5350. }
  5351. } else if (op === '*') {
  5352. unit.numerator = unit.numerator.concat(other.unit.numerator).sort();
  5353. unit.denominator = unit.denominator.concat(other.unit.denominator).sort();
  5354. unit.cancel();
  5355. } else if (op === '/') {
  5356. unit.numerator = unit.numerator.concat(other.unit.denominator).sort();
  5357. unit.denominator = unit.denominator.concat(other.unit.numerator).sort();
  5358. unit.cancel();
  5359. }
  5360. return new Dimension(value, unit);
  5361. };
  5362. Dimension.prototype.compare = function (other) {
  5363. var a, b;
  5364. if (!(other instanceof Dimension)) {
  5365. return undefined;
  5366. }
  5367. if (this.unit.isEmpty() || other.unit.isEmpty()) {
  5368. a = this;
  5369. b = other;
  5370. } else {
  5371. a = this.unify();
  5372. b = other.unify();
  5373. if (a.unit.compare(b.unit) !== 0) {
  5374. return undefined;
  5375. }
  5376. }
  5377. return Node.numericCompare(a.value, b.value);
  5378. };
  5379. Dimension.prototype.unify = function () {
  5380. return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });
  5381. };
  5382. Dimension.prototype.convertTo = function (conversions) {
  5383. var value = this.value, unit = this.unit.clone(),
  5384. i, groupName, group, targetUnit, derivedConversions = {}, applyUnit;
  5385. if (typeof conversions === 'string') {
  5386. for (i in unitConversions) {
  5387. if (unitConversions[i].hasOwnProperty(conversions)) {
  5388. derivedConversions = {};
  5389. derivedConversions[i] = conversions;
  5390. }
  5391. }
  5392. conversions = derivedConversions;
  5393. }
  5394. applyUnit = function (atomicUnit, denominator) {
  5395. /* jshint loopfunc:true */
  5396. if (group.hasOwnProperty(atomicUnit)) {
  5397. if (denominator) {
  5398. value = value / (group[atomicUnit] / group[targetUnit]);
  5399. } else {
  5400. value = value * (group[atomicUnit] / group[targetUnit]);
  5401. }
  5402. return targetUnit;
  5403. }
  5404. return atomicUnit;
  5405. };
  5406. for (groupName in conversions) {
  5407. if (conversions.hasOwnProperty(groupName)) {
  5408. targetUnit = conversions[groupName];
  5409. group = unitConversions[groupName];
  5410. unit.map(applyUnit);
  5411. }
  5412. }
  5413. unit.cancel();
  5414. return new Dimension(value, unit);
  5415. };
  5416. module.exports = Dimension;
  5417. },{"../data/unit-conversions":14,"./color":50,"./node":70,"./unit":79}],57:[function(require,module,exports){
  5418. var Node = require("./node"),
  5419. Selector = require("./selector"),
  5420. Ruleset = require("./ruleset");
  5421. var Directive = function (name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {
  5422. var i;
  5423. this.name = name;
  5424. this.value = value;
  5425. if (rules) {
  5426. if (Array.isArray(rules)) {
  5427. this.rules = rules;
  5428. } else {
  5429. this.rules = [rules];
  5430. this.rules[0].selectors = (new Selector([], null, null, this.index, currentFileInfo)).createEmptySelectors();
  5431. }
  5432. for (i = 0; i < this.rules.length; i++) {
  5433. this.rules[i].allowImports = true;
  5434. }
  5435. }
  5436. this.index = index;
  5437. this.currentFileInfo = currentFileInfo;
  5438. this.debugInfo = debugInfo;
  5439. this.isRooted = isRooted || false;
  5440. this.copyVisibilityInfo(visibilityInfo);
  5441. this.allowRoot = true;
  5442. };
  5443. Directive.prototype = new Node();
  5444. Directive.prototype.type = "Directive";
  5445. Directive.prototype.accept = function (visitor) {
  5446. var value = this.value, rules = this.rules;
  5447. if (rules) {
  5448. this.rules = visitor.visitArray(rules);
  5449. }
  5450. if (value) {
  5451. this.value = visitor.visit(value);
  5452. }
  5453. };
  5454. Directive.prototype.isRulesetLike = function() {
  5455. return this.rules || !this.isCharset();
  5456. };
  5457. Directive.prototype.isCharset = function() {
  5458. return "@charset" === this.name;
  5459. };
  5460. Directive.prototype.genCSS = function (context, output) {
  5461. var value = this.value, rules = this.rules;
  5462. output.add(this.name, this.currentFileInfo, this.index);
  5463. if (value) {
  5464. output.add(' ');
  5465. value.genCSS(context, output);
  5466. }
  5467. if (rules) {
  5468. this.outputRuleset(context, output, rules);
  5469. } else {
  5470. output.add(';');
  5471. }
  5472. };
  5473. Directive.prototype.eval = function (context) {
  5474. var mediaPathBackup, mediaBlocksBackup, value = this.value, rules = this.rules;
  5475. //media stored inside other directive should not bubble over it
  5476. //backpup media bubbling information
  5477. mediaPathBackup = context.mediaPath;
  5478. mediaBlocksBackup = context.mediaBlocks;
  5479. //deleted media bubbling information
  5480. context.mediaPath = [];
  5481. context.mediaBlocks = [];
  5482. if (value) {
  5483. value = value.eval(context);
  5484. }
  5485. if (rules) {
  5486. // assuming that there is only one rule at this point - that is how parser constructs the rule
  5487. rules = [rules[0].eval(context)];
  5488. rules[0].root = true;
  5489. }
  5490. //restore media bubbling information
  5491. context.mediaPath = mediaPathBackup;
  5492. context.mediaBlocks = mediaBlocksBackup;
  5493. return new Directive(this.name, value, rules,
  5494. this.index, this.currentFileInfo, this.debugInfo, this.isRooted, this.visibilityInfo());
  5495. };
  5496. Directive.prototype.variable = function (name) {
  5497. if (this.rules) {
  5498. // assuming that there is only one rule at this point - that is how parser constructs the rule
  5499. return Ruleset.prototype.variable.call(this.rules[0], name);
  5500. }
  5501. };
  5502. Directive.prototype.find = function () {
  5503. if (this.rules) {
  5504. // assuming that there is only one rule at this point - that is how parser constructs the rule
  5505. return Ruleset.prototype.find.apply(this.rules[0], arguments);
  5506. }
  5507. };
  5508. Directive.prototype.rulesets = function () {
  5509. if (this.rules) {
  5510. // assuming that there is only one rule at this point - that is how parser constructs the rule
  5511. return Ruleset.prototype.rulesets.apply(this.rules[0]);
  5512. }
  5513. };
  5514. Directive.prototype.outputRuleset = function (context, output, rules) {
  5515. var ruleCnt = rules.length, i;
  5516. context.tabLevel = (context.tabLevel | 0) + 1;
  5517. // Compressed
  5518. if (context.compress) {
  5519. output.add('{');
  5520. for (i = 0; i < ruleCnt; i++) {
  5521. rules[i].genCSS(context, output);
  5522. }
  5523. output.add('}');
  5524. context.tabLevel--;
  5525. return;
  5526. }
  5527. // Non-compressed
  5528. var tabSetStr = '\n' + Array(context.tabLevel).join(" "), tabRuleStr = tabSetStr + " ";
  5529. if (!ruleCnt) {
  5530. output.add(" {" + tabSetStr + '}');
  5531. } else {
  5532. output.add(" {" + tabRuleStr);
  5533. rules[0].genCSS(context, output);
  5534. for (i = 1; i < ruleCnt; i++) {
  5535. output.add(tabRuleStr);
  5536. rules[i].genCSS(context, output);
  5537. }
  5538. output.add(tabSetStr + '}');
  5539. }
  5540. context.tabLevel--;
  5541. };
  5542. module.exports = Directive;
  5543. },{"./node":70,"./ruleset":76,"./selector":77}],58:[function(require,module,exports){
  5544. var Node = require("./node"),
  5545. Paren = require("./paren"),
  5546. Combinator = require("./combinator");
  5547. var Element = function (combinator, value, index, currentFileInfo, info) {
  5548. this.combinator = combinator instanceof Combinator ?
  5549. combinator : new Combinator(combinator);
  5550. if (typeof value === 'string') {
  5551. this.value = value.trim();
  5552. } else if (value) {
  5553. this.value = value;
  5554. } else {
  5555. this.value = "";
  5556. }
  5557. this.index = index;
  5558. this.currentFileInfo = currentFileInfo;
  5559. this.copyVisibilityInfo(info);
  5560. };
  5561. Element.prototype = new Node();
  5562. Element.prototype.type = "Element";
  5563. Element.prototype.accept = function (visitor) {
  5564. var value = this.value;
  5565. this.combinator = visitor.visit(this.combinator);
  5566. if (typeof value === "object") {
  5567. this.value = visitor.visit(value);
  5568. }
  5569. };
  5570. Element.prototype.eval = function (context) {
  5571. return new Element(this.combinator,
  5572. this.value.eval ? this.value.eval(context) : this.value,
  5573. this.index,
  5574. this.currentFileInfo, this.visibilityInfo());
  5575. };
  5576. Element.prototype.clone = function () {
  5577. return new Element(this.combinator,
  5578. this.value,
  5579. this.index,
  5580. this.currentFileInfo, this.visibilityInfo());
  5581. };
  5582. Element.prototype.genCSS = function (context, output) {
  5583. output.add(this.toCSS(context), this.currentFileInfo, this.index);
  5584. };
  5585. Element.prototype.toCSS = function (context) {
  5586. context = context || {};
  5587. var value = this.value, firstSelector = context.firstSelector;
  5588. if (value instanceof Paren) {
  5589. // selector in parens should not be affected by outer selector
  5590. // flags (breaks only interpolated selectors - see #1973)
  5591. context.firstSelector = true;
  5592. }
  5593. value = value.toCSS ? value.toCSS(context) : value;
  5594. context.firstSelector = firstSelector;
  5595. if (value === '' && this.combinator.value.charAt(0) === '&') {
  5596. return '';
  5597. } else {
  5598. return this.combinator.toCSS(context) + value;
  5599. }
  5600. };
  5601. module.exports = Element;
  5602. },{"./combinator":51,"./node":70,"./paren":72}],59:[function(require,module,exports){
  5603. var Node = require("./node"),
  5604. Paren = require("./paren"),
  5605. Comment = require("./comment");
  5606. var Expression = function (value) {
  5607. this.value = value;
  5608. if (!value) {
  5609. throw new Error("Expression requires an array parameter");
  5610. }
  5611. };
  5612. Expression.prototype = new Node();
  5613. Expression.prototype.type = "Expression";
  5614. Expression.prototype.accept = function (visitor) {
  5615. this.value = visitor.visitArray(this.value);
  5616. };
  5617. Expression.prototype.eval = function (context) {
  5618. var returnValue,
  5619. inParenthesis = this.parens && !this.parensInOp,
  5620. doubleParen = false;
  5621. if (inParenthesis) {
  5622. context.inParenthesis();
  5623. }
  5624. if (this.value.length > 1) {
  5625. returnValue = new Expression(this.value.map(function (e) {
  5626. return e.eval(context);
  5627. }));
  5628. } else if (this.value.length === 1) {
  5629. if (this.value[0].parens && !this.value[0].parensInOp) {
  5630. doubleParen = true;
  5631. }
  5632. returnValue = this.value[0].eval(context);
  5633. } else {
  5634. returnValue = this;
  5635. }
  5636. if (inParenthesis) {
  5637. context.outOfParenthesis();
  5638. }
  5639. if (this.parens && this.parensInOp && !(context.isMathOn()) && !doubleParen) {
  5640. returnValue = new Paren(returnValue);
  5641. }
  5642. return returnValue;
  5643. };
  5644. Expression.prototype.genCSS = function (context, output) {
  5645. for (var i = 0; i < this.value.length; i++) {
  5646. this.value[i].genCSS(context, output);
  5647. if (i + 1 < this.value.length) {
  5648. output.add(" ");
  5649. }
  5650. }
  5651. };
  5652. Expression.prototype.throwAwayComments = function () {
  5653. this.value = this.value.filter(function(v) {
  5654. return !(v instanceof Comment);
  5655. });
  5656. };
  5657. module.exports = Expression;
  5658. },{"./comment":52,"./node":70,"./paren":72}],60:[function(require,module,exports){
  5659. var Node = require("./node"),
  5660. Selector = require("./selector");
  5661. var Extend = function Extend(selector, option, index, currentFileInfo, visibilityInfo) {
  5662. this.selector = selector;
  5663. this.option = option;
  5664. this.index = index;
  5665. this.object_id = Extend.next_id++;
  5666. this.parent_ids = [this.object_id];
  5667. this.currentFileInfo = currentFileInfo || {};
  5668. this.copyVisibilityInfo(visibilityInfo);
  5669. this.allowRoot = true;
  5670. switch(option) {
  5671. case "all":
  5672. this.allowBefore = true;
  5673. this.allowAfter = true;
  5674. break;
  5675. default:
  5676. this.allowBefore = false;
  5677. this.allowAfter = false;
  5678. break;
  5679. }
  5680. };
  5681. Extend.next_id = 0;
  5682. Extend.prototype = new Node();
  5683. Extend.prototype.type = "Extend";
  5684. Extend.prototype.accept = function (visitor) {
  5685. this.selector = visitor.visit(this.selector);
  5686. };
  5687. Extend.prototype.eval = function (context) {
  5688. return new Extend(this.selector.eval(context), this.option, this.index, this.currentFileInfo, this.visibilityInfo());
  5689. };
  5690. Extend.prototype.clone = function (context) {
  5691. return new Extend(this.selector, this.option, this.index, this.currentFileInfo, this.visibilityInfo());
  5692. };
  5693. //it concatenates (joins) all selectors in selector array
  5694. Extend.prototype.findSelfSelectors = function (selectors) {
  5695. var selfElements = [],
  5696. i,
  5697. selectorElements;
  5698. for (i = 0; i < selectors.length; i++) {
  5699. selectorElements = selectors[i].elements;
  5700. // duplicate the logic in genCSS function inside the selector node.
  5701. // future TODO - move both logics into the selector joiner visitor
  5702. if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") {
  5703. selectorElements[0].combinator.value = ' ';
  5704. }
  5705. selfElements = selfElements.concat(selectors[i].elements);
  5706. }
  5707. this.selfSelectors = [new Selector(selfElements)];
  5708. this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());
  5709. };
  5710. module.exports = Extend;
  5711. },{"./node":70,"./selector":77}],61:[function(require,module,exports){
  5712. var Node = require("./node"),
  5713. Media = require("./media"),
  5714. URL = require("./url"),
  5715. Quoted = require("./quoted"),
  5716. Ruleset = require("./ruleset"),
  5717. Anonymous = require("./anonymous");
  5718. //
  5719. // CSS @import node
  5720. //
  5721. // The general strategy here is that we don't want to wait
  5722. // for the parsing to be completed, before we start importing
  5723. // the file. That's because in the context of a browser,
  5724. // most of the time will be spent waiting for the server to respond.
  5725. //
  5726. // On creation, we push the import path to our import queue, though
  5727. // `import,push`, we also pass it a callback, which it'll call once
  5728. // the file has been fetched, and parsed.
  5729. //
  5730. var Import = function (path, features, options, index, currentFileInfo, visibilityInfo) {
  5731. this.options = options;
  5732. this.index = index;
  5733. this.path = path;
  5734. this.features = features;
  5735. this.currentFileInfo = currentFileInfo;
  5736. this.allowRoot = true;
  5737. if (this.options.less !== undefined || this.options.inline) {
  5738. this.css = !this.options.less || this.options.inline;
  5739. } else {
  5740. var pathValue = this.getPath();
  5741. if (pathValue && /[#\.\&\?\/]css([\?;].*)?$/.test(pathValue)) {
  5742. this.css = true;
  5743. }
  5744. }
  5745. this.copyVisibilityInfo(visibilityInfo);
  5746. };
  5747. //
  5748. // The actual import node doesn't return anything, when converted to CSS.
  5749. // The reason is that it's used at the evaluation stage, so that the rules
  5750. // it imports can be treated like any other rules.
  5751. //
  5752. // In `eval`, we make sure all Import nodes get evaluated, recursively, so
  5753. // we end up with a flat structure, which can easily be imported in the parent
  5754. // ruleset.
  5755. //
  5756. Import.prototype = new Node();
  5757. Import.prototype.type = "Import";
  5758. Import.prototype.accept = function (visitor) {
  5759. if (this.features) {
  5760. this.features = visitor.visit(this.features);
  5761. }
  5762. this.path = visitor.visit(this.path);
  5763. if (!this.options.plugin && !this.options.inline && this.root) {
  5764. this.root = visitor.visit(this.root);
  5765. }
  5766. };
  5767. Import.prototype.genCSS = function (context, output) {
  5768. if (this.css && this.path.currentFileInfo.reference === undefined) {
  5769. output.add("@import ", this.currentFileInfo, this.index);
  5770. this.path.genCSS(context, output);
  5771. if (this.features) {
  5772. output.add(" ");
  5773. this.features.genCSS(context, output);
  5774. }
  5775. output.add(';');
  5776. }
  5777. };
  5778. Import.prototype.getPath = function () {
  5779. return (this.path instanceof URL) ?
  5780. this.path.value.value : this.path.value;
  5781. };
  5782. Import.prototype.isVariableImport = function () {
  5783. var path = this.path;
  5784. if (path instanceof URL) {
  5785. path = path.value;
  5786. }
  5787. if (path instanceof Quoted) {
  5788. return path.containsVariables();
  5789. }
  5790. return true;
  5791. };
  5792. Import.prototype.evalForImport = function (context) {
  5793. var path = this.path;
  5794. if (path instanceof URL) {
  5795. path = path.value;
  5796. }
  5797. return new Import(path.eval(context), this.features, this.options, this.index, this.currentFileInfo, this.visibilityInfo());
  5798. };
  5799. Import.prototype.evalPath = function (context) {
  5800. var path = this.path.eval(context);
  5801. var rootpath = this.currentFileInfo && this.currentFileInfo.rootpath;
  5802. if (!(path instanceof URL)) {
  5803. if (rootpath) {
  5804. var pathValue = path.value;
  5805. // Add the base path if the import is relative
  5806. if (pathValue && context.isPathRelative(pathValue)) {
  5807. path.value = rootpath + pathValue;
  5808. }
  5809. }
  5810. path.value = context.normalizePath(path.value);
  5811. }
  5812. return path;
  5813. };
  5814. Import.prototype.eval = function (context) {
  5815. var result = this.doEval(context);
  5816. if (this.options.reference || this.blocksVisibility()) {
  5817. if (result.length || result.length === 0) {
  5818. result.forEach(function (node) {
  5819. node.addVisibilityBlock();
  5820. }
  5821. );
  5822. } else {
  5823. result.addVisibilityBlock();
  5824. }
  5825. }
  5826. return result;
  5827. };
  5828. Import.prototype.doEval = function (context) {
  5829. var ruleset, registry,
  5830. features = this.features && this.features.eval(context);
  5831. if (this.options.plugin) {
  5832. registry = context.frames[0] && context.frames[0].functionRegistry;
  5833. if ( registry && this.root && this.root.functions ) {
  5834. registry.addMultiple( this.root.functions );
  5835. }
  5836. return [];
  5837. }
  5838. if (this.skip) {
  5839. if (typeof this.skip === "function") {
  5840. this.skip = this.skip();
  5841. }
  5842. if (this.skip) {
  5843. return [];
  5844. }
  5845. }
  5846. if (this.options.inline) {
  5847. var contents = new Anonymous(this.root, 0,
  5848. {
  5849. filename: this.importedFilename,
  5850. reference: this.path.currentFileInfo && this.path.currentFileInfo.reference
  5851. }, true, true);
  5852. return this.features ? new Media([contents], this.features.value) : [contents];
  5853. } else if (this.css) {
  5854. var newImport = new Import(this.evalPath(context), features, this.options, this.index);
  5855. if (!newImport.css && this.error) {
  5856. throw this.error;
  5857. }
  5858. return newImport;
  5859. } else {
  5860. ruleset = new Ruleset(null, this.root.rules.slice(0));
  5861. ruleset.evalImports(context);
  5862. return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;
  5863. }
  5864. };
  5865. module.exports = Import;
  5866. },{"./anonymous":46,"./media":66,"./node":70,"./quoted":73,"./ruleset":76,"./url":80}],62:[function(require,module,exports){
  5867. var tree = {};
  5868. tree.Node = require('./node');
  5869. tree.Alpha = require('./alpha');
  5870. tree.Color = require('./color');
  5871. tree.Directive = require('./directive');
  5872. tree.DetachedRuleset = require('./detached-ruleset');
  5873. tree.Operation = require('./operation');
  5874. tree.Dimension = require('./dimension');
  5875. tree.Unit = require('./unit');
  5876. tree.Keyword = require('./keyword');
  5877. tree.Variable = require('./variable');
  5878. tree.Ruleset = require('./ruleset');
  5879. tree.Element = require('./element');
  5880. tree.Attribute = require('./attribute');
  5881. tree.Combinator = require('./combinator');
  5882. tree.Selector = require('./selector');
  5883. tree.Quoted = require('./quoted');
  5884. tree.Expression = require('./expression');
  5885. tree.Rule = require('./rule');
  5886. tree.Call = require('./call');
  5887. tree.URL = require('./url');
  5888. tree.Import = require('./import');
  5889. tree.mixin = {
  5890. Call: require('./mixin-call'),
  5891. Definition: require('./mixin-definition')
  5892. };
  5893. tree.Comment = require('./comment');
  5894. tree.Anonymous = require('./anonymous');
  5895. tree.Value = require('./value');
  5896. tree.JavaScript = require('./javascript');
  5897. tree.Assignment = require('./assignment');
  5898. tree.Condition = require('./condition');
  5899. tree.Paren = require('./paren');
  5900. tree.Media = require('./media');
  5901. tree.UnicodeDescriptor = require('./unicode-descriptor');
  5902. tree.Negative = require('./negative');
  5903. tree.Extend = require('./extend');
  5904. tree.RulesetCall = require('./ruleset-call');
  5905. module.exports = tree;
  5906. },{"./alpha":45,"./anonymous":46,"./assignment":47,"./attribute":48,"./call":49,"./color":50,"./combinator":51,"./comment":52,"./condition":53,"./detached-ruleset":55,"./dimension":56,"./directive":57,"./element":58,"./expression":59,"./extend":60,"./import":61,"./javascript":63,"./keyword":65,"./media":66,"./mixin-call":67,"./mixin-definition":68,"./negative":69,"./node":70,"./operation":71,"./paren":72,"./quoted":73,"./rule":74,"./ruleset":76,"./ruleset-call":75,"./selector":77,"./unicode-descriptor":78,"./unit":79,"./url":80,"./value":81,"./variable":82}],63:[function(require,module,exports){
  5907. var JsEvalNode = require("./js-eval-node"),
  5908. Dimension = require("./dimension"),
  5909. Quoted = require("./quoted"),
  5910. Anonymous = require("./anonymous");
  5911. var JavaScript = function (string, escaped, index, currentFileInfo) {
  5912. this.escaped = escaped;
  5913. this.expression = string;
  5914. this.index = index;
  5915. this.currentFileInfo = currentFileInfo;
  5916. };
  5917. JavaScript.prototype = new JsEvalNode();
  5918. JavaScript.prototype.type = "JavaScript";
  5919. JavaScript.prototype.eval = function(context) {
  5920. var result = this.evaluateJavaScript(this.expression, context);
  5921. if (typeof result === 'number') {
  5922. return new Dimension(result);
  5923. } else if (typeof result === 'string') {
  5924. return new Quoted('"' + result + '"', result, this.escaped, this.index);
  5925. } else if (Array.isArray(result)) {
  5926. return new Anonymous(result.join(', '));
  5927. } else {
  5928. return new Anonymous(result);
  5929. }
  5930. };
  5931. module.exports = JavaScript;
  5932. },{"./anonymous":46,"./dimension":56,"./js-eval-node":64,"./quoted":73}],64:[function(require,module,exports){
  5933. var Node = require("./node"),
  5934. Variable = require("./variable");
  5935. var JsEvalNode = function() {
  5936. };
  5937. JsEvalNode.prototype = new Node();
  5938. JsEvalNode.prototype.evaluateJavaScript = function (expression, context) {
  5939. var result,
  5940. that = this,
  5941. evalContext = {};
  5942. if (context.javascriptEnabled !== undefined && !context.javascriptEnabled) {
  5943. throw { message: "You are using JavaScript, which has been disabled.",
  5944. filename: this.currentFileInfo.filename,
  5945. index: this.index };
  5946. }
  5947. expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) {
  5948. return that.jsify(new Variable('@' + name, that.index, that.currentFileInfo).eval(context));
  5949. });
  5950. try {
  5951. expression = new Function('return (' + expression + ')');
  5952. } catch (e) {
  5953. throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" ,
  5954. filename: this.currentFileInfo.filename,
  5955. index: this.index };
  5956. }
  5957. var variables = context.frames[0].variables();
  5958. for (var k in variables) {
  5959. if (variables.hasOwnProperty(k)) {
  5960. /*jshint loopfunc:true */
  5961. evalContext[k.slice(1)] = {
  5962. value: variables[k].value,
  5963. toJS: function () {
  5964. return this.value.eval(context).toCSS();
  5965. }
  5966. };
  5967. }
  5968. }
  5969. try {
  5970. result = expression.call(evalContext);
  5971. } catch (e) {
  5972. throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" ,
  5973. filename: this.currentFileInfo.filename,
  5974. index: this.index };
  5975. }
  5976. return result;
  5977. };
  5978. JsEvalNode.prototype.jsify = function (obj) {
  5979. if (Array.isArray(obj.value) && (obj.value.length > 1)) {
  5980. return '[' + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + ']';
  5981. } else {
  5982. return obj.toCSS();
  5983. }
  5984. };
  5985. module.exports = JsEvalNode;
  5986. },{"./node":70,"./variable":82}],65:[function(require,module,exports){
  5987. var Node = require("./node");
  5988. var Keyword = function (value) { this.value = value; };
  5989. Keyword.prototype = new Node();
  5990. Keyword.prototype.type = "Keyword";
  5991. Keyword.prototype.genCSS = function (context, output) {
  5992. if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; }
  5993. output.add(this.value);
  5994. };
  5995. Keyword.True = new Keyword('true');
  5996. Keyword.False = new Keyword('false');
  5997. module.exports = Keyword;
  5998. },{"./node":70}],66:[function(require,module,exports){
  5999. var Ruleset = require("./ruleset"),
  6000. Value = require("./value"),
  6001. Selector = require("./selector"),
  6002. Anonymous = require("./anonymous"),
  6003. Expression = require("./expression"),
  6004. Directive = require("./directive");
  6005. var Media = function (value, features, index, currentFileInfo, visibilityInfo) {
  6006. this.index = index;
  6007. this.currentFileInfo = currentFileInfo;
  6008. var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();
  6009. this.features = new Value(features);
  6010. this.rules = [new Ruleset(selectors, value)];
  6011. this.rules[0].allowImports = true;
  6012. this.copyVisibilityInfo(visibilityInfo);
  6013. this.allowRoot = true;
  6014. };
  6015. Media.prototype = new Directive();
  6016. Media.prototype.type = "Media";
  6017. Media.prototype.isRulesetLike = true;
  6018. Media.prototype.accept = function (visitor) {
  6019. if (this.features) {
  6020. this.features = visitor.visit(this.features);
  6021. }
  6022. if (this.rules) {
  6023. this.rules = visitor.visitArray(this.rules);
  6024. }
  6025. };
  6026. Media.prototype.genCSS = function (context, output) {
  6027. output.add('@media ', this.currentFileInfo, this.index);
  6028. this.features.genCSS(context, output);
  6029. this.outputRuleset(context, output, this.rules);
  6030. };
  6031. Media.prototype.eval = function (context) {
  6032. if (!context.mediaBlocks) {
  6033. context.mediaBlocks = [];
  6034. context.mediaPath = [];
  6035. }
  6036. var media = new Media(null, [], this.index, this.currentFileInfo, this.visibilityInfo());
  6037. if (this.debugInfo) {
  6038. this.rules[0].debugInfo = this.debugInfo;
  6039. media.debugInfo = this.debugInfo;
  6040. }
  6041. var strictMathBypass = false;
  6042. if (!context.strictMath) {
  6043. strictMathBypass = true;
  6044. context.strictMath = true;
  6045. }
  6046. try {
  6047. media.features = this.features.eval(context);
  6048. }
  6049. finally {
  6050. if (strictMathBypass) {
  6051. context.strictMath = false;
  6052. }
  6053. }
  6054. context.mediaPath.push(media);
  6055. context.mediaBlocks.push(media);
  6056. this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();
  6057. context.frames.unshift(this.rules[0]);
  6058. media.rules = [this.rules[0].eval(context)];
  6059. context.frames.shift();
  6060. context.mediaPath.pop();
  6061. return context.mediaPath.length === 0 ? media.evalTop(context) :
  6062. media.evalNested(context);
  6063. };
  6064. Media.prototype.evalTop = function (context) {
  6065. var result = this;
  6066. // Render all dependent Media blocks.
  6067. if (context.mediaBlocks.length > 1) {
  6068. var selectors = (new Selector([], null, null, this.index, this.currentFileInfo)).createEmptySelectors();
  6069. result = new Ruleset(selectors, context.mediaBlocks);
  6070. result.multiMedia = true;
  6071. result.copyVisibilityInfo(this.visibilityInfo());
  6072. }
  6073. delete context.mediaBlocks;
  6074. delete context.mediaPath;
  6075. return result;
  6076. };
  6077. Media.prototype.evalNested = function (context) {
  6078. var i, value,
  6079. path = context.mediaPath.concat([this]);
  6080. // Extract the media-query conditions separated with `,` (OR).
  6081. for (i = 0; i < path.length; i++) {
  6082. value = path[i].features instanceof Value ?
  6083. path[i].features.value : path[i].features;
  6084. path[i] = Array.isArray(value) ? value : [value];
  6085. }
  6086. // Trace all permutations to generate the resulting media-query.
  6087. //
  6088. // (a, b and c) with nested (d, e) ->
  6089. // a and d
  6090. // a and e
  6091. // b and c and d
  6092. // b and c and e
  6093. this.features = new Value(this.permute(path).map(function (path) {
  6094. path = path.map(function (fragment) {
  6095. return fragment.toCSS ? fragment : new Anonymous(fragment);
  6096. });
  6097. for (i = path.length - 1; i > 0; i--) {
  6098. path.splice(i, 0, new Anonymous("and"));
  6099. }
  6100. return new Expression(path);
  6101. }));
  6102. // Fake a tree-node that doesn't output anything.
  6103. return new Ruleset([], []);
  6104. };
  6105. Media.prototype.permute = function (arr) {
  6106. if (arr.length === 0) {
  6107. return [];
  6108. } else if (arr.length === 1) {
  6109. return arr[0];
  6110. } else {
  6111. var result = [];
  6112. var rest = this.permute(arr.slice(1));
  6113. for (var i = 0; i < rest.length; i++) {
  6114. for (var j = 0; j < arr[0].length; j++) {
  6115. result.push([arr[0][j]].concat(rest[i]));
  6116. }
  6117. }
  6118. return result;
  6119. }
  6120. };
  6121. Media.prototype.bubbleSelectors = function (selectors) {
  6122. if (!selectors) {
  6123. return;
  6124. }
  6125. this.rules = [new Ruleset(selectors.slice(0), [this.rules[0]])];
  6126. };
  6127. module.exports = Media;
  6128. },{"./anonymous":46,"./directive":57,"./expression":59,"./ruleset":76,"./selector":77,"./value":81}],67:[function(require,module,exports){
  6129. var Node = require("./node"),
  6130. Selector = require("./selector"),
  6131. MixinDefinition = require("./mixin-definition"),
  6132. defaultFunc = require("../functions/default");
  6133. var MixinCall = function (elements, args, index, currentFileInfo, important) {
  6134. this.selector = new Selector(elements);
  6135. this.arguments = args || [];
  6136. this.index = index;
  6137. this.currentFileInfo = currentFileInfo;
  6138. this.important = important;
  6139. this.allowRoot = true;
  6140. };
  6141. MixinCall.prototype = new Node();
  6142. MixinCall.prototype.type = "MixinCall";
  6143. MixinCall.prototype.accept = function (visitor) {
  6144. if (this.selector) {
  6145. this.selector = visitor.visit(this.selector);
  6146. }
  6147. if (this.arguments.length) {
  6148. this.arguments = visitor.visitArray(this.arguments);
  6149. }
  6150. };
  6151. MixinCall.prototype.eval = function (context) {
  6152. var mixins, mixin, mixinPath, args = [], arg, argValue,
  6153. rules = [], match = false, i, m, f, isRecursive, isOneFound,
  6154. candidates = [], candidate, conditionResult = [], defaultResult, defFalseEitherCase = -1,
  6155. defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter;
  6156. function calcDefGroup(mixin, mixinPath) {
  6157. var f, p, namespace;
  6158. for (f = 0; f < 2; f++) {
  6159. conditionResult[f] = true;
  6160. defaultFunc.value(f);
  6161. for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {
  6162. namespace = mixinPath[p];
  6163. if (namespace.matchCondition) {
  6164. conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);
  6165. }
  6166. }
  6167. if (mixin.matchCondition) {
  6168. conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);
  6169. }
  6170. }
  6171. if (conditionResult[0] || conditionResult[1]) {
  6172. if (conditionResult[0] != conditionResult[1]) {
  6173. return conditionResult[1] ?
  6174. defTrue : defFalse;
  6175. }
  6176. return defNone;
  6177. }
  6178. return defFalseEitherCase;
  6179. }
  6180. for (i = 0; i < this.arguments.length; i++) {
  6181. arg = this.arguments[i];
  6182. argValue = arg.value.eval(context);
  6183. if (arg.expand && Array.isArray(argValue.value)) {
  6184. argValue = argValue.value;
  6185. for (m = 0; m < argValue.length; m++) {
  6186. args.push({value: argValue[m]});
  6187. }
  6188. } else {
  6189. args.push({name: arg.name, value: argValue});
  6190. }
  6191. }
  6192. noArgumentsFilter = function(rule) {return rule.matchArgs(null, context);};
  6193. for (i = 0; i < context.frames.length; i++) {
  6194. if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {
  6195. isOneFound = true;
  6196. // To make `default()` function independent of definition order we have two "subpasses" here.
  6197. // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),
  6198. // and build candidate list with corresponding flags. Then, when we know all possible matches,
  6199. // we make a final decision.
  6200. for (m = 0; m < mixins.length; m++) {
  6201. mixin = mixins[m].rule;
  6202. mixinPath = mixins[m].path;
  6203. isRecursive = false;
  6204. for (f = 0; f < context.frames.length; f++) {
  6205. if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {
  6206. isRecursive = true;
  6207. break;
  6208. }
  6209. }
  6210. if (isRecursive) {
  6211. continue;
  6212. }
  6213. if (mixin.matchArgs(args, context)) {
  6214. candidate = {mixin: mixin, group: calcDefGroup(mixin, mixinPath)};
  6215. if (candidate.group !== defFalseEitherCase) {
  6216. candidates.push(candidate);
  6217. }
  6218. match = true;
  6219. }
  6220. }
  6221. defaultFunc.reset();
  6222. count = [0, 0, 0];
  6223. for (m = 0; m < candidates.length; m++) {
  6224. count[candidates[m].group]++;
  6225. }
  6226. if (count[defNone] > 0) {
  6227. defaultResult = defFalse;
  6228. } else {
  6229. defaultResult = defTrue;
  6230. if ((count[defTrue] + count[defFalse]) > 1) {
  6231. throw { type: 'Runtime',
  6232. message: 'Ambiguous use of `default()` found when matching for `' + this.format(args) + '`',
  6233. index: this.index, filename: this.currentFileInfo.filename };
  6234. }
  6235. }
  6236. for (m = 0; m < candidates.length; m++) {
  6237. candidate = candidates[m].group;
  6238. if ((candidate === defNone) || (candidate === defaultResult)) {
  6239. try {
  6240. mixin = candidates[m].mixin;
  6241. if (!(mixin instanceof MixinDefinition)) {
  6242. originalRuleset = mixin.originalRuleset || mixin;
  6243. mixin = new MixinDefinition("", [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
  6244. mixin.originalRuleset = originalRuleset;
  6245. }
  6246. var newRules = mixin.evalCall(context, args, this.important).rules;
  6247. this._setVisibilityToReplacement(newRules);
  6248. Array.prototype.push.apply(rules, newRules);
  6249. } catch (e) {
  6250. throw { message: e.message, index: this.index, filename: this.currentFileInfo.filename, stack: e.stack };
  6251. }
  6252. }
  6253. }
  6254. if (match) {
  6255. return rules;
  6256. }
  6257. }
  6258. }
  6259. if (isOneFound) {
  6260. throw { type: 'Runtime',
  6261. message: 'No matching definition was found for `' + this.format(args) + '`',
  6262. index: this.index, filename: this.currentFileInfo.filename };
  6263. } else {
  6264. throw { type: 'Name',
  6265. message: this.selector.toCSS().trim() + " is undefined",
  6266. index: this.index, filename: this.currentFileInfo.filename };
  6267. }
  6268. };
  6269. MixinCall.prototype._setVisibilityToReplacement = function (replacement) {
  6270. var i, rule;
  6271. if (this.blocksVisibility()) {
  6272. for (i = 0; i < replacement.length; i++) {
  6273. rule = replacement[i];
  6274. rule.addVisibilityBlock();
  6275. }
  6276. }
  6277. };
  6278. MixinCall.prototype.format = function (args) {
  6279. return this.selector.toCSS().trim() + '(' +
  6280. (args ? args.map(function (a) {
  6281. var argValue = "";
  6282. if (a.name) {
  6283. argValue += a.name + ":";
  6284. }
  6285. if (a.value.toCSS) {
  6286. argValue += a.value.toCSS();
  6287. } else {
  6288. argValue += "???";
  6289. }
  6290. return argValue;
  6291. }).join(', ') : "") + ")";
  6292. };
  6293. module.exports = MixinCall;
  6294. },{"../functions/default":20,"./mixin-definition":68,"./node":70,"./selector":77}],68:[function(require,module,exports){
  6295. var Selector = require("./selector"),
  6296. Element = require("./element"),
  6297. Ruleset = require("./ruleset"),
  6298. Rule = require("./rule"),
  6299. Expression = require("./expression"),
  6300. contexts = require("../contexts");
  6301. var Definition = function (name, params, rules, condition, variadic, frames, visibilityInfo) {
  6302. this.name = name;
  6303. this.selectors = [new Selector([new Element(null, name, this.index, this.currentFileInfo)])];
  6304. this.params = params;
  6305. this.condition = condition;
  6306. this.variadic = variadic;
  6307. this.arity = params.length;
  6308. this.rules = rules;
  6309. this._lookups = {};
  6310. var optionalParameters = [];
  6311. this.required = params.reduce(function (count, p) {
  6312. if (!p.name || (p.name && !p.value)) {
  6313. return count + 1;
  6314. }
  6315. else {
  6316. optionalParameters.push(p.name);
  6317. return count;
  6318. }
  6319. }, 0);
  6320. this.optionalParameters = optionalParameters;
  6321. this.frames = frames;
  6322. this.copyVisibilityInfo(visibilityInfo);
  6323. this.allowRoot = true;
  6324. };
  6325. Definition.prototype = new Ruleset();
  6326. Definition.prototype.type = "MixinDefinition";
  6327. Definition.prototype.evalFirst = true;
  6328. Definition.prototype.accept = function (visitor) {
  6329. if (this.params && this.params.length) {
  6330. this.params = visitor.visitArray(this.params);
  6331. }
  6332. this.rules = visitor.visitArray(this.rules);
  6333. if (this.condition) {
  6334. this.condition = visitor.visit(this.condition);
  6335. }
  6336. };
  6337. Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) {
  6338. /*jshint boss:true */
  6339. var frame = new Ruleset(null, null),
  6340. varargs, arg,
  6341. params = this.params.slice(0),
  6342. i, j, val, name, isNamedFound, argIndex, argsLength = 0;
  6343. if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {
  6344. frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();
  6345. }
  6346. mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));
  6347. if (args) {
  6348. args = args.slice(0);
  6349. argsLength = args.length;
  6350. for (i = 0; i < argsLength; i++) {
  6351. arg = args[i];
  6352. if (name = (arg && arg.name)) {
  6353. isNamedFound = false;
  6354. for (j = 0; j < params.length; j++) {
  6355. if (!evaldArguments[j] && name === params[j].name) {
  6356. evaldArguments[j] = arg.value.eval(context);
  6357. frame.prependRule(new Rule(name, arg.value.eval(context)));
  6358. isNamedFound = true;
  6359. break;
  6360. }
  6361. }
  6362. if (isNamedFound) {
  6363. args.splice(i, 1);
  6364. i--;
  6365. continue;
  6366. } else {
  6367. throw { type: 'Runtime', message: "Named argument for " + this.name +
  6368. ' ' + args[i].name + ' not found' };
  6369. }
  6370. }
  6371. }
  6372. }
  6373. argIndex = 0;
  6374. for (i = 0; i < params.length; i++) {
  6375. if (evaldArguments[i]) { continue; }
  6376. arg = args && args[argIndex];
  6377. if (name = params[i].name) {
  6378. if (params[i].variadic) {
  6379. varargs = [];
  6380. for (j = argIndex; j < argsLength; j++) {
  6381. varargs.push(args[j].value.eval(context));
  6382. }
  6383. frame.prependRule(new Rule(name, new Expression(varargs).eval(context)));
  6384. } else {
  6385. val = arg && arg.value;
  6386. if (val) {
  6387. val = val.eval(context);
  6388. } else if (params[i].value) {
  6389. val = params[i].value.eval(mixinEnv);
  6390. frame.resetCache();
  6391. } else {
  6392. throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
  6393. ' (' + argsLength + ' for ' + this.arity + ')' };
  6394. }
  6395. frame.prependRule(new Rule(name, val));
  6396. evaldArguments[i] = val;
  6397. }
  6398. }
  6399. if (params[i].variadic && args) {
  6400. for (j = argIndex; j < argsLength; j++) {
  6401. evaldArguments[j] = args[j].value.eval(context);
  6402. }
  6403. }
  6404. argIndex++;
  6405. }
  6406. return frame;
  6407. };
  6408. Definition.prototype.makeImportant = function() {
  6409. var rules = !this.rules ? this.rules : this.rules.map(function (r) {
  6410. if (r.makeImportant) {
  6411. return r.makeImportant(true);
  6412. } else {
  6413. return r;
  6414. }
  6415. });
  6416. var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);
  6417. return result;
  6418. };
  6419. Definition.prototype.eval = function (context) {
  6420. return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || context.frames.slice(0));
  6421. };
  6422. Definition.prototype.evalCall = function (context, args, important) {
  6423. var _arguments = [],
  6424. mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames,
  6425. frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments),
  6426. rules, ruleset;
  6427. frame.prependRule(new Rule('@arguments', new Expression(_arguments).eval(context)));
  6428. rules = this.rules.slice(0);
  6429. ruleset = new Ruleset(null, rules);
  6430. ruleset.originalRuleset = this;
  6431. ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));
  6432. if (important) {
  6433. ruleset = ruleset.makeImportant();
  6434. }
  6435. return ruleset;
  6436. };
  6437. Definition.prototype.matchCondition = function (args, context) {
  6438. if (this.condition && !this.condition.eval(
  6439. new contexts.Eval(context,
  6440. [this.evalParams(context, /* the parameter variables*/
  6441. new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]
  6442. .concat(this.frames || []) // the parent namespace/mixin frames
  6443. .concat(context.frames)))) { // the current environment frames
  6444. return false;
  6445. }
  6446. return true;
  6447. };
  6448. Definition.prototype.matchArgs = function (args, context) {
  6449. var allArgsCnt = (args && args.length) || 0, len, optionalParameters = this.optionalParameters;
  6450. var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) {
  6451. if (optionalParameters.indexOf(p.name) < 0) {
  6452. return count + 1;
  6453. } else {
  6454. return count;
  6455. }
  6456. }, 0);
  6457. if (! this.variadic) {
  6458. if (requiredArgsCnt < this.required) {
  6459. return false;
  6460. }
  6461. if (allArgsCnt > this.params.length) {
  6462. return false;
  6463. }
  6464. } else {
  6465. if (requiredArgsCnt < (this.required - 1)) {
  6466. return false;
  6467. }
  6468. }
  6469. // check patterns
  6470. len = Math.min(requiredArgsCnt, this.arity);
  6471. for (var i = 0; i < len; i++) {
  6472. if (!this.params[i].name && !this.params[i].variadic) {
  6473. if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) {
  6474. return false;
  6475. }
  6476. }
  6477. }
  6478. return true;
  6479. };
  6480. module.exports = Definition;
  6481. },{"../contexts":11,"./element":58,"./expression":59,"./rule":74,"./ruleset":76,"./selector":77}],69:[function(require,module,exports){
  6482. var Node = require("./node"),
  6483. Operation = require("./operation"),
  6484. Dimension = require("./dimension");
  6485. var Negative = function (node) {
  6486. this.value = node;
  6487. };
  6488. Negative.prototype = new Node();
  6489. Negative.prototype.type = "Negative";
  6490. Negative.prototype.genCSS = function (context, output) {
  6491. output.add('-');
  6492. this.value.genCSS(context, output);
  6493. };
  6494. Negative.prototype.eval = function (context) {
  6495. if (context.isMathOn()) {
  6496. return (new Operation('*', [new Dimension(-1), this.value])).eval(context);
  6497. }
  6498. return new Negative(this.value.eval(context));
  6499. };
  6500. module.exports = Negative;
  6501. },{"./dimension":56,"./node":70,"./operation":71}],70:[function(require,module,exports){
  6502. var Node = function() {
  6503. };
  6504. Node.prototype.toCSS = function (context) {
  6505. var strs = [];
  6506. this.genCSS(context, {
  6507. add: function(chunk, fileInfo, index) {
  6508. strs.push(chunk);
  6509. },
  6510. isEmpty: function () {
  6511. return strs.length === 0;
  6512. }
  6513. });
  6514. return strs.join('');
  6515. };
  6516. Node.prototype.genCSS = function (context, output) {
  6517. output.add(this.value);
  6518. };
  6519. Node.prototype.accept = function (visitor) {
  6520. this.value = visitor.visit(this.value);
  6521. };
  6522. Node.prototype.eval = function () { return this; };
  6523. Node.prototype._operate = function (context, op, a, b) {
  6524. switch (op) {
  6525. case '+': return a + b;
  6526. case '-': return a - b;
  6527. case '*': return a * b;
  6528. case '/': return a / b;
  6529. }
  6530. };
  6531. Node.prototype.fround = function(context, value) {
  6532. var precision = context && context.numPrecision;
  6533. //add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999....) are properly rounded...
  6534. return (precision == null) ? value : Number((value + 2e-16).toFixed(precision));
  6535. };
  6536. Node.compare = function (a, b) {
  6537. /* returns:
  6538. -1: a < b
  6539. 0: a = b
  6540. 1: a > b
  6541. and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */
  6542. if ((a.compare) &&
  6543. // for "symmetric results" force toCSS-based comparison
  6544. // of Quoted or Anonymous if either value is one of those
  6545. !(b.type === "Quoted" || b.type === "Anonymous")) {
  6546. return a.compare(b);
  6547. } else if (b.compare) {
  6548. return -b.compare(a);
  6549. } else if (a.type !== b.type) {
  6550. return undefined;
  6551. }
  6552. a = a.value;
  6553. b = b.value;
  6554. if (!Array.isArray(a)) {
  6555. return a === b ? 0 : undefined;
  6556. }
  6557. if (a.length !== b.length) {
  6558. return undefined;
  6559. }
  6560. for (var i = 0; i < a.length; i++) {
  6561. if (Node.compare(a[i], b[i]) !== 0) {
  6562. return undefined;
  6563. }
  6564. }
  6565. return 0;
  6566. };
  6567. Node.numericCompare = function (a, b) {
  6568. return a < b ? -1
  6569. : a === b ? 0
  6570. : a > b ? 1 : undefined;
  6571. };
  6572. // Returns true if this node represents root of ast imported by reference
  6573. Node.prototype.blocksVisibility = function () {
  6574. if (this.visibilityBlocks == null) {
  6575. this.visibilityBlocks = 0;
  6576. }
  6577. return this.visibilityBlocks !== 0;
  6578. };
  6579. Node.prototype.addVisibilityBlock = function () {
  6580. if (this.visibilityBlocks == null) {
  6581. this.visibilityBlocks = 0;
  6582. }
  6583. this.visibilityBlocks = this.visibilityBlocks + 1;
  6584. };
  6585. Node.prototype.removeVisibilityBlock = function () {
  6586. if (this.visibilityBlocks == null) {
  6587. this.visibilityBlocks = 0;
  6588. }
  6589. this.visibilityBlocks = this.visibilityBlocks - 1;
  6590. };
  6591. //Turns on node visibility - if called node will be shown in output regardless
  6592. //of whether it comes from import by reference or not
  6593. Node.prototype.ensureVisibility = function () {
  6594. this.nodeVisible = true;
  6595. };
  6596. //Turns off node visibility - if called node will NOT be shown in output regardless
  6597. //of whether it comes from import by reference or not
  6598. Node.prototype.ensureInvisibility = function () {
  6599. this.nodeVisible = false;
  6600. };
  6601. // return values:
  6602. // false - the node must not be visible
  6603. // true - the node must be visible
  6604. // undefined or null - the node has the same visibility as its parent
  6605. Node.prototype.isVisible = function () {
  6606. return this.nodeVisible;
  6607. };
  6608. Node.prototype.visibilityInfo = function() {
  6609. return {
  6610. visibilityBlocks: this.visibilityBlocks,
  6611. nodeVisible: this.nodeVisible
  6612. };
  6613. };
  6614. Node.prototype.copyVisibilityInfo = function(info) {
  6615. if (!info) {
  6616. return;
  6617. }
  6618. this.visibilityBlocks = info.visibilityBlocks;
  6619. this.nodeVisible = info.nodeVisible;
  6620. };
  6621. module.exports = Node;
  6622. },{}],71:[function(require,module,exports){
  6623. var Node = require("./node"),
  6624. Color = require("./color"),
  6625. Dimension = require("./dimension");
  6626. var Operation = function (op, operands, isSpaced) {
  6627. this.op = op.trim();
  6628. this.operands = operands;
  6629. this.isSpaced = isSpaced;
  6630. };
  6631. Operation.prototype = new Node();
  6632. Operation.prototype.type = "Operation";
  6633. Operation.prototype.accept = function (visitor) {
  6634. this.operands = visitor.visit(this.operands);
  6635. };
  6636. Operation.prototype.eval = function (context) {
  6637. var a = this.operands[0].eval(context),
  6638. b = this.operands[1].eval(context);
  6639. if (context.isMathOn()) {
  6640. if (a instanceof Dimension && b instanceof Color) {
  6641. a = a.toColor();
  6642. }
  6643. if (b instanceof Dimension && a instanceof Color) {
  6644. b = b.toColor();
  6645. }
  6646. if (!a.operate) {
  6647. throw { type: "Operation",
  6648. message: "Operation on an invalid type" };
  6649. }
  6650. return a.operate(context, this.op, b);
  6651. } else {
  6652. return new Operation(this.op, [a, b], this.isSpaced);
  6653. }
  6654. };
  6655. Operation.prototype.genCSS = function (context, output) {
  6656. this.operands[0].genCSS(context, output);
  6657. if (this.isSpaced) {
  6658. output.add(" ");
  6659. }
  6660. output.add(this.op);
  6661. if (this.isSpaced) {
  6662. output.add(" ");
  6663. }
  6664. this.operands[1].genCSS(context, output);
  6665. };
  6666. module.exports = Operation;
  6667. },{"./color":50,"./dimension":56,"./node":70}],72:[function(require,module,exports){
  6668. var Node = require("./node");
  6669. var Paren = function (node) {
  6670. this.value = node;
  6671. };
  6672. Paren.prototype = new Node();
  6673. Paren.prototype.type = "Paren";
  6674. Paren.prototype.genCSS = function (context, output) {
  6675. output.add('(');
  6676. this.value.genCSS(context, output);
  6677. output.add(')');
  6678. };
  6679. Paren.prototype.eval = function (context) {
  6680. return new Paren(this.value.eval(context));
  6681. };
  6682. module.exports = Paren;
  6683. },{"./node":70}],73:[function(require,module,exports){
  6684. var Node = require("./node"),
  6685. JsEvalNode = require("./js-eval-node"),
  6686. Variable = require("./variable");
  6687. var Quoted = function (str, content, escaped, index, currentFileInfo) {
  6688. this.escaped = (escaped == null) ? true : escaped;
  6689. this.value = content || '';
  6690. this.quote = str.charAt(0);
  6691. this.index = index;
  6692. this.currentFileInfo = currentFileInfo;
  6693. };
  6694. Quoted.prototype = new JsEvalNode();
  6695. Quoted.prototype.type = "Quoted";
  6696. Quoted.prototype.genCSS = function (context, output) {
  6697. if (!this.escaped) {
  6698. output.add(this.quote, this.currentFileInfo, this.index);
  6699. }
  6700. output.add(this.value);
  6701. if (!this.escaped) {
  6702. output.add(this.quote);
  6703. }
  6704. };
  6705. Quoted.prototype.containsVariables = function() {
  6706. return this.value.match(/(`([^`]+)`)|@\{([\w-]+)\}/);
  6707. };
  6708. Quoted.prototype.eval = function (context) {
  6709. var that = this, value = this.value;
  6710. var javascriptReplacement = function (_, exp) {
  6711. return String(that.evaluateJavaScript(exp, context));
  6712. };
  6713. var interpolationReplacement = function (_, name) {
  6714. var v = new Variable('@' + name, that.index, that.currentFileInfo).eval(context, true);
  6715. return (v instanceof Quoted) ? v.value : v.toCSS();
  6716. };
  6717. function iterativeReplace(value, regexp, replacementFnc) {
  6718. var evaluatedValue = value;
  6719. do {
  6720. value = evaluatedValue;
  6721. evaluatedValue = value.replace(regexp, replacementFnc);
  6722. } while (value !== evaluatedValue);
  6723. return evaluatedValue;
  6724. }
  6725. value = iterativeReplace(value, /`([^`]+)`/g, javascriptReplacement);
  6726. value = iterativeReplace(value, /@\{([\w-]+)\}/g, interpolationReplacement);
  6727. return new Quoted(this.quote + value + this.quote, value, this.escaped, this.index, this.currentFileInfo);
  6728. };
  6729. Quoted.prototype.compare = function (other) {
  6730. // when comparing quoted strings allow the quote to differ
  6731. if (other.type === "Quoted" && !this.escaped && !other.escaped) {
  6732. return Node.numericCompare(this.value, other.value);
  6733. } else {
  6734. return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;
  6735. }
  6736. };
  6737. module.exports = Quoted;
  6738. },{"./js-eval-node":64,"./node":70,"./variable":82}],74:[function(require,module,exports){
  6739. var Node = require("./node"),
  6740. Value = require("./value"),
  6741. Keyword = require("./keyword");
  6742. var Rule = function (name, value, important, merge, index, currentFileInfo, inline, variable) {
  6743. this.name = name;
  6744. this.value = (value instanceof Node) ? value : new Value([value]); //value instanceof tree.Value || value instanceof tree.Ruleset ??
  6745. this.important = important ? ' ' + important.trim() : '';
  6746. this.merge = merge;
  6747. this.index = index;
  6748. this.currentFileInfo = currentFileInfo;
  6749. this.inline = inline || false;
  6750. this.variable = (variable !== undefined) ? variable
  6751. : (name.charAt && (name.charAt(0) === '@'));
  6752. this.allowRoot = true;
  6753. };
  6754. function evalName(context, name) {
  6755. var value = "", i, n = name.length,
  6756. output = {add: function (s) {value += s;}};
  6757. for (i = 0; i < n; i++) {
  6758. name[i].eval(context).genCSS(context, output);
  6759. }
  6760. return value;
  6761. }
  6762. Rule.prototype = new Node();
  6763. Rule.prototype.type = "Rule";
  6764. Rule.prototype.genCSS = function (context, output) {
  6765. output.add(this.name + (context.compress ? ':' : ': '), this.currentFileInfo, this.index);
  6766. try {
  6767. this.value.genCSS(context, output);
  6768. }
  6769. catch(e) {
  6770. e.index = this.index;
  6771. e.filename = this.currentFileInfo.filename;
  6772. throw e;
  6773. }
  6774. output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? "" : ";"), this.currentFileInfo, this.index);
  6775. };
  6776. Rule.prototype.eval = function (context) {
  6777. var strictMathBypass = false, name = this.name, evaldValue, variable = this.variable;
  6778. if (typeof name !== "string") {
  6779. // expand 'primitive' name directly to get
  6780. // things faster (~10% for benchmark.less):
  6781. name = (name.length === 1) && (name[0] instanceof Keyword) ?
  6782. name[0].value : evalName(context, name);
  6783. variable = false; // never treat expanded interpolation as new variable name
  6784. }
  6785. if (name === "font" && !context.strictMath) {
  6786. strictMathBypass = true;
  6787. context.strictMath = true;
  6788. }
  6789. try {
  6790. context.importantScope.push({});
  6791. evaldValue = this.value.eval(context);
  6792. if (!this.variable && evaldValue.type === "DetachedRuleset") {
  6793. throw { message: "Rulesets cannot be evaluated on a property.",
  6794. index: this.index, filename: this.currentFileInfo.filename };
  6795. }
  6796. var important = this.important,
  6797. importantResult = context.importantScope.pop();
  6798. if (!important && importantResult.important) {
  6799. important = importantResult.important;
  6800. }
  6801. return new Rule(name,
  6802. evaldValue,
  6803. important,
  6804. this.merge,
  6805. this.index, this.currentFileInfo, this.inline,
  6806. variable);
  6807. }
  6808. catch(e) {
  6809. if (typeof e.index !== 'number') {
  6810. e.index = this.index;
  6811. e.filename = this.currentFileInfo.filename;
  6812. }
  6813. throw e;
  6814. }
  6815. finally {
  6816. if (strictMathBypass) {
  6817. context.strictMath = false;
  6818. }
  6819. }
  6820. };
  6821. Rule.prototype.makeImportant = function () {
  6822. return new Rule(this.name,
  6823. this.value,
  6824. "!important",
  6825. this.merge,
  6826. this.index, this.currentFileInfo, this.inline);
  6827. };
  6828. module.exports = Rule;
  6829. },{"./keyword":65,"./node":70,"./value":81}],75:[function(require,module,exports){
  6830. var Node = require("./node"),
  6831. Variable = require("./variable");
  6832. var RulesetCall = function (variable) {
  6833. this.variable = variable;
  6834. this.allowRoot = true;
  6835. };
  6836. RulesetCall.prototype = new Node();
  6837. RulesetCall.prototype.type = "RulesetCall";
  6838. RulesetCall.prototype.eval = function (context) {
  6839. var detachedRuleset = new Variable(this.variable).eval(context);
  6840. return detachedRuleset.callEval(context);
  6841. };
  6842. module.exports = RulesetCall;
  6843. },{"./node":70,"./variable":82}],76:[function(require,module,exports){
  6844. var Node = require("./node"),
  6845. Rule = require("./rule"),
  6846. Selector = require("./selector"),
  6847. Element = require("./element"),
  6848. Paren = require("./paren"),
  6849. contexts = require("../contexts"),
  6850. globalFunctionRegistry = require("../functions/function-registry"),
  6851. defaultFunc = require("../functions/default"),
  6852. getDebugInfo = require("./debug-info");
  6853. var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
  6854. this.selectors = selectors;
  6855. this.rules = rules;
  6856. this._lookups = {};
  6857. this.strictImports = strictImports;
  6858. this.copyVisibilityInfo(visibilityInfo);
  6859. this.allowRoot = true;
  6860. };
  6861. Ruleset.prototype = new Node();
  6862. Ruleset.prototype.type = "Ruleset";
  6863. Ruleset.prototype.isRuleset = true;
  6864. Ruleset.prototype.isRulesetLike = true;
  6865. Ruleset.prototype.accept = function (visitor) {
  6866. if (this.paths) {
  6867. this.paths = visitor.visitArray(this.paths, true);
  6868. } else if (this.selectors) {
  6869. this.selectors = visitor.visitArray(this.selectors);
  6870. }
  6871. if (this.rules && this.rules.length) {
  6872. this.rules = visitor.visitArray(this.rules);
  6873. }
  6874. };
  6875. Ruleset.prototype.eval = function (context) {
  6876. var thisSelectors = this.selectors, selectors,
  6877. selCnt, selector, i, hasOnePassingSelector = false;
  6878. if (thisSelectors && (selCnt = thisSelectors.length)) {
  6879. selectors = [];
  6880. defaultFunc.error({
  6881. type: "Syntax",
  6882. message: "it is currently only allowed in parametric mixin guards,"
  6883. });
  6884. for (i = 0; i < selCnt; i++) {
  6885. selector = thisSelectors[i].eval(context);
  6886. selectors.push(selector);
  6887. if (selector.evaldCondition) {
  6888. hasOnePassingSelector = true;
  6889. }
  6890. }
  6891. defaultFunc.reset();
  6892. } else {
  6893. hasOnePassingSelector = true;
  6894. }
  6895. var rules = this.rules ? this.rules.slice(0) : null,
  6896. ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()),
  6897. rule, subRule;
  6898. ruleset.originalRuleset = this;
  6899. ruleset.root = this.root;
  6900. ruleset.firstRoot = this.firstRoot;
  6901. ruleset.allowImports = this.allowImports;
  6902. if (this.debugInfo) {
  6903. ruleset.debugInfo = this.debugInfo;
  6904. }
  6905. if (!hasOnePassingSelector) {
  6906. rules.length = 0;
  6907. }
  6908. // inherit a function registry from the frames stack when possible;
  6909. // otherwise from the global registry
  6910. ruleset.functionRegistry = (function (frames) {
  6911. var i = 0,
  6912. n = frames.length,
  6913. found;
  6914. for ( ; i !== n ; ++i ) {
  6915. found = frames[ i ].functionRegistry;
  6916. if ( found ) { return found; }
  6917. }
  6918. return globalFunctionRegistry;
  6919. }(context.frames)).inherit();
  6920. // push the current ruleset to the frames stack
  6921. var ctxFrames = context.frames;
  6922. ctxFrames.unshift(ruleset);
  6923. // currrent selectors
  6924. var ctxSelectors = context.selectors;
  6925. if (!ctxSelectors) {
  6926. context.selectors = ctxSelectors = [];
  6927. }
  6928. ctxSelectors.unshift(this.selectors);
  6929. // Evaluate imports
  6930. if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {
  6931. ruleset.evalImports(context);
  6932. }
  6933. // Store the frames around mixin definitions,
  6934. // so they can be evaluated like closures when the time comes.
  6935. var rsRules = ruleset.rules, rsRuleCnt = rsRules ? rsRules.length : 0;
  6936. for (i = 0; i < rsRuleCnt; i++) {
  6937. if (rsRules[i].evalFirst) {
  6938. rsRules[i] = rsRules[i].eval(context);
  6939. }
  6940. }
  6941. var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;
  6942. // Evaluate mixin calls.
  6943. for (i = 0; i < rsRuleCnt; i++) {
  6944. if (rsRules[i].type === "MixinCall") {
  6945. /*jshint loopfunc:true */
  6946. rules = rsRules[i].eval(context).filter(function(r) {
  6947. if ((r instanceof Rule) && r.variable) {
  6948. // do not pollute the scope if the variable is
  6949. // already there. consider returning false here
  6950. // but we need a way to "return" variable from mixins
  6951. return !(ruleset.variable(r.name));
  6952. }
  6953. return true;
  6954. });
  6955. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  6956. rsRuleCnt += rules.length - 1;
  6957. i += rules.length - 1;
  6958. ruleset.resetCache();
  6959. } else if (rsRules[i].type === "RulesetCall") {
  6960. /*jshint loopfunc:true */
  6961. rules = rsRules[i].eval(context).rules.filter(function(r) {
  6962. if ((r instanceof Rule) && r.variable) {
  6963. // do not pollute the scope at all
  6964. return false;
  6965. }
  6966. return true;
  6967. });
  6968. rsRules.splice.apply(rsRules, [i, 1].concat(rules));
  6969. rsRuleCnt += rules.length - 1;
  6970. i += rules.length - 1;
  6971. ruleset.resetCache();
  6972. }
  6973. }
  6974. // Evaluate everything else
  6975. for (i = 0; i < rsRules.length; i++) {
  6976. rule = rsRules[i];
  6977. if (!rule.evalFirst) {
  6978. rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;
  6979. }
  6980. }
  6981. // Evaluate everything else
  6982. for (i = 0; i < rsRules.length; i++) {
  6983. rule = rsRules[i];
  6984. // for rulesets, check if it is a css guard and can be removed
  6985. if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
  6986. // check if it can be folded in (e.g. & where)
  6987. if (rule.selectors[0].isJustParentSelector()) {
  6988. rsRules.splice(i--, 1);
  6989. for (var j = 0; j < rule.rules.length; j++) {
  6990. subRule = rule.rules[j];
  6991. subRule.copyVisibilityInfo(rule.visibilityInfo());
  6992. if (!(subRule instanceof Rule) || !subRule.variable) {
  6993. rsRules.splice(++i, 0, subRule);
  6994. }
  6995. }
  6996. }
  6997. }
  6998. }
  6999. // Pop the stack
  7000. ctxFrames.shift();
  7001. ctxSelectors.shift();
  7002. if (context.mediaBlocks) {
  7003. for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {
  7004. context.mediaBlocks[i].bubbleSelectors(selectors);
  7005. }
  7006. }
  7007. return ruleset;
  7008. };
  7009. Ruleset.prototype.evalImports = function(context) {
  7010. var rules = this.rules, i, importRules;
  7011. if (!rules) { return; }
  7012. for (i = 0; i < rules.length; i++) {
  7013. if (rules[i].type === "Import") {
  7014. importRules = rules[i].eval(context);
  7015. if (importRules && (importRules.length || importRules.length === 0)) {
  7016. rules.splice.apply(rules, [i, 1].concat(importRules));
  7017. i+= importRules.length - 1;
  7018. } else {
  7019. rules.splice(i, 1, importRules);
  7020. }
  7021. this.resetCache();
  7022. }
  7023. }
  7024. };
  7025. Ruleset.prototype.makeImportant = function() {
  7026. var result = new Ruleset(this.selectors, this.rules.map(function (r) {
  7027. if (r.makeImportant) {
  7028. return r.makeImportant();
  7029. } else {
  7030. return r;
  7031. }
  7032. }), this.strictImports, this.visibilityInfo());
  7033. return result;
  7034. };
  7035. Ruleset.prototype.matchArgs = function (args) {
  7036. return !args || args.length === 0;
  7037. };
  7038. // lets you call a css selector with a guard
  7039. Ruleset.prototype.matchCondition = function (args, context) {
  7040. var lastSelector = this.selectors[this.selectors.length - 1];
  7041. if (!lastSelector.evaldCondition) {
  7042. return false;
  7043. }
  7044. if (lastSelector.condition &&
  7045. !lastSelector.condition.eval(
  7046. new contexts.Eval(context,
  7047. context.frames))) {
  7048. return false;
  7049. }
  7050. return true;
  7051. };
  7052. Ruleset.prototype.resetCache = function () {
  7053. this._rulesets = null;
  7054. this._variables = null;
  7055. this._lookups = {};
  7056. };
  7057. Ruleset.prototype.variables = function () {
  7058. if (!this._variables) {
  7059. this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) {
  7060. if (r instanceof Rule && r.variable === true) {
  7061. hash[r.name] = r;
  7062. }
  7063. // when evaluating variables in an import statement, imports have not been eval'd
  7064. // so we need to go inside import statements.
  7065. // guard against root being a string (in the case of inlined less)
  7066. if (r.type === "Import" && r.root && r.root.variables) {
  7067. var vars = r.root.variables();
  7068. for (var name in vars) {
  7069. if (vars.hasOwnProperty(name)) {
  7070. hash[name] = vars[name];
  7071. }
  7072. }
  7073. }
  7074. return hash;
  7075. }, {});
  7076. }
  7077. return this._variables;
  7078. };
  7079. Ruleset.prototype.variable = function (name) {
  7080. return this.variables()[name];
  7081. };
  7082. Ruleset.prototype.rulesets = function () {
  7083. if (!this.rules) { return []; }
  7084. var filtRules = [], rules = this.rules, cnt = rules.length,
  7085. i, rule;
  7086. for (i = 0; i < cnt; i++) {
  7087. rule = rules[i];
  7088. if (rule.isRuleset) {
  7089. filtRules.push(rule);
  7090. }
  7091. }
  7092. return filtRules;
  7093. };
  7094. Ruleset.prototype.prependRule = function (rule) {
  7095. var rules = this.rules;
  7096. if (rules) {
  7097. rules.unshift(rule);
  7098. } else {
  7099. this.rules = [ rule ];
  7100. }
  7101. };
  7102. Ruleset.prototype.find = function (selector, self, filter) {
  7103. self = self || this;
  7104. var rules = [], match, foundMixins,
  7105. key = selector.toCSS();
  7106. if (key in this._lookups) { return this._lookups[key]; }
  7107. this.rulesets().forEach(function (rule) {
  7108. if (rule !== self) {
  7109. for (var j = 0; j < rule.selectors.length; j++) {
  7110. match = selector.match(rule.selectors[j]);
  7111. if (match) {
  7112. if (selector.elements.length > match) {
  7113. if (!filter || filter(rule)) {
  7114. foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);
  7115. for (var i = 0; i < foundMixins.length; ++i) {
  7116. foundMixins[i].path.push(rule);
  7117. }
  7118. Array.prototype.push.apply(rules, foundMixins);
  7119. }
  7120. } else {
  7121. rules.push({ rule: rule, path: []});
  7122. }
  7123. break;
  7124. }
  7125. }
  7126. }
  7127. });
  7128. this._lookups[key] = rules;
  7129. return rules;
  7130. };
  7131. Ruleset.prototype.genCSS = function (context, output) {
  7132. var i, j,
  7133. charsetRuleNodes = [],
  7134. ruleNodes = [],
  7135. debugInfo, // Line number debugging
  7136. rule,
  7137. path;
  7138. context.tabLevel = (context.tabLevel || 0);
  7139. if (!this.root) {
  7140. context.tabLevel++;
  7141. }
  7142. var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(" "),
  7143. tabSetStr = context.compress ? '' : Array(context.tabLevel).join(" "),
  7144. sep;
  7145. function isRulesetLikeNode(rule) {
  7146. // if it has nested rules, then it should be treated like a ruleset
  7147. // medias and comments do not have nested rules, but should be treated like rulesets anyway
  7148. // some directives and anonymous nodes are ruleset like, others are not
  7149. if (typeof rule.isRulesetLike === "boolean") {
  7150. return rule.isRulesetLike;
  7151. } else if (typeof rule.isRulesetLike === "function") {
  7152. return rule.isRulesetLike();
  7153. }
  7154. //anything else is assumed to be a rule
  7155. return false;
  7156. }
  7157. var charsetNodeIndex = 0;
  7158. var importNodeIndex = 0;
  7159. for (i = 0; i < this.rules.length; i++) {
  7160. rule = this.rules[i];
  7161. if (rule.type === "Comment") {
  7162. if (importNodeIndex === i) {
  7163. importNodeIndex++;
  7164. }
  7165. ruleNodes.push(rule);
  7166. } else if (rule.isCharset && rule.isCharset()) {
  7167. ruleNodes.splice(charsetNodeIndex, 0, rule);
  7168. charsetNodeIndex++;
  7169. importNodeIndex++;
  7170. } else if (rule.type === "Import") {
  7171. ruleNodes.splice(importNodeIndex, 0, rule);
  7172. importNodeIndex++;
  7173. } else {
  7174. ruleNodes.push(rule);
  7175. }
  7176. }
  7177. ruleNodes = charsetRuleNodes.concat(ruleNodes);
  7178. // If this is the root node, we don't render
  7179. // a selector, or {}.
  7180. if (!this.root) {
  7181. debugInfo = getDebugInfo(context, this, tabSetStr);
  7182. if (debugInfo) {
  7183. output.add(debugInfo);
  7184. output.add(tabSetStr);
  7185. }
  7186. var paths = this.paths, pathCnt = paths.length,
  7187. pathSubCnt;
  7188. sep = context.compress ? ',' : (',\n' + tabSetStr);
  7189. for (i = 0; i < pathCnt; i++) {
  7190. path = paths[i];
  7191. if (!(pathSubCnt = path.length)) { continue; }
  7192. if (i > 0) { output.add(sep); }
  7193. context.firstSelector = true;
  7194. path[0].genCSS(context, output);
  7195. context.firstSelector = false;
  7196. for (j = 1; j < pathSubCnt; j++) {
  7197. path[j].genCSS(context, output);
  7198. }
  7199. }
  7200. output.add((context.compress ? '{' : ' {\n') + tabRuleStr);
  7201. }
  7202. // Compile rules and rulesets
  7203. for (i = 0; i < ruleNodes.length; i++) {
  7204. rule = ruleNodes[i];
  7205. if (i + 1 === ruleNodes.length) {
  7206. context.lastRule = true;
  7207. }
  7208. var currentLastRule = context.lastRule;
  7209. if (isRulesetLikeNode(rule)) {
  7210. context.lastRule = false;
  7211. }
  7212. if (rule.genCSS) {
  7213. rule.genCSS(context, output);
  7214. } else if (rule.value) {
  7215. output.add(rule.value.toString());
  7216. }
  7217. context.lastRule = currentLastRule;
  7218. if (!context.lastRule) {
  7219. output.add(context.compress ? '' : ('\n' + tabRuleStr));
  7220. } else {
  7221. context.lastRule = false;
  7222. }
  7223. }
  7224. if (!this.root) {
  7225. output.add((context.compress ? '}' : '\n' + tabSetStr + '}'));
  7226. context.tabLevel--;
  7227. }
  7228. if (!output.isEmpty() && !context.compress && this.firstRoot) {
  7229. output.add('\n');
  7230. }
  7231. };
  7232. Ruleset.prototype.joinSelectors = function (paths, context, selectors) {
  7233. for (var s = 0; s < selectors.length; s++) {
  7234. this.joinSelector(paths, context, selectors[s]);
  7235. }
  7236. };
  7237. Ruleset.prototype.joinSelector = function (paths, context, selector) {
  7238. function createParenthesis(elementsToPak, originalElement) {
  7239. var replacementParen, j;
  7240. if (elementsToPak.length === 0) {
  7241. replacementParen = new Paren(elementsToPak[0]);
  7242. } else {
  7243. var insideParent = [];
  7244. for (j = 0; j < elementsToPak.length; j++) {
  7245. insideParent.push(new Element(null, elementsToPak[j], originalElement.index, originalElement.currentFileInfo));
  7246. }
  7247. replacementParen = new Paren(new Selector(insideParent));
  7248. }
  7249. return replacementParen;
  7250. }
  7251. function createSelector(containedElement, originalElement) {
  7252. var element, selector;
  7253. element = new Element(null, containedElement, originalElement.index, originalElement.currentFileInfo);
  7254. selector = new Selector([element]);
  7255. return selector;
  7256. }
  7257. // joins selector path from `beginningPath` with selector path in `addPath`
  7258. // `replacedElement` contains element that is being replaced by `addPath`
  7259. // returns concatenated path
  7260. function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {
  7261. var newSelectorPath, lastSelector, newJoinedSelector;
  7262. // our new selector path
  7263. newSelectorPath = [];
  7264. //construct the joined selector - if & is the first thing this will be empty,
  7265. // if not newJoinedSelector will be the last set of elements in the selector
  7266. if (beginningPath.length > 0) {
  7267. newSelectorPath = beginningPath.slice(0);
  7268. lastSelector = newSelectorPath.pop();
  7269. newJoinedSelector = originalSelector.createDerived(lastSelector.elements.slice(0));
  7270. }
  7271. else {
  7272. newJoinedSelector = originalSelector.createDerived([]);
  7273. }
  7274. if (addPath.length > 0) {
  7275. // /deep/ is a combinator that is valid without anything in front of it
  7276. // so if the & does not have a combinator that is "" or " " then
  7277. // and there is a combinator on the parent, then grab that.
  7278. // this also allows + a { & .b { .a & { ... though not sure why you would want to do that
  7279. var combinator = replacedElement.combinator, parentEl = addPath[0].elements[0];
  7280. if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {
  7281. combinator = parentEl.combinator;
  7282. }
  7283. // join the elements so far with the first part of the parent
  7284. newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.index, replacedElement.currentFileInfo));
  7285. newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
  7286. }
  7287. // now add the joined selector - but only if it is not empty
  7288. if (newJoinedSelector.elements.length !== 0) {
  7289. newSelectorPath.push(newJoinedSelector);
  7290. }
  7291. //put together the parent selectors after the join (e.g. the rest of the parent)
  7292. if (addPath.length > 1) {
  7293. var restOfPath = addPath.slice(1);
  7294. restOfPath = restOfPath.map(function (selector) {
  7295. return selector.createDerived(selector.elements, []);
  7296. });
  7297. newSelectorPath = newSelectorPath.concat(restOfPath);
  7298. }
  7299. return newSelectorPath;
  7300. }
  7301. // joins selector path from `beginningPath` with every selector path in `addPaths` array
  7302. // `replacedElement` contains element that is being replaced by `addPath`
  7303. // returns array with all concatenated paths
  7304. function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {
  7305. var j;
  7306. for (j = 0; j < beginningPath.length; j++) {
  7307. var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);
  7308. result.push(newSelectorPath);
  7309. }
  7310. return result;
  7311. }
  7312. function mergeElementsOnToSelectors(elements, selectors) {
  7313. var i, sel;
  7314. if (elements.length === 0) {
  7315. return ;
  7316. }
  7317. if (selectors.length === 0) {
  7318. selectors.push([ new Selector(elements) ]);
  7319. return;
  7320. }
  7321. for (i = 0; i < selectors.length; i++) {
  7322. sel = selectors[i];
  7323. // if the previous thing in sel is a parent this needs to join on to it
  7324. if (sel.length > 0) {
  7325. sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));
  7326. }
  7327. else {
  7328. sel.push(new Selector(elements));
  7329. }
  7330. }
  7331. }
  7332. // replace all parent selectors inside `inSelector` by content of `context` array
  7333. // resulting selectors are returned inside `paths` array
  7334. // returns true if `inSelector` contained at least one parent selector
  7335. function replaceParentSelector(paths, context, inSelector) {
  7336. // The paths are [[Selector]]
  7337. // The first list is a list of comma separated selectors
  7338. // The inner list is a list of inheritance separated selectors
  7339. // e.g.
  7340. // .a, .b {
  7341. // .c {
  7342. // }
  7343. // }
  7344. // == [[.a] [.c]] [[.b] [.c]]
  7345. //
  7346. var i, j, k, currentElements, newSelectors, selectorsMultiplied, sel, el, hadParentSelector = false, length, lastSelector;
  7347. function findNestedSelector(element) {
  7348. var maybeSelector;
  7349. if (element.value.type !== 'Paren') {
  7350. return null;
  7351. }
  7352. maybeSelector = element.value.value;
  7353. if (maybeSelector.type !== 'Selector') {
  7354. return null;
  7355. }
  7356. return maybeSelector;
  7357. }
  7358. // the elements from the current selector so far
  7359. currentElements = [];
  7360. // the current list of new selectors to add to the path.
  7361. // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors
  7362. // by the parents
  7363. newSelectors = [
  7364. []
  7365. ];
  7366. for (i = 0; i < inSelector.elements.length; i++) {
  7367. el = inSelector.elements[i];
  7368. // non parent reference elements just get added
  7369. if (el.value !== "&") {
  7370. var nestedSelector = findNestedSelector(el);
  7371. if (nestedSelector != null) {
  7372. // merge the current list of non parent selector elements
  7373. // on to the current list of selectors to add
  7374. mergeElementsOnToSelectors(currentElements, newSelectors);
  7375. var nestedPaths = [], replaced, replacedNewSelectors = [];
  7376. replaced = replaceParentSelector(nestedPaths, context, nestedSelector);
  7377. hadParentSelector = hadParentSelector || replaced;
  7378. //the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors
  7379. for (k = 0; k < nestedPaths.length; k++) {
  7380. var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);
  7381. addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);
  7382. }
  7383. newSelectors = replacedNewSelectors;
  7384. currentElements = [];
  7385. } else {
  7386. currentElements.push(el);
  7387. }
  7388. } else {
  7389. hadParentSelector = true;
  7390. // the new list of selectors to add
  7391. selectorsMultiplied = [];
  7392. // merge the current list of non parent selector elements
  7393. // on to the current list of selectors to add
  7394. mergeElementsOnToSelectors(currentElements, newSelectors);
  7395. // loop through our current selectors
  7396. for (j = 0; j < newSelectors.length; j++) {
  7397. sel = newSelectors[j];
  7398. // if we don't have any parent paths, the & might be in a mixin so that it can be used
  7399. // whether there are parents or not
  7400. if (context.length === 0) {
  7401. // the combinator used on el should now be applied to the next element instead so that
  7402. // it is not lost
  7403. if (sel.length > 0) {
  7404. sel[0].elements.push(new Element(el.combinator, '', el.index, el.currentFileInfo));
  7405. }
  7406. selectorsMultiplied.push(sel);
  7407. }
  7408. else {
  7409. // and the parent selectors
  7410. for (k = 0; k < context.length; k++) {
  7411. // We need to put the current selectors
  7412. // then join the last selector's elements on to the parents selectors
  7413. var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);
  7414. // add that to our new set of selectors
  7415. selectorsMultiplied.push(newSelectorPath);
  7416. }
  7417. }
  7418. }
  7419. // our new selectors has been multiplied, so reset the state
  7420. newSelectors = selectorsMultiplied;
  7421. currentElements = [];
  7422. }
  7423. }
  7424. // if we have any elements left over (e.g. .a& .b == .b)
  7425. // add them on to all the current selectors
  7426. mergeElementsOnToSelectors(currentElements, newSelectors);
  7427. for (i = 0; i < newSelectors.length; i++) {
  7428. length = newSelectors[i].length;
  7429. if (length > 0) {
  7430. paths.push(newSelectors[i]);
  7431. lastSelector = newSelectors[i][length - 1];
  7432. newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);
  7433. //newSelectors[i][length - 1].copyVisibilityInfo(inSelector.visibilityInfo());
  7434. }
  7435. }
  7436. return hadParentSelector;
  7437. }
  7438. function deriveSelector(visibilityInfo, deriveFrom) {
  7439. var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);
  7440. newSelector.copyVisibilityInfo(visibilityInfo);
  7441. return newSelector;
  7442. }
  7443. // joinSelector code follows
  7444. var i, newPaths, hadParentSelector;
  7445. newPaths = [];
  7446. hadParentSelector = replaceParentSelector(newPaths, context, selector);
  7447. if (!hadParentSelector) {
  7448. if (context.length > 0) {
  7449. newPaths = [];
  7450. for (i = 0; i < context.length; i++) {
  7451. //var concatenated = [];
  7452. //context[i].forEach(function(entry) {
  7453. // var newEntry = entry.createDerived(entry.elements, entry.extendList, entry.evaldCondition);
  7454. // newEntry.copyVisibilityInfo(selector.visibilityInfo());
  7455. // concatenated.push(newEntry);
  7456. //}, this);
  7457. var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));
  7458. concatenated.push(selector);
  7459. newPaths.push(concatenated);
  7460. }
  7461. }
  7462. else {
  7463. newPaths = [[selector]];
  7464. }
  7465. }
  7466. for (i = 0; i < newPaths.length; i++) {
  7467. paths.push(newPaths[i]);
  7468. }
  7469. };
  7470. module.exports = Ruleset;
  7471. },{"../contexts":11,"../functions/default":20,"../functions/function-registry":22,"./debug-info":54,"./element":58,"./node":70,"./paren":72,"./rule":74,"./selector":77}],77:[function(require,module,exports){
  7472. var Node = require("./node"),
  7473. Element = require("./element");
  7474. var Selector = function (elements, extendList, condition, index, currentFileInfo, visibilityInfo) {
  7475. this.elements = elements;
  7476. this.extendList = extendList;
  7477. this.condition = condition;
  7478. this.currentFileInfo = currentFileInfo || {};
  7479. if (!condition) {
  7480. this.evaldCondition = true;
  7481. }
  7482. this.copyVisibilityInfo(visibilityInfo);
  7483. };
  7484. Selector.prototype = new Node();
  7485. Selector.prototype.type = "Selector";
  7486. Selector.prototype.accept = function (visitor) {
  7487. if (this.elements) {
  7488. this.elements = visitor.visitArray(this.elements);
  7489. }
  7490. if (this.extendList) {
  7491. this.extendList = visitor.visitArray(this.extendList);
  7492. }
  7493. if (this.condition) {
  7494. this.condition = visitor.visit(this.condition);
  7495. }
  7496. };
  7497. Selector.prototype.createDerived = function(elements, extendList, evaldCondition) {
  7498. var info = this.visibilityInfo();
  7499. evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;
  7500. var newSelector = new Selector(elements, extendList || this.extendList, null, this.index, this.currentFileInfo, info);
  7501. newSelector.evaldCondition = evaldCondition;
  7502. newSelector.mediaEmpty = this.mediaEmpty;
  7503. return newSelector;
  7504. };
  7505. Selector.prototype.createEmptySelectors = function() {
  7506. var el = new Element('', '&', this.index, this.currentFileInfo),
  7507. sels = [new Selector([el], null, null, this.index, this.currentFileInfo)];
  7508. sels[0].mediaEmpty = true;
  7509. return sels;
  7510. };
  7511. Selector.prototype.match = function (other) {
  7512. var elements = this.elements,
  7513. len = elements.length,
  7514. olen, i;
  7515. other.CacheElements();
  7516. olen = other._elements.length;
  7517. if (olen === 0 || len < olen) {
  7518. return 0;
  7519. } else {
  7520. for (i = 0; i < olen; i++) {
  7521. if (elements[i].value !== other._elements[i]) {
  7522. return 0;
  7523. }
  7524. }
  7525. }
  7526. return olen; // return number of matched elements
  7527. };
  7528. Selector.prototype.CacheElements = function() {
  7529. if (this._elements) {
  7530. return;
  7531. }
  7532. var elements = this.elements.map( function(v) {
  7533. return v.combinator.value + (v.value.value || v.value);
  7534. }).join("").match(/[,&#\*\.\w-]([\w-]|(\\.))*/g);
  7535. if (elements) {
  7536. if (elements[0] === "&") {
  7537. elements.shift();
  7538. }
  7539. } else {
  7540. elements = [];
  7541. }
  7542. this._elements = elements;
  7543. };
  7544. Selector.prototype.isJustParentSelector = function() {
  7545. return !this.mediaEmpty &&
  7546. this.elements.length === 1 &&
  7547. this.elements[0].value === '&' &&
  7548. (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');
  7549. };
  7550. Selector.prototype.eval = function (context) {
  7551. var evaldCondition = this.condition && this.condition.eval(context),
  7552. elements = this.elements, extendList = this.extendList;
  7553. elements = elements && elements.map(function (e) { return e.eval(context); });
  7554. extendList = extendList && extendList.map(function(extend) { return extend.eval(context); });
  7555. return this.createDerived(elements, extendList, evaldCondition);
  7556. };
  7557. Selector.prototype.genCSS = function (context, output) {
  7558. var i, element;
  7559. if ((!context || !context.firstSelector) && this.elements[0].combinator.value === "") {
  7560. output.add(' ', this.currentFileInfo, this.index);
  7561. }
  7562. if (!this._css) {
  7563. //TODO caching? speed comparison?
  7564. for (i = 0; i < this.elements.length; i++) {
  7565. element = this.elements[i];
  7566. element.genCSS(context, output);
  7567. }
  7568. }
  7569. };
  7570. Selector.prototype.getIsOutput = function() {
  7571. return this.evaldCondition;
  7572. };
  7573. module.exports = Selector;
  7574. },{"./element":58,"./node":70}],78:[function(require,module,exports){
  7575. var Node = require("./node");
  7576. var UnicodeDescriptor = function (value) {
  7577. this.value = value;
  7578. };
  7579. UnicodeDescriptor.prototype = new Node();
  7580. UnicodeDescriptor.prototype.type = "UnicodeDescriptor";
  7581. module.exports = UnicodeDescriptor;
  7582. },{"./node":70}],79:[function(require,module,exports){
  7583. var Node = require("./node"),
  7584. unitConversions = require("../data/unit-conversions");
  7585. var Unit = function (numerator, denominator, backupUnit) {
  7586. this.numerator = numerator ? numerator.slice(0).sort() : [];
  7587. this.denominator = denominator ? denominator.slice(0).sort() : [];
  7588. if (backupUnit) {
  7589. this.backupUnit = backupUnit;
  7590. } else if (numerator && numerator.length) {
  7591. this.backupUnit = numerator[0];
  7592. }
  7593. };
  7594. Unit.prototype = new Node();
  7595. Unit.prototype.type = "Unit";
  7596. Unit.prototype.clone = function () {
  7597. return new Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit);
  7598. };
  7599. Unit.prototype.genCSS = function (context, output) {
  7600. // Dimension checks the unit is singular and throws an error if in strict math mode.
  7601. var strictUnits = context && context.strictUnits;
  7602. if (this.numerator.length === 1) {
  7603. output.add(this.numerator[0]); // the ideal situation
  7604. } else if (!strictUnits && this.backupUnit) {
  7605. output.add(this.backupUnit);
  7606. } else if (!strictUnits && this.denominator.length) {
  7607. output.add(this.denominator[0]);
  7608. }
  7609. };
  7610. Unit.prototype.toString = function () {
  7611. var i, returnStr = this.numerator.join("*");
  7612. for (i = 0; i < this.denominator.length; i++) {
  7613. returnStr += "/" + this.denominator[i];
  7614. }
  7615. return returnStr;
  7616. };
  7617. Unit.prototype.compare = function (other) {
  7618. return this.is(other.toString()) ? 0 : undefined;
  7619. };
  7620. Unit.prototype.is = function (unitString) {
  7621. return this.toString().toUpperCase() === unitString.toUpperCase();
  7622. };
  7623. Unit.prototype.isLength = function () {
  7624. return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/));
  7625. };
  7626. Unit.prototype.isEmpty = function () {
  7627. return this.numerator.length === 0 && this.denominator.length === 0;
  7628. };
  7629. Unit.prototype.isSingular = function() {
  7630. return this.numerator.length <= 1 && this.denominator.length === 0;
  7631. };
  7632. Unit.prototype.map = function(callback) {
  7633. var i;
  7634. for (i = 0; i < this.numerator.length; i++) {
  7635. this.numerator[i] = callback(this.numerator[i], false);
  7636. }
  7637. for (i = 0; i < this.denominator.length; i++) {
  7638. this.denominator[i] = callback(this.denominator[i], true);
  7639. }
  7640. };
  7641. Unit.prototype.usedUnits = function() {
  7642. var group, result = {}, mapUnit, groupName;
  7643. mapUnit = function (atomicUnit) {
  7644. /*jshint loopfunc:true */
  7645. if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
  7646. result[groupName] = atomicUnit;
  7647. }
  7648. return atomicUnit;
  7649. };
  7650. for (groupName in unitConversions) {
  7651. if (unitConversions.hasOwnProperty(groupName)) {
  7652. group = unitConversions[groupName];
  7653. this.map(mapUnit);
  7654. }
  7655. }
  7656. return result;
  7657. };
  7658. Unit.prototype.cancel = function () {
  7659. var counter = {}, atomicUnit, i;
  7660. for (i = 0; i < this.numerator.length; i++) {
  7661. atomicUnit = this.numerator[i];
  7662. counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
  7663. }
  7664. for (i = 0; i < this.denominator.length; i++) {
  7665. atomicUnit = this.denominator[i];
  7666. counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
  7667. }
  7668. this.numerator = [];
  7669. this.denominator = [];
  7670. for (atomicUnit in counter) {
  7671. if (counter.hasOwnProperty(atomicUnit)) {
  7672. var count = counter[atomicUnit];
  7673. if (count > 0) {
  7674. for (i = 0; i < count; i++) {
  7675. this.numerator.push(atomicUnit);
  7676. }
  7677. } else if (count < 0) {
  7678. for (i = 0; i < -count; i++) {
  7679. this.denominator.push(atomicUnit);
  7680. }
  7681. }
  7682. }
  7683. }
  7684. this.numerator.sort();
  7685. this.denominator.sort();
  7686. };
  7687. module.exports = Unit;
  7688. },{"../data/unit-conversions":14,"./node":70}],80:[function(require,module,exports){
  7689. var Node = require("./node");
  7690. var URL = function (val, index, currentFileInfo, isEvald) {
  7691. this.value = val;
  7692. this.currentFileInfo = currentFileInfo;
  7693. this.index = index;
  7694. this.isEvald = isEvald;
  7695. };
  7696. URL.prototype = new Node();
  7697. URL.prototype.type = "Url";
  7698. URL.prototype.accept = function (visitor) {
  7699. this.value = visitor.visit(this.value);
  7700. };
  7701. URL.prototype.genCSS = function (context, output) {
  7702. output.add("url(");
  7703. this.value.genCSS(context, output);
  7704. output.add(")");
  7705. };
  7706. URL.prototype.eval = function (context) {
  7707. var val = this.value.eval(context),
  7708. rootpath;
  7709. if (!this.isEvald) {
  7710. // Add the base path if the URL is relative
  7711. rootpath = this.currentFileInfo && this.currentFileInfo.rootpath;
  7712. if (rootpath &&
  7713. typeof val.value === "string" &&
  7714. context.isPathRelative(val.value)) {
  7715. if (!val.quote) {
  7716. rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\" + match; });
  7717. }
  7718. val.value = rootpath + val.value;
  7719. }
  7720. val.value = context.normalizePath(val.value);
  7721. // Add url args if enabled
  7722. if (context.urlArgs) {
  7723. if (!val.value.match(/^\s*data:/)) {
  7724. var delimiter = val.value.indexOf('?') === -1 ? '?' : '&';
  7725. var urlArgs = delimiter + context.urlArgs;
  7726. if (val.value.indexOf('#') !== -1) {
  7727. val.value = val.value.replace('#', urlArgs + '#');
  7728. } else {
  7729. val.value += urlArgs;
  7730. }
  7731. }
  7732. }
  7733. }
  7734. return new URL(val, this.index, this.currentFileInfo, true);
  7735. };
  7736. module.exports = URL;
  7737. },{"./node":70}],81:[function(require,module,exports){
  7738. var Node = require("./node");
  7739. var Value = function (value) {
  7740. this.value = value;
  7741. if (!value) {
  7742. throw new Error("Value requires an array argument");
  7743. }
  7744. };
  7745. Value.prototype = new Node();
  7746. Value.prototype.type = "Value";
  7747. Value.prototype.accept = function (visitor) {
  7748. if (this.value) {
  7749. this.value = visitor.visitArray(this.value);
  7750. }
  7751. };
  7752. Value.prototype.eval = function (context) {
  7753. if (this.value.length === 1) {
  7754. return this.value[0].eval(context);
  7755. } else {
  7756. return new Value(this.value.map(function (v) {
  7757. return v.eval(context);
  7758. }));
  7759. }
  7760. };
  7761. Value.prototype.genCSS = function (context, output) {
  7762. var i;
  7763. for (i = 0; i < this.value.length; i++) {
  7764. this.value[i].genCSS(context, output);
  7765. if (i + 1 < this.value.length) {
  7766. output.add((context && context.compress) ? ',' : ', ');
  7767. }
  7768. }
  7769. };
  7770. module.exports = Value;
  7771. },{"./node":70}],82:[function(require,module,exports){
  7772. var Node = require("./node");
  7773. var Variable = function (name, index, currentFileInfo) {
  7774. this.name = name;
  7775. this.index = index;
  7776. this.currentFileInfo = currentFileInfo || {};
  7777. };
  7778. Variable.prototype = new Node();
  7779. Variable.prototype.type = "Variable";
  7780. Variable.prototype.eval = function (context) {
  7781. var variable, name = this.name;
  7782. if (name.indexOf('@@') === 0) {
  7783. name = '@' + new Variable(name.slice(1), this.index, this.currentFileInfo).eval(context).value;
  7784. }
  7785. if (this.evaluating) {
  7786. throw { type: 'Name',
  7787. message: "Recursive variable definition for " + name,
  7788. filename: this.currentFileInfo.filename,
  7789. index: this.index };
  7790. }
  7791. this.evaluating = true;
  7792. variable = this.find(context.frames, function (frame) {
  7793. var v = frame.variable(name);
  7794. if (v) {
  7795. if (v.important) {
  7796. var importantScope = context.importantScope[context.importantScope.length - 1];
  7797. importantScope.important = v.important;
  7798. }
  7799. return v.value.eval(context);
  7800. }
  7801. });
  7802. if (variable) {
  7803. this.evaluating = false;
  7804. return variable;
  7805. } else {
  7806. throw { type: 'Name',
  7807. message: "variable " + name + " is undefined",
  7808. filename: this.currentFileInfo.filename,
  7809. index: this.index };
  7810. }
  7811. };
  7812. Variable.prototype.find = function (obj, fun) {
  7813. for (var i = 0, r; i < obj.length; i++) {
  7814. r = fun.call(obj, obj[i]);
  7815. if (r) { return r; }
  7816. }
  7817. return null;
  7818. };
  7819. module.exports = Variable;
  7820. },{"./node":70}],83:[function(require,module,exports){
  7821. module.exports = {
  7822. getLocation: function(index, inputStream) {
  7823. var n = index + 1,
  7824. line = null,
  7825. column = -1;
  7826. while (--n >= 0 && inputStream.charAt(n) !== '\n') {
  7827. column++;
  7828. }
  7829. if (typeof index === 'number') {
  7830. line = (inputStream.slice(0, index).match(/\n/g) || "").length;
  7831. }
  7832. return {
  7833. line: line,
  7834. column: column
  7835. };
  7836. }
  7837. };
  7838. },{}],84:[function(require,module,exports){
  7839. var tree = require("../tree"),
  7840. Visitor = require("./visitor"),
  7841. logger = require("../logger");
  7842. /*jshint loopfunc:true */
  7843. var ExtendFinderVisitor = function() {
  7844. this._visitor = new Visitor(this);
  7845. this.contexts = [];
  7846. this.allExtendsStack = [[]];
  7847. };
  7848. ExtendFinderVisitor.prototype = {
  7849. run: function (root) {
  7850. root = this._visitor.visit(root);
  7851. root.allExtends = this.allExtendsStack[0];
  7852. return root;
  7853. },
  7854. visitRule: function (ruleNode, visitArgs) {
  7855. visitArgs.visitDeeper = false;
  7856. },
  7857. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  7858. visitArgs.visitDeeper = false;
  7859. },
  7860. visitRuleset: function (rulesetNode, visitArgs) {
  7861. if (rulesetNode.root) {
  7862. return;
  7863. }
  7864. var i, j, extend, allSelectorsExtendList = [], extendList;
  7865. // get &:extend(.a); rules which apply to all selectors in this ruleset
  7866. var rules = rulesetNode.rules, ruleCnt = rules ? rules.length : 0;
  7867. for (i = 0; i < ruleCnt; i++) {
  7868. if (rulesetNode.rules[i] instanceof tree.Extend) {
  7869. allSelectorsExtendList.push(rules[i]);
  7870. rulesetNode.extendOnEveryPath = true;
  7871. }
  7872. }
  7873. // now find every selector and apply the extends that apply to all extends
  7874. // and the ones which apply to an individual extend
  7875. var paths = rulesetNode.paths;
  7876. for (i = 0; i < paths.length; i++) {
  7877. var selectorPath = paths[i],
  7878. selector = selectorPath[selectorPath.length - 1],
  7879. selExtendList = selector.extendList;
  7880. extendList = selExtendList ? selExtendList.slice(0).concat(allSelectorsExtendList)
  7881. : allSelectorsExtendList;
  7882. if (extendList) {
  7883. extendList = extendList.map(function(allSelectorsExtend) {
  7884. return allSelectorsExtend.clone();
  7885. });
  7886. }
  7887. for (j = 0; j < extendList.length; j++) {
  7888. this.foundExtends = true;
  7889. extend = extendList[j];
  7890. extend.findSelfSelectors(selectorPath);
  7891. extend.ruleset = rulesetNode;
  7892. if (j === 0) { extend.firstExtendOnThisSelectorPath = true; }
  7893. this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);
  7894. }
  7895. }
  7896. this.contexts.push(rulesetNode.selectors);
  7897. },
  7898. visitRulesetOut: function (rulesetNode) {
  7899. if (!rulesetNode.root) {
  7900. this.contexts.length = this.contexts.length - 1;
  7901. }
  7902. },
  7903. visitMedia: function (mediaNode, visitArgs) {
  7904. mediaNode.allExtends = [];
  7905. this.allExtendsStack.push(mediaNode.allExtends);
  7906. },
  7907. visitMediaOut: function (mediaNode) {
  7908. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  7909. },
  7910. visitDirective: function (directiveNode, visitArgs) {
  7911. directiveNode.allExtends = [];
  7912. this.allExtendsStack.push(directiveNode.allExtends);
  7913. },
  7914. visitDirectiveOut: function (directiveNode) {
  7915. this.allExtendsStack.length = this.allExtendsStack.length - 1;
  7916. }
  7917. };
  7918. var ProcessExtendsVisitor = function() {
  7919. this._visitor = new Visitor(this);
  7920. };
  7921. ProcessExtendsVisitor.prototype = {
  7922. run: function(root) {
  7923. var extendFinder = new ExtendFinderVisitor();
  7924. this.extendIndices = {};
  7925. extendFinder.run(root);
  7926. if (!extendFinder.foundExtends) { return root; }
  7927. root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));
  7928. this.allExtendsStack = [root.allExtends];
  7929. var newRoot = this._visitor.visit(root);
  7930. this.checkExtendsForNonMatched(root.allExtends);
  7931. return newRoot;
  7932. },
  7933. checkExtendsForNonMatched: function(extendList) {
  7934. var indices = this.extendIndices;
  7935. extendList.filter(function(extend) {
  7936. return !extend.hasFoundMatches && extend.parent_ids.length == 1;
  7937. }).forEach(function(extend) {
  7938. var selector = "_unknown_";
  7939. try {
  7940. selector = extend.selector.toCSS({});
  7941. }
  7942. catch(_) {}
  7943. if (!indices[extend.index + ' ' + selector]) {
  7944. indices[extend.index + ' ' + selector] = true;
  7945. logger.warn("extend '" + selector + "' has no matches");
  7946. }
  7947. });
  7948. },
  7949. doExtendChaining: function (extendsList, extendsListTarget, iterationCount) {
  7950. //
  7951. // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering
  7952. // and pasting the selector we would do normally, but we are also adding an extend with the same target selector
  7953. // this means this new extend can then go and alter other extends
  7954. //
  7955. // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors
  7956. // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already
  7957. // processed if we look at each selector at a time, as is done in visitRuleset
  7958. var extendIndex, targetExtendIndex, matches, extendsToAdd = [], newSelector, extendVisitor = this, selectorPath,
  7959. extend, targetExtend, newExtend;
  7960. iterationCount = iterationCount || 0;
  7961. //loop through comparing every extend with every target extend.
  7962. // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
  7963. // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
  7964. // and the second is the target.
  7965. // the separation into two lists allows us to process a subset of chains with a bigger set, as is the
  7966. // case when processing media queries
  7967. for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {
  7968. for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {
  7969. extend = extendsList[extendIndex];
  7970. targetExtend = extendsListTarget[targetExtendIndex];
  7971. // look for circular references
  7972. if ( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ) { continue; }
  7973. // find a match in the target extends self selector (the bit before :extend)
  7974. selectorPath = [targetExtend.selfSelectors[0]];
  7975. matches = extendVisitor.findMatch(extend, selectorPath);
  7976. if (matches.length) {
  7977. extend.hasFoundMatches = true;
  7978. // we found a match, so for each self selector..
  7979. extend.selfSelectors.forEach(function(selfSelector) {
  7980. var info = targetExtend.visibilityInfo();
  7981. // process the extend as usual
  7982. newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());
  7983. // but now we create a new extend from it
  7984. newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.currentFileInfo, info);
  7985. newExtend.selfSelectors = newSelector;
  7986. // add the extend onto the list of extends for that selector
  7987. newSelector[newSelector.length - 1].extendList = [newExtend];
  7988. // record that we need to add it.
  7989. extendsToAdd.push(newExtend);
  7990. newExtend.ruleset = targetExtend.ruleset;
  7991. //remember its parents for circular references
  7992. newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);
  7993. // only process the selector once.. if we have :extend(.a,.b) then multiple
  7994. // extends will look at the same selector path, so when extending
  7995. // we know that any others will be duplicates in terms of what is added to the css
  7996. if (targetExtend.firstExtendOnThisSelectorPath) {
  7997. newExtend.firstExtendOnThisSelectorPath = true;
  7998. targetExtend.ruleset.paths.push(newSelector);
  7999. }
  8000. });
  8001. }
  8002. }
  8003. }
  8004. if (extendsToAdd.length) {
  8005. // try to detect circular references to stop a stack overflow.
  8006. // may no longer be needed.
  8007. this.extendChainCount++;
  8008. if (iterationCount > 100) {
  8009. var selectorOne = "{unable to calculate}";
  8010. var selectorTwo = "{unable to calculate}";
  8011. try {
  8012. selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
  8013. selectorTwo = extendsToAdd[0].selector.toCSS();
  8014. }
  8015. catch(e) {}
  8016. throw { message: "extend circular reference detected. One of the circular extends is currently:" +
  8017. selectorOne + ":extend(" + selectorTwo + ")"};
  8018. }
  8019. // now process the new extends on the existing rules so that we can handle a extending b extending c extending
  8020. // d extending e...
  8021. return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));
  8022. } else {
  8023. return extendsToAdd;
  8024. }
  8025. },
  8026. visitRule: function (ruleNode, visitArgs) {
  8027. visitArgs.visitDeeper = false;
  8028. },
  8029. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  8030. visitArgs.visitDeeper = false;
  8031. },
  8032. visitSelector: function (selectorNode, visitArgs) {
  8033. visitArgs.visitDeeper = false;
  8034. },
  8035. visitRuleset: function (rulesetNode, visitArgs) {
  8036. if (rulesetNode.root) {
  8037. return;
  8038. }
  8039. var matches, pathIndex, extendIndex, allExtends = this.allExtendsStack[this.allExtendsStack.length - 1],
  8040. selectorsToAdd = [], extendVisitor = this, selectorPath;
  8041. // look at each selector path in the ruleset, find any extend matches and then copy, find and replace
  8042. for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {
  8043. for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {
  8044. selectorPath = rulesetNode.paths[pathIndex];
  8045. // extending extends happens initially, before the main pass
  8046. if (rulesetNode.extendOnEveryPath) { continue; }
  8047. var extendList = selectorPath[selectorPath.length - 1].extendList;
  8048. if (extendList && extendList.length) { continue; }
  8049. matches = this.findMatch(allExtends[extendIndex], selectorPath);
  8050. if (matches.length) {
  8051. allExtends[extendIndex].hasFoundMatches = true;
  8052. allExtends[extendIndex].selfSelectors.forEach(function(selfSelector) {
  8053. var extendedSelectors;
  8054. extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());
  8055. selectorsToAdd.push(extendedSelectors);
  8056. });
  8057. }
  8058. }
  8059. }
  8060. rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);
  8061. },
  8062. findMatch: function (extend, haystackSelectorPath) {
  8063. //
  8064. // look through the haystack selector path to try and find the needle - extend.selector
  8065. // returns an array of selector matches that can then be replaced
  8066. //
  8067. var haystackSelectorIndex, hackstackSelector, hackstackElementIndex, haystackElement,
  8068. targetCombinator, i,
  8069. extendVisitor = this,
  8070. needleElements = extend.selector.elements,
  8071. potentialMatches = [], potentialMatch, matches = [];
  8072. // loop through the haystack elements
  8073. for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {
  8074. hackstackSelector = haystackSelectorPath[haystackSelectorIndex];
  8075. for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {
  8076. haystackElement = hackstackSelector.elements[hackstackElementIndex];
  8077. // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
  8078. if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {
  8079. potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,
  8080. initialCombinator: haystackElement.combinator});
  8081. }
  8082. for (i = 0; i < potentialMatches.length; i++) {
  8083. potentialMatch = potentialMatches[i];
  8084. // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
  8085. // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to
  8086. // work out what the resulting combinator will be
  8087. targetCombinator = haystackElement.combinator.value;
  8088. if (targetCombinator === '' && hackstackElementIndex === 0) {
  8089. targetCombinator = ' ';
  8090. }
  8091. // if we don't match, null our match to indicate failure
  8092. if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||
  8093. (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {
  8094. potentialMatch = null;
  8095. } else {
  8096. potentialMatch.matched++;
  8097. }
  8098. // if we are still valid and have finished, test whether we have elements after and whether these are allowed
  8099. if (potentialMatch) {
  8100. potentialMatch.finished = potentialMatch.matched === needleElements.length;
  8101. if (potentialMatch.finished &&
  8102. (!extend.allowAfter &&
  8103. (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {
  8104. potentialMatch = null;
  8105. }
  8106. }
  8107. // if null we remove, if not, we are still valid, so either push as a valid match or continue
  8108. if (potentialMatch) {
  8109. if (potentialMatch.finished) {
  8110. potentialMatch.length = needleElements.length;
  8111. potentialMatch.endPathIndex = haystackSelectorIndex;
  8112. potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match
  8113. potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again
  8114. matches.push(potentialMatch);
  8115. }
  8116. } else {
  8117. potentialMatches.splice(i, 1);
  8118. i--;
  8119. }
  8120. }
  8121. }
  8122. }
  8123. return matches;
  8124. },
  8125. isElementValuesEqual: function(elementValue1, elementValue2) {
  8126. if (typeof elementValue1 === "string" || typeof elementValue2 === "string") {
  8127. return elementValue1 === elementValue2;
  8128. }
  8129. if (elementValue1 instanceof tree.Attribute) {
  8130. if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {
  8131. return false;
  8132. }
  8133. if (!elementValue1.value || !elementValue2.value) {
  8134. if (elementValue1.value || elementValue2.value) {
  8135. return false;
  8136. }
  8137. return true;
  8138. }
  8139. elementValue1 = elementValue1.value.value || elementValue1.value;
  8140. elementValue2 = elementValue2.value.value || elementValue2.value;
  8141. return elementValue1 === elementValue2;
  8142. }
  8143. elementValue1 = elementValue1.value;
  8144. elementValue2 = elementValue2.value;
  8145. if (elementValue1 instanceof tree.Selector) {
  8146. if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {
  8147. return false;
  8148. }
  8149. for (var i = 0; i < elementValue1.elements.length; i++) {
  8150. if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) {
  8151. if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) {
  8152. return false;
  8153. }
  8154. }
  8155. if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) {
  8156. return false;
  8157. }
  8158. }
  8159. return true;
  8160. }
  8161. return false;
  8162. },
  8163. extendSelector:function (matches, selectorPath, replacementSelector, isVisible) {
  8164. //for a set of matches, replace each match with the replacement selector
  8165. var currentSelectorPathIndex = 0,
  8166. currentSelectorPathElementIndex = 0,
  8167. path = [],
  8168. matchIndex,
  8169. selector,
  8170. firstElement,
  8171. match,
  8172. newElements;
  8173. for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {
  8174. match = matches[matchIndex];
  8175. selector = selectorPath[match.pathIndex];
  8176. firstElement = new tree.Element(
  8177. match.initialCombinator,
  8178. replacementSelector.elements[0].value,
  8179. replacementSelector.elements[0].index,
  8180. replacementSelector.elements[0].currentFileInfo
  8181. );
  8182. if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {
  8183. path[path.length - 1].elements = path[path.length - 1]
  8184. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  8185. currentSelectorPathElementIndex = 0;
  8186. currentSelectorPathIndex++;
  8187. }
  8188. newElements = selector.elements
  8189. .slice(currentSelectorPathElementIndex, match.index)
  8190. .concat([firstElement])
  8191. .concat(replacementSelector.elements.slice(1));
  8192. if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {
  8193. path[path.length - 1].elements =
  8194. path[path.length - 1].elements.concat(newElements);
  8195. } else {
  8196. path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));
  8197. path.push(new tree.Selector(
  8198. newElements
  8199. ));
  8200. }
  8201. currentSelectorPathIndex = match.endPathIndex;
  8202. currentSelectorPathElementIndex = match.endPathElementIndex;
  8203. if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {
  8204. currentSelectorPathElementIndex = 0;
  8205. currentSelectorPathIndex++;
  8206. }
  8207. }
  8208. if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {
  8209. path[path.length - 1].elements = path[path.length - 1]
  8210. .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));
  8211. currentSelectorPathIndex++;
  8212. }
  8213. path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));
  8214. path = path.map(function (currentValue) {
  8215. // we can re-use elements here, because the visibility property matters only for selectors
  8216. var derived = currentValue.createDerived(currentValue.elements);
  8217. if (isVisible) {
  8218. derived.ensureVisibility();
  8219. } else {
  8220. derived.ensureInvisibility();
  8221. }
  8222. return derived;
  8223. });
  8224. return path;
  8225. },
  8226. visitMedia: function (mediaNode, visitArgs) {
  8227. var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  8228. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));
  8229. this.allExtendsStack.push(newAllExtends);
  8230. },
  8231. visitMediaOut: function (mediaNode) {
  8232. var lastIndex = this.allExtendsStack.length - 1;
  8233. this.allExtendsStack.length = lastIndex;
  8234. },
  8235. visitDirective: function (directiveNode, visitArgs) {
  8236. var newAllExtends = directiveNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);
  8237. newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, directiveNode.allExtends));
  8238. this.allExtendsStack.push(newAllExtends);
  8239. },
  8240. visitDirectiveOut: function (directiveNode) {
  8241. var lastIndex = this.allExtendsStack.length - 1;
  8242. this.allExtendsStack.length = lastIndex;
  8243. }
  8244. };
  8245. module.exports = ProcessExtendsVisitor;
  8246. },{"../logger":33,"../tree":62,"./visitor":91}],85:[function(require,module,exports){
  8247. function ImportSequencer(onSequencerEmpty) {
  8248. this.imports = [];
  8249. this.variableImports = [];
  8250. this._onSequencerEmpty = onSequencerEmpty;
  8251. this._currentDepth = 0;
  8252. }
  8253. ImportSequencer.prototype.addImport = function(callback) {
  8254. var importSequencer = this,
  8255. importItem = {
  8256. callback: callback,
  8257. args: null,
  8258. isReady: false
  8259. };
  8260. this.imports.push(importItem);
  8261. return function() {
  8262. importItem.args = Array.prototype.slice.call(arguments, 0);
  8263. importItem.isReady = true;
  8264. importSequencer.tryRun();
  8265. };
  8266. };
  8267. ImportSequencer.prototype.addVariableImport = function(callback) {
  8268. this.variableImports.push(callback);
  8269. };
  8270. ImportSequencer.prototype.tryRun = function() {
  8271. this._currentDepth++;
  8272. try {
  8273. while (true) {
  8274. while (this.imports.length > 0) {
  8275. var importItem = this.imports[0];
  8276. if (!importItem.isReady) {
  8277. return;
  8278. }
  8279. this.imports = this.imports.slice(1);
  8280. importItem.callback.apply(null, importItem.args);
  8281. }
  8282. if (this.variableImports.length === 0) {
  8283. break;
  8284. }
  8285. var variableImport = this.variableImports[0];
  8286. this.variableImports = this.variableImports.slice(1);
  8287. variableImport();
  8288. }
  8289. } finally {
  8290. this._currentDepth--;
  8291. }
  8292. if (this._currentDepth === 0 && this._onSequencerEmpty) {
  8293. this._onSequencerEmpty();
  8294. }
  8295. };
  8296. module.exports = ImportSequencer;
  8297. },{}],86:[function(require,module,exports){
  8298. var contexts = require("../contexts"),
  8299. Visitor = require("./visitor"),
  8300. ImportSequencer = require("./import-sequencer");
  8301. var ImportVisitor = function(importer, finish) {
  8302. this._visitor = new Visitor(this);
  8303. this._importer = importer;
  8304. this._finish = finish;
  8305. this.context = new contexts.Eval();
  8306. this.importCount = 0;
  8307. this.onceFileDetectionMap = {};
  8308. this.recursionDetector = {};
  8309. this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));
  8310. };
  8311. ImportVisitor.prototype = {
  8312. isReplacing: false,
  8313. run: function (root) {
  8314. try {
  8315. // process the contents
  8316. this._visitor.visit(root);
  8317. }
  8318. catch(e) {
  8319. this.error = e;
  8320. }
  8321. this.isFinished = true;
  8322. this._sequencer.tryRun();
  8323. },
  8324. _onSequencerEmpty: function() {
  8325. if (!this.isFinished) {
  8326. return;
  8327. }
  8328. this._finish(this.error);
  8329. },
  8330. visitImport: function (importNode, visitArgs) {
  8331. var inlineCSS = importNode.options.inline;
  8332. if (!importNode.css || inlineCSS) {
  8333. var context = new contexts.Eval(this.context, this.context.frames.slice(0));
  8334. var importParent = context.frames[0];
  8335. this.importCount++;
  8336. if (importNode.isVariableImport()) {
  8337. this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));
  8338. } else {
  8339. this.processImportNode(importNode, context, importParent);
  8340. }
  8341. }
  8342. visitArgs.visitDeeper = false;
  8343. },
  8344. processImportNode: function(importNode, context, importParent) {
  8345. var evaldImportNode,
  8346. inlineCSS = importNode.options.inline;
  8347. try {
  8348. evaldImportNode = importNode.evalForImport(context);
  8349. } catch(e) {
  8350. if (!e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; }
  8351. // attempt to eval properly and treat as css
  8352. importNode.css = true;
  8353. // if that fails, this error will be thrown
  8354. importNode.error = e;
  8355. }
  8356. if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {
  8357. if (evaldImportNode.options.multiple) {
  8358. context.importMultiple = true;
  8359. }
  8360. // try appending if we haven't determined if it is css or not
  8361. var tryAppendLessExtension = evaldImportNode.css === undefined;
  8362. for (var i = 0; i < importParent.rules.length; i++) {
  8363. if (importParent.rules[i] === importNode) {
  8364. importParent.rules[i] = evaldImportNode;
  8365. break;
  8366. }
  8367. }
  8368. var onImported = this.onImported.bind(this, evaldImportNode, context),
  8369. sequencedOnImported = this._sequencer.addImport(onImported);
  8370. this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.currentFileInfo,
  8371. evaldImportNode.options, sequencedOnImported);
  8372. } else {
  8373. this.importCount--;
  8374. if (this.isFinished) {
  8375. this._sequencer.tryRun();
  8376. }
  8377. }
  8378. },
  8379. onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {
  8380. if (e) {
  8381. if (!e.filename) {
  8382. e.index = importNode.index; e.filename = importNode.currentFileInfo.filename;
  8383. }
  8384. this.error = e;
  8385. }
  8386. var importVisitor = this,
  8387. inlineCSS = importNode.options.inline,
  8388. isPlugin = importNode.options.plugin,
  8389. isOptional = importNode.options.optional,
  8390. duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;
  8391. if (!context.importMultiple) {
  8392. if (duplicateImport) {
  8393. importNode.skip = true;
  8394. } else {
  8395. importNode.skip = function() {
  8396. if (fullPath in importVisitor.onceFileDetectionMap) {
  8397. return true;
  8398. }
  8399. importVisitor.onceFileDetectionMap[fullPath] = true;
  8400. return false;
  8401. };
  8402. }
  8403. }
  8404. if (!fullPath && isOptional) {
  8405. importNode.skip = true;
  8406. }
  8407. if (root) {
  8408. importNode.root = root;
  8409. importNode.importedFilename = fullPath;
  8410. if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {
  8411. importVisitor.recursionDetector[fullPath] = true;
  8412. var oldContext = this.context;
  8413. this.context = context;
  8414. try {
  8415. this._visitor.visit(root);
  8416. } catch (e) {
  8417. this.error = e;
  8418. }
  8419. this.context = oldContext;
  8420. }
  8421. }
  8422. importVisitor.importCount--;
  8423. if (importVisitor.isFinished) {
  8424. importVisitor._sequencer.tryRun();
  8425. }
  8426. },
  8427. visitRule: function (ruleNode, visitArgs) {
  8428. if (ruleNode.value.type === "DetachedRuleset") {
  8429. this.context.frames.unshift(ruleNode);
  8430. } else {
  8431. visitArgs.visitDeeper = false;
  8432. }
  8433. },
  8434. visitRuleOut : function(ruleNode) {
  8435. if (ruleNode.value.type === "DetachedRuleset") {
  8436. this.context.frames.shift();
  8437. }
  8438. },
  8439. visitDirective: function (directiveNode, visitArgs) {
  8440. this.context.frames.unshift(directiveNode);
  8441. },
  8442. visitDirectiveOut: function (directiveNode) {
  8443. this.context.frames.shift();
  8444. },
  8445. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  8446. this.context.frames.unshift(mixinDefinitionNode);
  8447. },
  8448. visitMixinDefinitionOut: function (mixinDefinitionNode) {
  8449. this.context.frames.shift();
  8450. },
  8451. visitRuleset: function (rulesetNode, visitArgs) {
  8452. this.context.frames.unshift(rulesetNode);
  8453. },
  8454. visitRulesetOut: function (rulesetNode) {
  8455. this.context.frames.shift();
  8456. },
  8457. visitMedia: function (mediaNode, visitArgs) {
  8458. this.context.frames.unshift(mediaNode.rules[0]);
  8459. },
  8460. visitMediaOut: function (mediaNode) {
  8461. this.context.frames.shift();
  8462. }
  8463. };
  8464. module.exports = ImportVisitor;
  8465. },{"../contexts":11,"./import-sequencer":85,"./visitor":91}],87:[function(require,module,exports){
  8466. var visitors = {
  8467. Visitor: require("./visitor"),
  8468. ImportVisitor: require('./import-visitor'),
  8469. MarkVisibleSelectorsVisitor: require("./set-tree-visibility-visitor"),
  8470. ExtendVisitor: require('./extend-visitor'),
  8471. JoinSelectorVisitor: require('./join-selector-visitor'),
  8472. ToCSSVisitor: require('./to-css-visitor')
  8473. };
  8474. module.exports = visitors;
  8475. },{"./extend-visitor":84,"./import-visitor":86,"./join-selector-visitor":88,"./set-tree-visibility-visitor":89,"./to-css-visitor":90,"./visitor":91}],88:[function(require,module,exports){
  8476. var Visitor = require("./visitor");
  8477. var JoinSelectorVisitor = function() {
  8478. this.contexts = [[]];
  8479. this._visitor = new Visitor(this);
  8480. };
  8481. JoinSelectorVisitor.prototype = {
  8482. run: function (root) {
  8483. return this._visitor.visit(root);
  8484. },
  8485. visitRule: function (ruleNode, visitArgs) {
  8486. visitArgs.visitDeeper = false;
  8487. },
  8488. visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {
  8489. visitArgs.visitDeeper = false;
  8490. },
  8491. visitRuleset: function (rulesetNode, visitArgs) {
  8492. var context = this.contexts[this.contexts.length - 1],
  8493. paths = [], selectors;
  8494. this.contexts.push(paths);
  8495. if (! rulesetNode.root) {
  8496. selectors = rulesetNode.selectors;
  8497. if (selectors) {
  8498. selectors = selectors.filter(function(selector) { return selector.getIsOutput(); });
  8499. rulesetNode.selectors = selectors.length ? selectors : (selectors = null);
  8500. if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); }
  8501. }
  8502. if (!selectors) { rulesetNode.rules = null; }
  8503. rulesetNode.paths = paths;
  8504. }
  8505. },
  8506. visitRulesetOut: function (rulesetNode) {
  8507. this.contexts.length = this.contexts.length - 1;
  8508. },
  8509. visitMedia: function (mediaNode, visitArgs) {
  8510. var context = this.contexts[this.contexts.length - 1];
  8511. mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);
  8512. },
  8513. visitDirective: function (directiveNode, visitArgs) {
  8514. var context = this.contexts[this.contexts.length - 1];
  8515. if (directiveNode.rules && directiveNode.rules.length) {
  8516. directiveNode.rules[0].root = (directiveNode.isRooted || context.length === 0 || null);
  8517. }
  8518. }
  8519. };
  8520. module.exports = JoinSelectorVisitor;
  8521. },{"./visitor":91}],89:[function(require,module,exports){
  8522. var SetTreeVisibilityVisitor = function(visible) {
  8523. this.visible = visible;
  8524. };
  8525. SetTreeVisibilityVisitor.prototype.run = function(root) {
  8526. this.visit(root);
  8527. };
  8528. SetTreeVisibilityVisitor.prototype.visitArray = function(nodes) {
  8529. if (!nodes) {
  8530. return nodes;
  8531. }
  8532. var cnt = nodes.length, i;
  8533. for (i = 0; i < cnt; i++) {
  8534. this.visit(nodes[i]);
  8535. }
  8536. return nodes;
  8537. };
  8538. SetTreeVisibilityVisitor.prototype.visit = function(node) {
  8539. if (!node) {
  8540. return node;
  8541. }
  8542. if (node.constructor === Array) {
  8543. return this.visitArray(node);
  8544. }
  8545. if (!node.blocksVisibility || node.blocksVisibility()) {
  8546. return node;
  8547. }
  8548. if (this.visible) {
  8549. node.ensureVisibility();
  8550. } else {
  8551. node.ensureInvisibility();
  8552. }
  8553. node.accept(this);
  8554. return node;
  8555. };
  8556. module.exports = SetTreeVisibilityVisitor;
  8557. },{}],90:[function(require,module,exports){
  8558. var tree = require("../tree"),
  8559. Visitor = require("./visitor");
  8560. var CSSVisitorUtils = function(context) {
  8561. this._visitor = new Visitor(this);
  8562. this._context = context;
  8563. };
  8564. CSSVisitorUtils.prototype = {
  8565. containsSilentNonBlockedChild: function(bodyRules) {
  8566. var rule;
  8567. if (bodyRules == null) {
  8568. return false;
  8569. }
  8570. for (var r = 0; r < bodyRules.length; r++) {
  8571. rule = bodyRules[r];
  8572. if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {
  8573. //the directive contains something that was referenced (likely by extend)
  8574. //therefore it needs to be shown in output too
  8575. return true;
  8576. }
  8577. }
  8578. return false;
  8579. },
  8580. keepOnlyVisibleChilds: function(owner) {
  8581. if (owner == null || owner.rules == null) {
  8582. return ;
  8583. }
  8584. owner.rules = owner.rules.filter(function(thing) {
  8585. return thing.isVisible();
  8586. }
  8587. );
  8588. },
  8589. isEmpty: function(owner) {
  8590. if (owner == null || owner.rules == null) {
  8591. return true;
  8592. }
  8593. return owner.rules.length === 0;
  8594. },
  8595. hasVisibleSelector: function(rulesetNode) {
  8596. if (rulesetNode == null || rulesetNode.paths == null) {
  8597. return false;
  8598. }
  8599. return rulesetNode.paths.length > 0;
  8600. },
  8601. resolveVisibility: function (node, originalRules) {
  8602. if (!node.blocksVisibility()) {
  8603. if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {
  8604. return ;
  8605. }
  8606. return node;
  8607. }
  8608. var compiledRulesBody = node.rules[0];
  8609. this.keepOnlyVisibleChilds(compiledRulesBody);
  8610. if (this.isEmpty(compiledRulesBody)) {
  8611. return ;
  8612. }
  8613. node.ensureVisibility();
  8614. node.removeVisibilityBlock();
  8615. return node;
  8616. },
  8617. isVisibleRuleset: function(rulesetNode) {
  8618. if (rulesetNode.firstRoot) {
  8619. return true;
  8620. }
  8621. if (this.isEmpty(rulesetNode)) {
  8622. return false;
  8623. }
  8624. if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {
  8625. return false;
  8626. }
  8627. return true;
  8628. }
  8629. };
  8630. var ToCSSVisitor = function(context) {
  8631. this._visitor = new Visitor(this);
  8632. this._context = context;
  8633. this.utils = new CSSVisitorUtils(context);
  8634. };
  8635. ToCSSVisitor.prototype = {
  8636. isReplacing: true,
  8637. run: function (root) {
  8638. return this._visitor.visit(root);
  8639. },
  8640. visitRule: function (ruleNode, visitArgs) {
  8641. if (ruleNode.blocksVisibility() || ruleNode.variable) {
  8642. return;
  8643. }
  8644. return ruleNode;
  8645. },
  8646. visitMixinDefinition: function (mixinNode, visitArgs) {
  8647. // mixin definitions do not get eval'd - this means they keep state
  8648. // so we have to clear that state here so it isn't used if toCSS is called twice
  8649. mixinNode.frames = [];
  8650. },
  8651. visitExtend: function (extendNode, visitArgs) {
  8652. },
  8653. visitComment: function (commentNode, visitArgs) {
  8654. if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {
  8655. return;
  8656. }
  8657. return commentNode;
  8658. },
  8659. visitMedia: function(mediaNode, visitArgs) {
  8660. var originalRules = mediaNode.rules[0].rules;
  8661. mediaNode.accept(this._visitor);
  8662. visitArgs.visitDeeper = false;
  8663. return this.utils.resolveVisibility(mediaNode, originalRules);
  8664. },
  8665. visitImport: function (importNode, visitArgs) {
  8666. if (importNode.blocksVisibility()) {
  8667. return ;
  8668. }
  8669. return importNode;
  8670. },
  8671. visitDirective: function(directiveNode, visitArgs) {
  8672. if (directiveNode.rules && directiveNode.rules.length) {
  8673. return this.visitDirectiveWithBody(directiveNode, visitArgs);
  8674. } else {
  8675. return this.visitDirectiveWithoutBody(directiveNode, visitArgs);
  8676. }
  8677. },
  8678. visitDirectiveWithBody: function(directiveNode, visitArgs) {
  8679. //if there is only one nested ruleset and that one has no path, then it is
  8680. //just fake ruleset
  8681. function hasFakeRuleset(directiveNode) {
  8682. var bodyRules = directiveNode.rules;
  8683. return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);
  8684. }
  8685. function getBodyRules(directiveNode) {
  8686. var nodeRules = directiveNode.rules;
  8687. if (hasFakeRuleset(directiveNode)) {
  8688. return nodeRules[0].rules;
  8689. }
  8690. return nodeRules;
  8691. }
  8692. //it is still true that it is only one ruleset in array
  8693. //this is last such moment
  8694. //process childs
  8695. var originalRules = getBodyRules(directiveNode);
  8696. directiveNode.accept(this._visitor);
  8697. visitArgs.visitDeeper = false;
  8698. if (!this.utils.isEmpty(directiveNode)) {
  8699. this._mergeRules(directiveNode.rules[0].rules);
  8700. }
  8701. return this.utils.resolveVisibility(directiveNode, originalRules);
  8702. },
  8703. visitDirectiveWithoutBody: function(directiveNode, visitArgs) {
  8704. if (directiveNode.blocksVisibility()) {
  8705. return;
  8706. }
  8707. if (directiveNode.name === "@charset") {
  8708. // Only output the debug info together with subsequent @charset definitions
  8709. // a comment (or @media statement) before the actual @charset directive would
  8710. // be considered illegal css as it has to be on the first line
  8711. if (this.charset) {
  8712. if (directiveNode.debugInfo) {
  8713. var comment = new tree.Comment("/* " + directiveNode.toCSS(this._context).replace(/\n/g, "") + " */\n");
  8714. comment.debugInfo = directiveNode.debugInfo;
  8715. return this._visitor.visit(comment);
  8716. }
  8717. return;
  8718. }
  8719. this.charset = true;
  8720. }
  8721. return directiveNode;
  8722. },
  8723. checkValidNodes: function(rules, isRoot) {
  8724. if (!rules) {
  8725. return;
  8726. }
  8727. for (var i = 0; i < rules.length; i++) {
  8728. var ruleNode = rules[i];
  8729. if (isRoot && ruleNode instanceof tree.Rule && !ruleNode.variable) {
  8730. throw { message: "Properties must be inside selector blocks. They cannot be in the root",
  8731. index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
  8732. }
  8733. if (ruleNode instanceof tree.Call) {
  8734. throw { message: "Function '" + ruleNode.name + "' is undefined",
  8735. index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
  8736. }
  8737. if (ruleNode.type && !ruleNode.allowRoot) {
  8738. throw { message: ruleNode.type + " node returned by a function is not valid here",
  8739. index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename};
  8740. }
  8741. }
  8742. },
  8743. visitRuleset: function (rulesetNode, visitArgs) {
  8744. //at this point rulesets are nested into each other
  8745. var rule, rulesets = [];
  8746. this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);
  8747. if (! rulesetNode.root) {
  8748. //remove invisible paths
  8749. this._compileRulesetPaths(rulesetNode);
  8750. // remove rulesets from this ruleset body and compile them separately
  8751. var nodeRules = rulesetNode.rules, nodeRuleCnt = nodeRules ? nodeRules.length : 0;
  8752. for (var i = 0; i < nodeRuleCnt; ) {
  8753. rule = nodeRules[i];
  8754. if (rule && rule.rules) {
  8755. // visit because we are moving them out from being a child
  8756. rulesets.push(this._visitor.visit(rule));
  8757. nodeRules.splice(i, 1);
  8758. nodeRuleCnt--;
  8759. continue;
  8760. }
  8761. i++;
  8762. }
  8763. // accept the visitor to remove rules and refactor itself
  8764. // then we can decide nogw whether we want it or not
  8765. // compile body
  8766. if (nodeRuleCnt > 0) {
  8767. rulesetNode.accept(this._visitor);
  8768. } else {
  8769. rulesetNode.rules = null;
  8770. }
  8771. visitArgs.visitDeeper = false;
  8772. } else { //if (! rulesetNode.root) {
  8773. rulesetNode.accept(this._visitor);
  8774. visitArgs.visitDeeper = false;
  8775. }
  8776. if (rulesetNode.rules) {
  8777. this._mergeRules(rulesetNode.rules);
  8778. this._removeDuplicateRules(rulesetNode.rules);
  8779. }
  8780. //now decide whether we keep the ruleset
  8781. if (this.utils.isVisibleRuleset(rulesetNode)) {
  8782. rulesetNode.ensureVisibility();
  8783. rulesets.splice(0, 0, rulesetNode);
  8784. }
  8785. if (rulesets.length === 1) {
  8786. return rulesets[0];
  8787. }
  8788. return rulesets;
  8789. },
  8790. _compileRulesetPaths: function(rulesetNode) {
  8791. if (rulesetNode.paths) {
  8792. rulesetNode.paths = rulesetNode.paths
  8793. .filter(function(p) {
  8794. var i;
  8795. if (p[0].elements[0].combinator.value === ' ') {
  8796. p[0].elements[0].combinator = new(tree.Combinator)('');
  8797. }
  8798. for (i = 0; i < p.length; i++) {
  8799. if (p[i].isVisible() && p[i].getIsOutput()) {
  8800. return true;
  8801. }
  8802. }
  8803. return false;
  8804. });
  8805. }
  8806. },
  8807. _removeDuplicateRules: function(rules) {
  8808. if (!rules) { return; }
  8809. // remove duplicates
  8810. var ruleCache = {},
  8811. ruleList, rule, i;
  8812. for (i = rules.length - 1; i >= 0 ; i--) {
  8813. rule = rules[i];
  8814. if (rule instanceof tree.Rule) {
  8815. if (!ruleCache[rule.name]) {
  8816. ruleCache[rule.name] = rule;
  8817. } else {
  8818. ruleList = ruleCache[rule.name];
  8819. if (ruleList instanceof tree.Rule) {
  8820. ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];
  8821. }
  8822. var ruleCSS = rule.toCSS(this._context);
  8823. if (ruleList.indexOf(ruleCSS) !== -1) {
  8824. rules.splice(i, 1);
  8825. } else {
  8826. ruleList.push(ruleCSS);
  8827. }
  8828. }
  8829. }
  8830. }
  8831. },
  8832. _mergeRules: function (rules) {
  8833. if (!rules) { return; }
  8834. var groups = {},
  8835. parts,
  8836. rule,
  8837. key;
  8838. for (var i = 0; i < rules.length; i++) {
  8839. rule = rules[i];
  8840. if ((rule instanceof tree.Rule) && rule.merge) {
  8841. key = [rule.name,
  8842. rule.important ? "!" : ""].join(",");
  8843. if (!groups[key]) {
  8844. groups[key] = [];
  8845. } else {
  8846. rules.splice(i--, 1);
  8847. }
  8848. groups[key].push(rule);
  8849. }
  8850. }
  8851. Object.keys(groups).map(function (k) {
  8852. function toExpression(values) {
  8853. return new (tree.Expression)(values.map(function (p) {
  8854. return p.value;
  8855. }));
  8856. }
  8857. function toValue(values) {
  8858. return new (tree.Value)(values.map(function (p) {
  8859. return p;
  8860. }));
  8861. }
  8862. parts = groups[k];
  8863. if (parts.length > 1) {
  8864. rule = parts[0];
  8865. var spacedGroups = [];
  8866. var lastSpacedGroup = [];
  8867. parts.map(function (p) {
  8868. if (p.merge === "+") {
  8869. if (lastSpacedGroup.length > 0) {
  8870. spacedGroups.push(toExpression(lastSpacedGroup));
  8871. }
  8872. lastSpacedGroup = [];
  8873. }
  8874. lastSpacedGroup.push(p);
  8875. });
  8876. spacedGroups.push(toExpression(lastSpacedGroup));
  8877. rule.value = toValue(spacedGroups);
  8878. }
  8879. });
  8880. },
  8881. visitAnonymous: function(anonymousNode, visitArgs) {
  8882. if (anonymousNode.blocksVisibility()) {
  8883. return ;
  8884. }
  8885. anonymousNode.accept(this._visitor);
  8886. return anonymousNode;
  8887. }
  8888. };
  8889. module.exports = ToCSSVisitor;
  8890. },{"../tree":62,"./visitor":91}],91:[function(require,module,exports){
  8891. var tree = require("../tree");
  8892. var _visitArgs = { visitDeeper: true },
  8893. _hasIndexed = false;
  8894. function _noop(node) {
  8895. return node;
  8896. }
  8897. function indexNodeTypes(parent, ticker) {
  8898. // add .typeIndex to tree node types for lookup table
  8899. var key, child;
  8900. for (key in parent) {
  8901. if (parent.hasOwnProperty(key)) {
  8902. child = parent[key];
  8903. switch (typeof child) {
  8904. case "function":
  8905. // ignore bound functions directly on tree which do not have a prototype
  8906. // or aren't nodes
  8907. if (child.prototype && child.prototype.type) {
  8908. child.prototype.typeIndex = ticker++;
  8909. }
  8910. break;
  8911. case "object":
  8912. ticker = indexNodeTypes(child, ticker);
  8913. break;
  8914. }
  8915. }
  8916. }
  8917. return ticker;
  8918. }
  8919. var Visitor = function(implementation) {
  8920. this._implementation = implementation;
  8921. this._visitFnCache = [];
  8922. if (!_hasIndexed) {
  8923. indexNodeTypes(tree, 1);
  8924. _hasIndexed = true;
  8925. }
  8926. };
  8927. Visitor.prototype = {
  8928. visit: function(node) {
  8929. if (!node) {
  8930. return node;
  8931. }
  8932. var nodeTypeIndex = node.typeIndex;
  8933. if (!nodeTypeIndex) {
  8934. return node;
  8935. }
  8936. var visitFnCache = this._visitFnCache,
  8937. impl = this._implementation,
  8938. aryIndx = nodeTypeIndex << 1,
  8939. outAryIndex = aryIndx | 1,
  8940. func = visitFnCache[aryIndx],
  8941. funcOut = visitFnCache[outAryIndex],
  8942. visitArgs = _visitArgs,
  8943. fnName;
  8944. visitArgs.visitDeeper = true;
  8945. if (!func) {
  8946. fnName = "visit" + node.type;
  8947. func = impl[fnName] || _noop;
  8948. funcOut = impl[fnName + "Out"] || _noop;
  8949. visitFnCache[aryIndx] = func;
  8950. visitFnCache[outAryIndex] = funcOut;
  8951. }
  8952. if (func !== _noop) {
  8953. var newNode = func.call(impl, node, visitArgs);
  8954. if (impl.isReplacing) {
  8955. node = newNode;
  8956. }
  8957. }
  8958. if (visitArgs.visitDeeper && node && node.accept) {
  8959. node.accept(this);
  8960. }
  8961. if (funcOut != _noop) {
  8962. funcOut.call(impl, node);
  8963. }
  8964. return node;
  8965. },
  8966. visitArray: function(nodes, nonReplacing) {
  8967. if (!nodes) {
  8968. return nodes;
  8969. }
  8970. var cnt = nodes.length, i;
  8971. // Non-replacing
  8972. if (nonReplacing || !this._implementation.isReplacing) {
  8973. for (i = 0; i < cnt; i++) {
  8974. this.visit(nodes[i]);
  8975. }
  8976. return nodes;
  8977. }
  8978. // Replacing
  8979. var out = [];
  8980. for (i = 0; i < cnt; i++) {
  8981. var evald = this.visit(nodes[i]);
  8982. if (evald === undefined) { continue; }
  8983. if (!evald.splice) {
  8984. out.push(evald);
  8985. } else if (evald.length) {
  8986. this.flatten(evald, out);
  8987. }
  8988. }
  8989. return out;
  8990. },
  8991. flatten: function(arr, out) {
  8992. if (!out) {
  8993. out = [];
  8994. }
  8995. var cnt, i, item,
  8996. nestedCnt, j, nestedItem;
  8997. for (i = 0, cnt = arr.length; i < cnt; i++) {
  8998. item = arr[i];
  8999. if (item === undefined) {
  9000. continue;
  9001. }
  9002. if (!item.splice) {
  9003. out.push(item);
  9004. continue;
  9005. }
  9006. for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {
  9007. nestedItem = item[j];
  9008. if (nestedItem === undefined) {
  9009. continue;
  9010. }
  9011. if (!nestedItem.splice) {
  9012. out.push(nestedItem);
  9013. } else if (nestedItem.length) {
  9014. this.flatten(nestedItem, out);
  9015. }
  9016. }
  9017. }
  9018. return out;
  9019. }
  9020. };
  9021. module.exports = Visitor;
  9022. },{"../tree":62}],92:[function(require,module,exports){
  9023. "use strict";
  9024. // rawAsap provides everything we need except exception management.
  9025. var rawAsap = require("./raw");
  9026. // RawTasks are recycled to reduce GC churn.
  9027. var freeTasks = [];
  9028. // We queue errors to ensure they are thrown in right order (FIFO).
  9029. // Array-as-queue is good enough here, since we are just dealing with exceptions.
  9030. var pendingErrors = [];
  9031. var requestErrorThrow = rawAsap.makeRequestCallFromTimer(throwFirstError);
  9032. function throwFirstError() {
  9033. if (pendingErrors.length) {
  9034. throw pendingErrors.shift();
  9035. }
  9036. }
  9037. /**
  9038. * Calls a task as soon as possible after returning, in its own event, with priority
  9039. * over other events like animation, reflow, and repaint. An error thrown from an
  9040. * event will not interrupt, nor even substantially slow down the processing of
  9041. * other events, but will be rather postponed to a lower priority event.
  9042. * @param {{call}} task A callable object, typically a function that takes no
  9043. * arguments.
  9044. */
  9045. module.exports = asap;
  9046. function asap(task) {
  9047. var rawTask;
  9048. if (freeTasks.length) {
  9049. rawTask = freeTasks.pop();
  9050. } else {
  9051. rawTask = new RawTask();
  9052. }
  9053. rawTask.task = task;
  9054. rawAsap(rawTask);
  9055. }
  9056. // We wrap tasks with recyclable task objects. A task object implements
  9057. // `call`, just like a function.
  9058. function RawTask() {
  9059. this.task = null;
  9060. }
  9061. // The sole purpose of wrapping the task is to catch the exception and recycle
  9062. // the task object after its single use.
  9063. RawTask.prototype.call = function () {
  9064. try {
  9065. this.task.call();
  9066. } catch (error) {
  9067. if (asap.onerror) {
  9068. // This hook exists purely for testing purposes.
  9069. // Its name will be periodically randomized to break any code that
  9070. // depends on its existence.
  9071. asap.onerror(error);
  9072. } else {
  9073. // In a web browser, exceptions are not fatal. However, to avoid
  9074. // slowing down the queue of pending tasks, we rethrow the error in a
  9075. // lower priority turn.
  9076. pendingErrors.push(error);
  9077. requestErrorThrow();
  9078. }
  9079. } finally {
  9080. this.task = null;
  9081. freeTasks[freeTasks.length] = this;
  9082. }
  9083. };
  9084. },{"./raw":93}],93:[function(require,module,exports){
  9085. (function (global){
  9086. "use strict";
  9087. // Use the fastest means possible to execute a task in its own turn, with
  9088. // priority over other events including IO, animation, reflow, and redraw
  9089. // events in browsers.
  9090. //
  9091. // An exception thrown by a task will permanently interrupt the processing of
  9092. // subsequent tasks. The higher level `asap` function ensures that if an
  9093. // exception is thrown by a task, that the task queue will continue flushing as
  9094. // soon as possible, but if you use `rawAsap` directly, you are responsible to
  9095. // either ensure that no exceptions are thrown from your task, or to manually
  9096. // call `rawAsap.requestFlush` if an exception is thrown.
  9097. module.exports = rawAsap;
  9098. function rawAsap(task) {
  9099. if (!queue.length) {
  9100. requestFlush();
  9101. flushing = true;
  9102. }
  9103. // Equivalent to push, but avoids a function call.
  9104. queue[queue.length] = task;
  9105. }
  9106. var queue = [];
  9107. // Once a flush has been requested, no further calls to `requestFlush` are
  9108. // necessary until the next `flush` completes.
  9109. var flushing = false;
  9110. // `requestFlush` is an implementation-specific method that attempts to kick
  9111. // off a `flush` event as quickly as possible. `flush` will attempt to exhaust
  9112. // the event queue before yielding to the browser's own event loop.
  9113. var requestFlush;
  9114. // The position of the next task to execute in the task queue. This is
  9115. // preserved between calls to `flush` so that it can be resumed if
  9116. // a task throws an exception.
  9117. var index = 0;
  9118. // If a task schedules additional tasks recursively, the task queue can grow
  9119. // unbounded. To prevent memory exhaustion, the task queue will periodically
  9120. // truncate already-completed tasks.
  9121. var capacity = 1024;
  9122. // The flush function processes all tasks that have been scheduled with
  9123. // `rawAsap` unless and until one of those tasks throws an exception.
  9124. // If a task throws an exception, `flush` ensures that its state will remain
  9125. // consistent and will resume where it left off when called again.
  9126. // However, `flush` does not make any arrangements to be called again if an
  9127. // exception is thrown.
  9128. function flush() {
  9129. while (index < queue.length) {
  9130. var currentIndex = index;
  9131. // Advance the index before calling the task. This ensures that we will
  9132. // begin flushing on the next task the task throws an error.
  9133. index = index + 1;
  9134. queue[currentIndex].call();
  9135. // Prevent leaking memory for long chains of recursive calls to `asap`.
  9136. // If we call `asap` within tasks scheduled by `asap`, the queue will
  9137. // grow, but to avoid an O(n) walk for every task we execute, we don't
  9138. // shift tasks off the queue after they have been executed.
  9139. // Instead, we periodically shift 1024 tasks off the queue.
  9140. if (index > capacity) {
  9141. // Manually shift all values starting at the index back to the
  9142. // beginning of the queue.
  9143. for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
  9144. queue[scan] = queue[scan + index];
  9145. }
  9146. queue.length -= index;
  9147. index = 0;
  9148. }
  9149. }
  9150. queue.length = 0;
  9151. index = 0;
  9152. flushing = false;
  9153. }
  9154. // `requestFlush` is implemented using a strategy based on data collected from
  9155. // every available SauceLabs Selenium web driver worker at time of writing.
  9156. // https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
  9157. // Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
  9158. // have WebKitMutationObserver but not un-prefixed MutationObserver.
  9159. // Must use `global` or `self` instead of `window` to work in both frames and web
  9160. // workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
  9161. /* globals self */
  9162. var scope = typeof global !== "undefined" ? global : self;
  9163. var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
  9164. // MutationObservers are desirable because they have high priority and work
  9165. // reliably everywhere they are implemented.
  9166. // They are implemented in all modern browsers.
  9167. //
  9168. // - Android 4-4.3
  9169. // - Chrome 26-34
  9170. // - Firefox 14-29
  9171. // - Internet Explorer 11
  9172. // - iPad Safari 6-7.1
  9173. // - iPhone Safari 7-7.1
  9174. // - Safari 6-7
  9175. if (typeof BrowserMutationObserver === "function") {
  9176. requestFlush = makeRequestCallFromMutationObserver(flush);
  9177. // MessageChannels are desirable because they give direct access to the HTML
  9178. // task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
  9179. // 11-12, and in web workers in many engines.
  9180. // Although message channels yield to any queued rendering and IO tasks, they
  9181. // would be better than imposing the 4ms delay of timers.
  9182. // However, they do not work reliably in Internet Explorer or Safari.
  9183. // Internet Explorer 10 is the only browser that has setImmediate but does
  9184. // not have MutationObservers.
  9185. // Although setImmediate yields to the browser's renderer, it would be
  9186. // preferrable to falling back to setTimeout since it does not have
  9187. // the minimum 4ms penalty.
  9188. // Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
  9189. // Desktop to a lesser extent) that renders both setImmediate and
  9190. // MessageChannel useless for the purposes of ASAP.
  9191. // https://github.com/kriskowal/q/issues/396
  9192. // Timers are implemented universally.
  9193. // We fall back to timers in workers in most engines, and in foreground
  9194. // contexts in the following browsers.
  9195. // However, note that even this simple case requires nuances to operate in a
  9196. // broad spectrum of browsers.
  9197. //
  9198. // - Firefox 3-13
  9199. // - Internet Explorer 6-9
  9200. // - iPad Safari 4.3
  9201. // - Lynx 2.8.7
  9202. } else {
  9203. requestFlush = makeRequestCallFromTimer(flush);
  9204. }
  9205. // `requestFlush` requests that the high priority event queue be flushed as
  9206. // soon as possible.
  9207. // This is useful to prevent an error thrown in a task from stalling the event
  9208. // queue if the exception handled by Node.js’s
  9209. // `process.on("uncaughtException")` or by a domain.
  9210. rawAsap.requestFlush = requestFlush;
  9211. // To request a high priority event, we induce a mutation observer by toggling
  9212. // the text of a text node between "1" and "-1".
  9213. function makeRequestCallFromMutationObserver(callback) {
  9214. var toggle = 1;
  9215. var observer = new BrowserMutationObserver(callback);
  9216. var node = document.createTextNode("");
  9217. observer.observe(node, {characterData: true});
  9218. return function requestCall() {
  9219. toggle = -toggle;
  9220. node.data = toggle;
  9221. };
  9222. }
  9223. // The message channel technique was discovered by Malte Ubl and was the
  9224. // original foundation for this library.
  9225. // http://www.nonblocking.io/2011/06/windownexttick.html
  9226. // Safari 6.0.5 (at least) intermittently fails to create message ports on a
  9227. // page's first load. Thankfully, this version of Safari supports
  9228. // MutationObservers, so we don't need to fall back in that case.
  9229. // function makeRequestCallFromMessageChannel(callback) {
  9230. // var channel = new MessageChannel();
  9231. // channel.port1.onmessage = callback;
  9232. // return function requestCall() {
  9233. // channel.port2.postMessage(0);
  9234. // };
  9235. // }
  9236. // For reasons explained above, we are also unable to use `setImmediate`
  9237. // under any circumstances.
  9238. // Even if we were, there is another bug in Internet Explorer 10.
  9239. // It is not sufficient to assign `setImmediate` to `requestFlush` because
  9240. // `setImmediate` must be called *by name* and therefore must be wrapped in a
  9241. // closure.
  9242. // Never forget.
  9243. // function makeRequestCallFromSetImmediate(callback) {
  9244. // return function requestCall() {
  9245. // setImmediate(callback);
  9246. // };
  9247. // }
  9248. // Safari 6.0 has a problem where timers will get lost while the user is
  9249. // scrolling. This problem does not impact ASAP because Safari 6.0 supports
  9250. // mutation observers, so that implementation is used instead.
  9251. // However, if we ever elect to use timers in Safari, the prevalent work-around
  9252. // is to add a scroll event listener that calls for a flush.
  9253. // `setTimeout` does not call the passed callback if the delay is less than
  9254. // approximately 7 in web workers in Firefox 8 through 18, and sometimes not
  9255. // even then.
  9256. function makeRequestCallFromTimer(callback) {
  9257. return function requestCall() {
  9258. // We dispatch a timeout with a specified delay of 0 for engines that
  9259. // can reliably accommodate that request. This will usually be snapped
  9260. // to a 4 milisecond delay, but once we're flushing, there's no delay
  9261. // between events.
  9262. var timeoutHandle = setTimeout(handleTimer, 0);
  9263. // However, since this timer gets frequently dropped in Firefox
  9264. // workers, we enlist an interval handle that will try to fire
  9265. // an event 20 times per second until it succeeds.
  9266. var intervalHandle = setInterval(handleTimer, 50);
  9267. function handleTimer() {
  9268. // Whichever timer succeeds will cancel both timers and
  9269. // execute the callback.
  9270. clearTimeout(timeoutHandle);
  9271. clearInterval(intervalHandle);
  9272. callback();
  9273. }
  9274. };
  9275. }
  9276. // This is for `asap.js` only.
  9277. // Its name will be periodically randomized to break any code that depends on
  9278. // its existence.
  9279. rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
  9280. // ASAP was originally a nextTick shim included in Q. This was factored out
  9281. // into this ASAP package. It was later adapted to RSVP which made further
  9282. // amendments. These decisions, particularly to marginalize MessageChannel and
  9283. // to capture the MutationObserver implementation in a closure, were integrated
  9284. // back into ASAP proper.
  9285. // https://github.com/tildeio/rsvp.js/blob/cddf7232546a9cf858524b75cde6f9edf72620a7/lib/rsvp/asap.js
  9286. }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  9287. },{}],94:[function(require,module,exports){
  9288. 'use strict';
  9289. var asap = require('asap/raw');
  9290. function noop() {}
  9291. // States:
  9292. //
  9293. // 0 - pending
  9294. // 1 - fulfilled with _value
  9295. // 2 - rejected with _value
  9296. // 3 - adopted the state of another promise, _value
  9297. //
  9298. // once the state is no longer pending (0) it is immutable
  9299. // All `_` prefixed properties will be reduced to `_{random number}`
  9300. // at build time to obfuscate them and discourage their use.
  9301. // We don't use symbols or Object.defineProperty to fully hide them
  9302. // because the performance isn't good enough.
  9303. // to avoid using try/catch inside critical functions, we
  9304. // extract them to here.
  9305. var LAST_ERROR = null;
  9306. var IS_ERROR = {};
  9307. function getThen(obj) {
  9308. try {
  9309. return obj.then;
  9310. } catch (ex) {
  9311. LAST_ERROR = ex;
  9312. return IS_ERROR;
  9313. }
  9314. }
  9315. function tryCallOne(fn, a) {
  9316. try {
  9317. return fn(a);
  9318. } catch (ex) {
  9319. LAST_ERROR = ex;
  9320. return IS_ERROR;
  9321. }
  9322. }
  9323. function tryCallTwo(fn, a, b) {
  9324. try {
  9325. fn(a, b);
  9326. } catch (ex) {
  9327. LAST_ERROR = ex;
  9328. return IS_ERROR;
  9329. }
  9330. }
  9331. module.exports = Promise;
  9332. function Promise(fn) {
  9333. if (typeof this !== 'object') {
  9334. throw new TypeError('Promises must be constructed via new');
  9335. }
  9336. if (typeof fn !== 'function') {
  9337. throw new TypeError('Promise constructor\'s argument is not a function');
  9338. }
  9339. this._40 = 0;
  9340. this._65 = 0;
  9341. this._55 = null;
  9342. this._72 = null;
  9343. if (fn === noop) return;
  9344. doResolve(fn, this);
  9345. }
  9346. Promise._37 = null;
  9347. Promise._87 = null;
  9348. Promise._61 = noop;
  9349. Promise.prototype.then = function(onFulfilled, onRejected) {
  9350. if (this.constructor !== Promise) {
  9351. return safeThen(this, onFulfilled, onRejected);
  9352. }
  9353. var res = new Promise(noop);
  9354. handle(this, new Handler(onFulfilled, onRejected, res));
  9355. return res;
  9356. };
  9357. function safeThen(self, onFulfilled, onRejected) {
  9358. return new self.constructor(function (resolve, reject) {
  9359. var res = new Promise(noop);
  9360. res.then(resolve, reject);
  9361. handle(self, new Handler(onFulfilled, onRejected, res));
  9362. });
  9363. }
  9364. function handle(self, deferred) {
  9365. while (self._65 === 3) {
  9366. self = self._55;
  9367. }
  9368. if (Promise._37) {
  9369. Promise._37(self);
  9370. }
  9371. if (self._65 === 0) {
  9372. if (self._40 === 0) {
  9373. self._40 = 1;
  9374. self._72 = deferred;
  9375. return;
  9376. }
  9377. if (self._40 === 1) {
  9378. self._40 = 2;
  9379. self._72 = [self._72, deferred];
  9380. return;
  9381. }
  9382. self._72.push(deferred);
  9383. return;
  9384. }
  9385. handleResolved(self, deferred);
  9386. }
  9387. function handleResolved(self, deferred) {
  9388. asap(function() {
  9389. var cb = self._65 === 1 ? deferred.onFulfilled : deferred.onRejected;
  9390. if (cb === null) {
  9391. if (self._65 === 1) {
  9392. resolve(deferred.promise, self._55);
  9393. } else {
  9394. reject(deferred.promise, self._55);
  9395. }
  9396. return;
  9397. }
  9398. var ret = tryCallOne(cb, self._55);
  9399. if (ret === IS_ERROR) {
  9400. reject(deferred.promise, LAST_ERROR);
  9401. } else {
  9402. resolve(deferred.promise, ret);
  9403. }
  9404. });
  9405. }
  9406. function resolve(self, newValue) {
  9407. // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
  9408. if (newValue === self) {
  9409. return reject(
  9410. self,
  9411. new TypeError('A promise cannot be resolved with itself.')
  9412. );
  9413. }
  9414. if (
  9415. newValue &&
  9416. (typeof newValue === 'object' || typeof newValue === 'function')
  9417. ) {
  9418. var then = getThen(newValue);
  9419. if (then === IS_ERROR) {
  9420. return reject(self, LAST_ERROR);
  9421. }
  9422. if (
  9423. then === self.then &&
  9424. newValue instanceof Promise
  9425. ) {
  9426. self._65 = 3;
  9427. self._55 = newValue;
  9428. finale(self);
  9429. return;
  9430. } else if (typeof then === 'function') {
  9431. doResolve(then.bind(newValue), self);
  9432. return;
  9433. }
  9434. }
  9435. self._65 = 1;
  9436. self._55 = newValue;
  9437. finale(self);
  9438. }
  9439. function reject(self, newValue) {
  9440. self._65 = 2;
  9441. self._55 = newValue;
  9442. if (Promise._87) {
  9443. Promise._87(self, newValue);
  9444. }
  9445. finale(self);
  9446. }
  9447. function finale(self) {
  9448. if (self._40 === 1) {
  9449. handle(self, self._72);
  9450. self._72 = null;
  9451. }
  9452. if (self._40 === 2) {
  9453. for (var i = 0; i < self._72.length; i++) {
  9454. handle(self, self._72[i]);
  9455. }
  9456. self._72 = null;
  9457. }
  9458. }
  9459. function Handler(onFulfilled, onRejected, promise){
  9460. this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
  9461. this.onRejected = typeof onRejected === 'function' ? onRejected : null;
  9462. this.promise = promise;
  9463. }
  9464. /**
  9465. * Take a potentially misbehaving resolver function and make sure
  9466. * onFulfilled and onRejected are only called once.
  9467. *
  9468. * Makes no guarantees about asynchrony.
  9469. */
  9470. function doResolve(fn, promise) {
  9471. var done = false;
  9472. var res = tryCallTwo(fn, function (value) {
  9473. if (done) return;
  9474. done = true;
  9475. resolve(promise, value);
  9476. }, function (reason) {
  9477. if (done) return;
  9478. done = true;
  9479. reject(promise, reason);
  9480. });
  9481. if (!done && res === IS_ERROR) {
  9482. done = true;
  9483. reject(promise, LAST_ERROR);
  9484. }
  9485. }
  9486. },{"asap/raw":93}],95:[function(require,module,exports){
  9487. 'use strict';
  9488. //This file contains the ES6 extensions to the core Promises/A+ API
  9489. var Promise = require('./core.js');
  9490. module.exports = Promise;
  9491. /* Static Functions */
  9492. var TRUE = valuePromise(true);
  9493. var FALSE = valuePromise(false);
  9494. var NULL = valuePromise(null);
  9495. var UNDEFINED = valuePromise(undefined);
  9496. var ZERO = valuePromise(0);
  9497. var EMPTYSTRING = valuePromise('');
  9498. function valuePromise(value) {
  9499. var p = new Promise(Promise._61);
  9500. p._65 = 1;
  9501. p._55 = value;
  9502. return p;
  9503. }
  9504. Promise.resolve = function (value) {
  9505. if (value instanceof Promise) return value;
  9506. if (value === null) return NULL;
  9507. if (value === undefined) return UNDEFINED;
  9508. if (value === true) return TRUE;
  9509. if (value === false) return FALSE;
  9510. if (value === 0) return ZERO;
  9511. if (value === '') return EMPTYSTRING;
  9512. if (typeof value === 'object' || typeof value === 'function') {
  9513. try {
  9514. var then = value.then;
  9515. if (typeof then === 'function') {
  9516. return new Promise(then.bind(value));
  9517. }
  9518. } catch (ex) {
  9519. return new Promise(function (resolve, reject) {
  9520. reject(ex);
  9521. });
  9522. }
  9523. }
  9524. return valuePromise(value);
  9525. };
  9526. Promise.all = function (arr) {
  9527. var args = Array.prototype.slice.call(arr);
  9528. return new Promise(function (resolve, reject) {
  9529. if (args.length === 0) return resolve([]);
  9530. var remaining = args.length;
  9531. function res(i, val) {
  9532. if (val && (typeof val === 'object' || typeof val === 'function')) {
  9533. if (val instanceof Promise && val.then === Promise.prototype.then) {
  9534. while (val._65 === 3) {
  9535. val = val._55;
  9536. }
  9537. if (val._65 === 1) return res(i, val._55);
  9538. if (val._65 === 2) reject(val._55);
  9539. val.then(function (val) {
  9540. res(i, val);
  9541. }, reject);
  9542. return;
  9543. } else {
  9544. var then = val.then;
  9545. if (typeof then === 'function') {
  9546. var p = new Promise(then.bind(val));
  9547. p.then(function (val) {
  9548. res(i, val);
  9549. }, reject);
  9550. return;
  9551. }
  9552. }
  9553. }
  9554. args[i] = val;
  9555. if (--remaining === 0) {
  9556. resolve(args);
  9557. }
  9558. }
  9559. for (var i = 0; i < args.length; i++) {
  9560. res(i, args[i]);
  9561. }
  9562. });
  9563. };
  9564. Promise.reject = function (value) {
  9565. return new Promise(function (resolve, reject) {
  9566. reject(value);
  9567. });
  9568. };
  9569. Promise.race = function (values) {
  9570. return new Promise(function (resolve, reject) {
  9571. values.forEach(function(value){
  9572. Promise.resolve(value).then(resolve, reject);
  9573. });
  9574. });
  9575. };
  9576. /* Prototype Methods */
  9577. Promise.prototype['catch'] = function (onRejected) {
  9578. return this.then(null, onRejected);
  9579. };
  9580. },{"./core.js":94}],96:[function(require,module,exports){
  9581. // should work in any browser without browserify
  9582. if (typeof Promise.prototype.done !== 'function') {
  9583. Promise.prototype.done = function (onFulfilled, onRejected) {
  9584. var self = arguments.length ? this.then.apply(this, arguments) : this
  9585. self.then(null, function (err) {
  9586. setTimeout(function () {
  9587. throw err
  9588. }, 0)
  9589. })
  9590. }
  9591. }
  9592. },{}],97:[function(require,module,exports){
  9593. // not "use strict" so we can declare global "Promise"
  9594. var asap = require('asap');
  9595. if (typeof Promise === 'undefined') {
  9596. Promise = require('./lib/core.js')
  9597. require('./lib/es6-extensions.js')
  9598. }
  9599. require('./polyfill-done.js');
  9600. },{"./lib/core.js":94,"./lib/es6-extensions.js":95,"./polyfill-done.js":96,"asap":92}]},{},[2])(2)
  9601. });