joint.js 729 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469
  1. /*! JointJS v0.9.0 - JavaScript diagramming library 2014-05-13
  2. This Source Code Form is subject to the terms of the Mozilla Public
  3. License, v. 2.0. If a copy of the MPL was not distributed with this
  4. file, You can obtain one at http://mozilla.org/MPL/2.0/.
  5. */
  6. /*!
  7. * jQuery JavaScript Library v2.0.3
  8. * http://jquery.com/
  9. *
  10. * Includes Sizzle.js
  11. * http://sizzlejs.com/
  12. *
  13. * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
  14. * Released under the MIT license
  15. * http://jquery.org/license
  16. *
  17. * Date: 2013-07-03T13:30Z
  18. */
  19. (function( window, undefined ) {
  20. // Can't do this because several apps including ASP.NET trace
  21. // the stack via arguments.caller.callee and Firefox dies if
  22. // you try to trace through "use strict" call chains. (#13335)
  23. // Support: Firefox 18+
  24. //"use strict";
  25. var
  26. // A central reference to the root jQuery(document)
  27. rootjQuery,
  28. // The deferred used on DOM ready
  29. readyList,
  30. // Support: IE9
  31. // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`
  32. core_strundefined = typeof undefined,
  33. // Use the correct document accordingly with window argument (sandbox)
  34. location = window.location,
  35. document = window.document,
  36. docElem = document.documentElement,
  37. // Map over jQuery in case of overwrite
  38. _jQuery = window.jQuery,
  39. // Map over the $ in case of overwrite
  40. _$ = window.$,
  41. // [[Class]] -> type pairs
  42. class2type = {},
  43. // List of deleted data cache ids, so we can reuse them
  44. core_deletedIds = [],
  45. core_version = "2.0.3",
  46. // Save a reference to some core methods
  47. core_concat = core_deletedIds.concat,
  48. core_push = core_deletedIds.push,
  49. core_slice = core_deletedIds.slice,
  50. core_indexOf = core_deletedIds.indexOf,
  51. core_toString = class2type.toString,
  52. core_hasOwn = class2type.hasOwnProperty,
  53. core_trim = core_version.trim,
  54. // Define a local copy of jQuery
  55. jQuery = function( selector, context ) {
  56. // The jQuery object is actually just the init constructor 'enhanced'
  57. return new jQuery.fn.init( selector, context, rootjQuery );
  58. },
  59. // Used for matching numbers
  60. core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,
  61. // Used for splitting on whitespace
  62. core_rnotwhite = /\S+/g,
  63. // A simple way to check for HTML strings
  64. // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
  65. // Strict HTML recognition (#11290: must start with <)
  66. rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
  67. // Match a standalone tag
  68. rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,
  69. // Matches dashed string for camelizing
  70. rmsPrefix = /^-ms-/,
  71. rdashAlpha = /-([\da-z])/gi,
  72. // Used by jQuery.camelCase as callback to replace()
  73. fcamelCase = function( all, letter ) {
  74. return letter.toUpperCase();
  75. },
  76. // The ready event handler and self cleanup method
  77. completed = function() {
  78. document.removeEventListener( "DOMContentLoaded", completed, false );
  79. window.removeEventListener( "load", completed, false );
  80. jQuery.ready();
  81. };
  82. jQuery.fn = jQuery.prototype = {
  83. // The current version of jQuery being used
  84. jquery: core_version,
  85. constructor: jQuery,
  86. init: function( selector, context, rootjQuery ) {
  87. var match, elem;
  88. // HANDLE: $(""), $(null), $(undefined), $(false)
  89. if ( !selector ) {
  90. return this;
  91. }
  92. // Handle HTML strings
  93. if ( typeof selector === "string" ) {
  94. if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
  95. // Assume that strings that start and end with <> are HTML and skip the regex check
  96. match = [ null, selector, null ];
  97. } else {
  98. match = rquickExpr.exec( selector );
  99. }
  100. // Match html or make sure no context is specified for #id
  101. if ( match && (match[1] || !context) ) {
  102. // HANDLE: $(html) -> $(array)
  103. if ( match[1] ) {
  104. context = context instanceof jQuery ? context[0] : context;
  105. // scripts is true for back-compat
  106. jQuery.merge( this, jQuery.parseHTML(
  107. match[1],
  108. context && context.nodeType ? context.ownerDocument || context : document,
  109. true
  110. ) );
  111. // HANDLE: $(html, props)
  112. if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
  113. for ( match in context ) {
  114. // Properties of context are called as methods if possible
  115. if ( jQuery.isFunction( this[ match ] ) ) {
  116. this[ match ]( context[ match ] );
  117. // ...and otherwise set as attributes
  118. } else {
  119. this.attr( match, context[ match ] );
  120. }
  121. }
  122. }
  123. return this;
  124. // HANDLE: $(#id)
  125. } else {
  126. elem = document.getElementById( match[2] );
  127. // Check parentNode to catch when Blackberry 4.6 returns
  128. // nodes that are no longer in the document #6963
  129. if ( elem && elem.parentNode ) {
  130. // Inject the element directly into the jQuery object
  131. this.length = 1;
  132. this[0] = elem;
  133. }
  134. this.context = document;
  135. this.selector = selector;
  136. return this;
  137. }
  138. // HANDLE: $(expr, $(...))
  139. } else if ( !context || context.jquery ) {
  140. return ( context || rootjQuery ).find( selector );
  141. // HANDLE: $(expr, context)
  142. // (which is just equivalent to: $(context).find(expr)
  143. } else {
  144. return this.constructor( context ).find( selector );
  145. }
  146. // HANDLE: $(DOMElement)
  147. } else if ( selector.nodeType ) {
  148. this.context = this[0] = selector;
  149. this.length = 1;
  150. return this;
  151. // HANDLE: $(function)
  152. // Shortcut for document ready
  153. } else if ( jQuery.isFunction( selector ) ) {
  154. return rootjQuery.ready( selector );
  155. }
  156. if ( selector.selector !== undefined ) {
  157. this.selector = selector.selector;
  158. this.context = selector.context;
  159. }
  160. return jQuery.makeArray( selector, this );
  161. },
  162. // Start with an empty selector
  163. selector: "",
  164. // The default length of a jQuery object is 0
  165. length: 0,
  166. toArray: function() {
  167. return core_slice.call( this );
  168. },
  169. // Get the Nth element in the matched element set OR
  170. // Get the whole matched element set as a clean array
  171. get: function( num ) {
  172. return num == null ?
  173. // Return a 'clean' array
  174. this.toArray() :
  175. // Return just the object
  176. ( num < 0 ? this[ this.length + num ] : this[ num ] );
  177. },
  178. // Take an array of elements and push it onto the stack
  179. // (returning the new matched element set)
  180. pushStack: function( elems ) {
  181. // Build a new jQuery matched element set
  182. var ret = jQuery.merge( this.constructor(), elems );
  183. // Add the old object onto the stack (as a reference)
  184. ret.prevObject = this;
  185. ret.context = this.context;
  186. // Return the newly-formed element set
  187. return ret;
  188. },
  189. // Execute a callback for every element in the matched set.
  190. // (You can seed the arguments with an array of args, but this is
  191. // only used internally.)
  192. each: function( callback, args ) {
  193. return jQuery.each( this, callback, args );
  194. },
  195. ready: function( fn ) {
  196. // Add the callback
  197. jQuery.ready.promise().done( fn );
  198. return this;
  199. },
  200. slice: function() {
  201. return this.pushStack( core_slice.apply( this, arguments ) );
  202. },
  203. first: function() {
  204. return this.eq( 0 );
  205. },
  206. last: function() {
  207. return this.eq( -1 );
  208. },
  209. eq: function( i ) {
  210. var len = this.length,
  211. j = +i + ( i < 0 ? len : 0 );
  212. return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
  213. },
  214. map: function( callback ) {
  215. return this.pushStack( jQuery.map(this, function( elem, i ) {
  216. return callback.call( elem, i, elem );
  217. }));
  218. },
  219. end: function() {
  220. return this.prevObject || this.constructor(null);
  221. },
  222. // For internal use only.
  223. // Behaves like an Array's method, not like a jQuery method.
  224. push: core_push,
  225. sort: [].sort,
  226. splice: [].splice
  227. };
  228. // Give the init function the jQuery prototype for later instantiation
  229. jQuery.fn.init.prototype = jQuery.fn;
  230. jQuery.extend = jQuery.fn.extend = function() {
  231. var options, name, src, copy, copyIsArray, clone,
  232. target = arguments[0] || {},
  233. i = 1,
  234. length = arguments.length,
  235. deep = false;
  236. // Handle a deep copy situation
  237. if ( typeof target === "boolean" ) {
  238. deep = target;
  239. target = arguments[1] || {};
  240. // skip the boolean and the target
  241. i = 2;
  242. }
  243. // Handle case when target is a string or something (possible in deep copy)
  244. if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
  245. target = {};
  246. }
  247. // extend jQuery itself if only one argument is passed
  248. if ( length === i ) {
  249. target = this;
  250. --i;
  251. }
  252. for ( ; i < length; i++ ) {
  253. // Only deal with non-null/undefined values
  254. if ( (options = arguments[ i ]) != null ) {
  255. // Extend the base object
  256. for ( name in options ) {
  257. src = target[ name ];
  258. copy = options[ name ];
  259. // Prevent never-ending loop
  260. if ( target === copy ) {
  261. continue;
  262. }
  263. // Recurse if we're merging plain objects or arrays
  264. if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
  265. if ( copyIsArray ) {
  266. copyIsArray = false;
  267. clone = src && jQuery.isArray(src) ? src : [];
  268. } else {
  269. clone = src && jQuery.isPlainObject(src) ? src : {};
  270. }
  271. // Never move original objects, clone them
  272. target[ name ] = jQuery.extend( deep, clone, copy );
  273. // Don't bring in undefined values
  274. } else if ( copy !== undefined ) {
  275. target[ name ] = copy;
  276. }
  277. }
  278. }
  279. }
  280. // Return the modified object
  281. return target;
  282. };
  283. jQuery.extend({
  284. // Unique for each copy of jQuery on the page
  285. expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ),
  286. noConflict: function( deep ) {
  287. if ( window.$ === jQuery ) {
  288. window.$ = _$;
  289. }
  290. if ( deep && window.jQuery === jQuery ) {
  291. window.jQuery = _jQuery;
  292. }
  293. return jQuery;
  294. },
  295. // Is the DOM ready to be used? Set to true once it occurs.
  296. isReady: false,
  297. // A counter to track how many items to wait for before
  298. // the ready event fires. See #6781
  299. readyWait: 1,
  300. // Hold (or release) the ready event
  301. holdReady: function( hold ) {
  302. if ( hold ) {
  303. jQuery.readyWait++;
  304. } else {
  305. jQuery.ready( true );
  306. }
  307. },
  308. // Handle when the DOM is ready
  309. ready: function( wait ) {
  310. // Abort if there are pending holds or we're already ready
  311. if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
  312. return;
  313. }
  314. // Remember that the DOM is ready
  315. jQuery.isReady = true;
  316. // If a normal DOM Ready event fired, decrement, and wait if need be
  317. if ( wait !== true && --jQuery.readyWait > 0 ) {
  318. return;
  319. }
  320. // If there are functions bound, to execute
  321. readyList.resolveWith( document, [ jQuery ] );
  322. // Trigger any bound ready events
  323. if ( jQuery.fn.trigger ) {
  324. jQuery( document ).trigger("ready").off("ready");
  325. }
  326. },
  327. // See test/unit/core.js for details concerning isFunction.
  328. // Since version 1.3, DOM methods and functions like alert
  329. // aren't supported. They return false on IE (#2968).
  330. isFunction: function( obj ) {
  331. return jQuery.type(obj) === "function";
  332. },
  333. isArray: Array.isArray,
  334. isWindow: function( obj ) {
  335. return obj != null && obj === obj.window;
  336. },
  337. isNumeric: function( obj ) {
  338. return !isNaN( parseFloat(obj) ) && isFinite( obj );
  339. },
  340. type: function( obj ) {
  341. if ( obj == null ) {
  342. return String( obj );
  343. }
  344. // Support: Safari <= 5.1 (functionish RegExp)
  345. return typeof obj === "object" || typeof obj === "function" ?
  346. class2type[ core_toString.call(obj) ] || "object" :
  347. typeof obj;
  348. },
  349. isPlainObject: function( obj ) {
  350. // Not plain objects:
  351. // - Any object or value whose internal [[Class]] property is not "[object Object]"
  352. // - DOM nodes
  353. // - window
  354. if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  355. return false;
  356. }
  357. // Support: Firefox <20
  358. // The try/catch suppresses exceptions thrown when attempting to access
  359. // the "constructor" property of certain host objects, ie. |window.location|
  360. // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
  361. try {
  362. if ( obj.constructor &&
  363. !core_hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
  364. return false;
  365. }
  366. } catch ( e ) {
  367. return false;
  368. }
  369. // If the function hasn't returned already, we're confident that
  370. // |obj| is a plain object, created by {} or constructed with new Object
  371. return true;
  372. },
  373. isEmptyObject: function( obj ) {
  374. var name;
  375. for ( name in obj ) {
  376. return false;
  377. }
  378. return true;
  379. },
  380. error: function( msg ) {
  381. throw new Error( msg );
  382. },
  383. // data: string of html
  384. // context (optional): If specified, the fragment will be created in this context, defaults to document
  385. // keepScripts (optional): If true, will include scripts passed in the html string
  386. parseHTML: function( data, context, keepScripts ) {
  387. if ( !data || typeof data !== "string" ) {
  388. return null;
  389. }
  390. if ( typeof context === "boolean" ) {
  391. keepScripts = context;
  392. context = false;
  393. }
  394. context = context || document;
  395. var parsed = rsingleTag.exec( data ),
  396. scripts = !keepScripts && [];
  397. // Single tag
  398. if ( parsed ) {
  399. return [ context.createElement( parsed[1] ) ];
  400. }
  401. parsed = jQuery.buildFragment( [ data ], context, scripts );
  402. if ( scripts ) {
  403. jQuery( scripts ).remove();
  404. }
  405. return jQuery.merge( [], parsed.childNodes );
  406. },
  407. parseJSON: JSON.parse,
  408. // Cross-browser xml parsing
  409. parseXML: function( data ) {
  410. var xml, tmp;
  411. if ( !data || typeof data !== "string" ) {
  412. return null;
  413. }
  414. // Support: IE9
  415. try {
  416. tmp = new DOMParser();
  417. xml = tmp.parseFromString( data , "text/xml" );
  418. } catch ( e ) {
  419. xml = undefined;
  420. }
  421. if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
  422. jQuery.error( "Invalid XML: " + data );
  423. }
  424. return xml;
  425. },
  426. noop: function() {},
  427. // Evaluates a script in a global context
  428. globalEval: function( code ) {
  429. var script,
  430. indirect = eval;
  431. code = jQuery.trim( code );
  432. if ( code ) {
  433. // If the code includes a valid, prologue position
  434. // strict mode pragma, execute code by injecting a
  435. // script tag into the document.
  436. if ( code.indexOf("use strict") === 1 ) {
  437. script = document.createElement("script");
  438. script.text = code;
  439. document.head.appendChild( script ).parentNode.removeChild( script );
  440. } else {
  441. // Otherwise, avoid the DOM node creation, insertion
  442. // and removal by using an indirect global eval
  443. indirect( code );
  444. }
  445. }
  446. },
  447. // Convert dashed to camelCase; used by the css and data modules
  448. // Microsoft forgot to hump their vendor prefix (#9572)
  449. camelCase: function( string ) {
  450. return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
  451. },
  452. nodeName: function( elem, name ) {
  453. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  454. },
  455. // args is for internal usage only
  456. each: function( obj, callback, args ) {
  457. var value,
  458. i = 0,
  459. length = obj.length,
  460. isArray = isArraylike( obj );
  461. if ( args ) {
  462. if ( isArray ) {
  463. for ( ; i < length; i++ ) {
  464. value = callback.apply( obj[ i ], args );
  465. if ( value === false ) {
  466. break;
  467. }
  468. }
  469. } else {
  470. for ( i in obj ) {
  471. value = callback.apply( obj[ i ], args );
  472. if ( value === false ) {
  473. break;
  474. }
  475. }
  476. }
  477. // A special, fast, case for the most common use of each
  478. } else {
  479. if ( isArray ) {
  480. for ( ; i < length; i++ ) {
  481. value = callback.call( obj[ i ], i, obj[ i ] );
  482. if ( value === false ) {
  483. break;
  484. }
  485. }
  486. } else {
  487. for ( i in obj ) {
  488. value = callback.call( obj[ i ], i, obj[ i ] );
  489. if ( value === false ) {
  490. break;
  491. }
  492. }
  493. }
  494. }
  495. return obj;
  496. },
  497. trim: function( text ) {
  498. return text == null ? "" : core_trim.call( text );
  499. },
  500. // results is for internal usage only
  501. makeArray: function( arr, results ) {
  502. var ret = results || [];
  503. if ( arr != null ) {
  504. if ( isArraylike( Object(arr) ) ) {
  505. jQuery.merge( ret,
  506. typeof arr === "string" ?
  507. [ arr ] : arr
  508. );
  509. } else {
  510. core_push.call( ret, arr );
  511. }
  512. }
  513. return ret;
  514. },
  515. inArray: function( elem, arr, i ) {
  516. return arr == null ? -1 : core_indexOf.call( arr, elem, i );
  517. },
  518. merge: function( first, second ) {
  519. var l = second.length,
  520. i = first.length,
  521. j = 0;
  522. if ( typeof l === "number" ) {
  523. for ( ; j < l; j++ ) {
  524. first[ i++ ] = second[ j ];
  525. }
  526. } else {
  527. while ( second[j] !== undefined ) {
  528. first[ i++ ] = second[ j++ ];
  529. }
  530. }
  531. first.length = i;
  532. return first;
  533. },
  534. grep: function( elems, callback, inv ) {
  535. var retVal,
  536. ret = [],
  537. i = 0,
  538. length = elems.length;
  539. inv = !!inv;
  540. // Go through the array, only saving the items
  541. // that pass the validator function
  542. for ( ; i < length; i++ ) {
  543. retVal = !!callback( elems[ i ], i );
  544. if ( inv !== retVal ) {
  545. ret.push( elems[ i ] );
  546. }
  547. }
  548. return ret;
  549. },
  550. // arg is for internal usage only
  551. map: function( elems, callback, arg ) {
  552. var value,
  553. i = 0,
  554. length = elems.length,
  555. isArray = isArraylike( elems ),
  556. ret = [];
  557. // Go through the array, translating each of the items to their
  558. if ( isArray ) {
  559. for ( ; i < length; i++ ) {
  560. value = callback( elems[ i ], i, arg );
  561. if ( value != null ) {
  562. ret[ ret.length ] = value;
  563. }
  564. }
  565. // Go through every key on the object,
  566. } else {
  567. for ( i in elems ) {
  568. value = callback( elems[ i ], i, arg );
  569. if ( value != null ) {
  570. ret[ ret.length ] = value;
  571. }
  572. }
  573. }
  574. // Flatten any nested arrays
  575. return core_concat.apply( [], ret );
  576. },
  577. // A global GUID counter for objects
  578. guid: 1,
  579. // Bind a function to a context, optionally partially applying any
  580. // arguments.
  581. proxy: function( fn, context ) {
  582. var tmp, args, proxy;
  583. if ( typeof context === "string" ) {
  584. tmp = fn[ context ];
  585. context = fn;
  586. fn = tmp;
  587. }
  588. // Quick check to determine if target is callable, in the spec
  589. // this throws a TypeError, but we will just return undefined.
  590. if ( !jQuery.isFunction( fn ) ) {
  591. return undefined;
  592. }
  593. // Simulated bind
  594. args = core_slice.call( arguments, 2 );
  595. proxy = function() {
  596. return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );
  597. };
  598. // Set the guid of unique handler to the same of original handler, so it can be removed
  599. proxy.guid = fn.guid = fn.guid || jQuery.guid++;
  600. return proxy;
  601. },
  602. // Multifunctional method to get and set values of a collection
  603. // The value/s can optionally be executed if it's a function
  604. access: function( elems, fn, key, value, chainable, emptyGet, raw ) {
  605. var i = 0,
  606. length = elems.length,
  607. bulk = key == null;
  608. // Sets many values
  609. if ( jQuery.type( key ) === "object" ) {
  610. chainable = true;
  611. for ( i in key ) {
  612. jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
  613. }
  614. // Sets one value
  615. } else if ( value !== undefined ) {
  616. chainable = true;
  617. if ( !jQuery.isFunction( value ) ) {
  618. raw = true;
  619. }
  620. if ( bulk ) {
  621. // Bulk operations run against the entire set
  622. if ( raw ) {
  623. fn.call( elems, value );
  624. fn = null;
  625. // ...except when executing function values
  626. } else {
  627. bulk = fn;
  628. fn = function( elem, key, value ) {
  629. return bulk.call( jQuery( elem ), value );
  630. };
  631. }
  632. }
  633. if ( fn ) {
  634. for ( ; i < length; i++ ) {
  635. fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
  636. }
  637. }
  638. }
  639. return chainable ?
  640. elems :
  641. // Gets
  642. bulk ?
  643. fn.call( elems ) :
  644. length ? fn( elems[0], key ) : emptyGet;
  645. },
  646. now: Date.now,
  647. // A method for quickly swapping in/out CSS properties to get correct calculations.
  648. // Note: this method belongs to the css module but it's needed here for the support module.
  649. // If support gets modularized, this method should be moved back to the css module.
  650. swap: function( elem, options, callback, args ) {
  651. var ret, name,
  652. old = {};
  653. // Remember the old values, and insert the new ones
  654. for ( name in options ) {
  655. old[ name ] = elem.style[ name ];
  656. elem.style[ name ] = options[ name ];
  657. }
  658. ret = callback.apply( elem, args || [] );
  659. // Revert the old values
  660. for ( name in options ) {
  661. elem.style[ name ] = old[ name ];
  662. }
  663. return ret;
  664. }
  665. });
  666. jQuery.ready.promise = function( obj ) {
  667. if ( !readyList ) {
  668. readyList = jQuery.Deferred();
  669. // Catch cases where $(document).ready() is called after the browser event has already occurred.
  670. // we once tried to use readyState "interactive" here, but it caused issues like the one
  671. // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15
  672. if ( document.readyState === "complete" ) {
  673. // Handle it asynchronously to allow scripts the opportunity to delay ready
  674. setTimeout( jQuery.ready );
  675. } else {
  676. // Use the handy event callback
  677. document.addEventListener( "DOMContentLoaded", completed, false );
  678. // A fallback to window.onload, that will always work
  679. window.addEventListener( "load", completed, false );
  680. }
  681. }
  682. return readyList.promise( obj );
  683. };
  684. // Populate the class2type map
  685. jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
  686. class2type[ "[object " + name + "]" ] = name.toLowerCase();
  687. });
  688. function isArraylike( obj ) {
  689. var length = obj.length,
  690. type = jQuery.type( obj );
  691. if ( jQuery.isWindow( obj ) ) {
  692. return false;
  693. }
  694. if ( obj.nodeType === 1 && length ) {
  695. return true;
  696. }
  697. return type === "array" || type !== "function" &&
  698. ( length === 0 ||
  699. typeof length === "number" && length > 0 && ( length - 1 ) in obj );
  700. }
  701. // All jQuery objects should point back to these
  702. rootjQuery = jQuery(document);
  703. /*!
  704. * Sizzle CSS Selector Engine v1.9.4-pre
  705. * http://sizzlejs.com/
  706. *
  707. * Copyright 2013 jQuery Foundation, Inc. and other contributors
  708. * Released under the MIT license
  709. * http://jquery.org/license
  710. *
  711. * Date: 2013-06-03
  712. */
  713. (function( window, undefined ) {
  714. var i,
  715. support,
  716. cachedruns,
  717. Expr,
  718. getText,
  719. isXML,
  720. compile,
  721. outermostContext,
  722. sortInput,
  723. // Local document vars
  724. setDocument,
  725. document,
  726. docElem,
  727. documentIsHTML,
  728. rbuggyQSA,
  729. rbuggyMatches,
  730. matches,
  731. contains,
  732. // Instance-specific data
  733. expando = "sizzle" + -(new Date()),
  734. preferredDoc = window.document,
  735. dirruns = 0,
  736. done = 0,
  737. classCache = createCache(),
  738. tokenCache = createCache(),
  739. compilerCache = createCache(),
  740. hasDuplicate = false,
  741. sortOrder = function( a, b ) {
  742. if ( a === b ) {
  743. hasDuplicate = true;
  744. return 0;
  745. }
  746. return 0;
  747. },
  748. // General-purpose constants
  749. strundefined = typeof undefined,
  750. MAX_NEGATIVE = 1 << 31,
  751. // Instance methods
  752. hasOwn = ({}).hasOwnProperty,
  753. arr = [],
  754. pop = arr.pop,
  755. push_native = arr.push,
  756. push = arr.push,
  757. slice = arr.slice,
  758. // Use a stripped-down indexOf if we can't use a native one
  759. indexOf = arr.indexOf || function( elem ) {
  760. var i = 0,
  761. len = this.length;
  762. for ( ; i < len; i++ ) {
  763. if ( this[i] === elem ) {
  764. return i;
  765. }
  766. }
  767. return -1;
  768. },
  769. booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
  770. // Regular expressions
  771. // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace
  772. whitespace = "[\\x20\\t\\r\\n\\f]",
  773. // http://www.w3.org/TR/css3-syntax/#characters
  774. characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
  775. // Loosely modeled on CSS identifier characters
  776. // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors
  777. // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
  778. identifier = characterEncoding.replace( "w", "w#" ),
  779. // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors
  780. attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace +
  781. "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]",
  782. // Prefer arguments quoted,
  783. // then not containing pseudos/brackets,
  784. // then attribute selectors/non-parenthetical expressions,
  785. // then anything else
  786. // These preferences are here to reduce the number of selectors
  787. // needing tokenize in the PSEUDO preFilter
  788. pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
  789. // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
  790. rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
  791. rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
  792. rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
  793. rsibling = new RegExp( whitespace + "*[+~]" ),
  794. rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ),
  795. rpseudo = new RegExp( pseudos ),
  796. ridentifier = new RegExp( "^" + identifier + "$" ),
  797. matchExpr = {
  798. "ID": new RegExp( "^#(" + characterEncoding + ")" ),
  799. "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ),
  800. "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ),
  801. "ATTR": new RegExp( "^" + attributes ),
  802. "PSEUDO": new RegExp( "^" + pseudos ),
  803. "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
  804. "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
  805. "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
  806. "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
  807. // For use in libraries implementing .is()
  808. // We use this for POS matching in `select`
  809. "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
  810. whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
  811. },
  812. rnative = /^[^{]+\{\s*\[native \w/,
  813. // Easily-parseable/retrievable ID or TAG or CLASS selectors
  814. rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
  815. rinputs = /^(?:input|select|textarea|button)$/i,
  816. rheader = /^h\d$/i,
  817. rescape = /'|\\/g,
  818. // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
  819. runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
  820. funescape = function( _, escaped, escapedWhitespace ) {
  821. var high = "0x" + escaped - 0x10000;
  822. // NaN means non-codepoint
  823. // Support: Firefox
  824. // Workaround erroneous numeric interpretation of +"0x"
  825. return high !== high || escapedWhitespace ?
  826. escaped :
  827. // BMP codepoint
  828. high < 0 ?
  829. String.fromCharCode( high + 0x10000 ) :
  830. // Supplemental Plane codepoint (surrogate pair)
  831. String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
  832. };
  833. // Optimize for push.apply( _, NodeList )
  834. try {
  835. push.apply(
  836. (arr = slice.call( preferredDoc.childNodes )),
  837. preferredDoc.childNodes
  838. );
  839. // Support: Android<4.0
  840. // Detect silently failing push.apply
  841. arr[ preferredDoc.childNodes.length ].nodeType;
  842. } catch ( e ) {
  843. push = { apply: arr.length ?
  844. // Leverage slice if possible
  845. function( target, els ) {
  846. push_native.apply( target, slice.call(els) );
  847. } :
  848. // Support: IE<9
  849. // Otherwise append directly
  850. function( target, els ) {
  851. var j = target.length,
  852. i = 0;
  853. // Can't trust NodeList.length
  854. while ( (target[j++] = els[i++]) ) {}
  855. target.length = j - 1;
  856. }
  857. };
  858. }
  859. function Sizzle( selector, context, results, seed ) {
  860. var match, elem, m, nodeType,
  861. // QSA vars
  862. i, groups, old, nid, newContext, newSelector;
  863. if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
  864. setDocument( context );
  865. }
  866. context = context || document;
  867. results = results || [];
  868. if ( !selector || typeof selector !== "string" ) {
  869. return results;
  870. }
  871. if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
  872. return [];
  873. }
  874. if ( documentIsHTML && !seed ) {
  875. // Shortcuts
  876. if ( (match = rquickExpr.exec( selector )) ) {
  877. // Speed-up: Sizzle("#ID")
  878. if ( (m = match[1]) ) {
  879. if ( nodeType === 9 ) {
  880. elem = context.getElementById( m );
  881. // Check parentNode to catch when Blackberry 4.6 returns
  882. // nodes that are no longer in the document #6963
  883. if ( elem && elem.parentNode ) {
  884. // Handle the case where IE, Opera, and Webkit return items
  885. // by name instead of ID
  886. if ( elem.id === m ) {
  887. results.push( elem );
  888. return results;
  889. }
  890. } else {
  891. return results;
  892. }
  893. } else {
  894. // Context is not a document
  895. if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
  896. contains( context, elem ) && elem.id === m ) {
  897. results.push( elem );
  898. return results;
  899. }
  900. }
  901. // Speed-up: Sizzle("TAG")
  902. } else if ( match[2] ) {
  903. push.apply( results, context.getElementsByTagName( selector ) );
  904. return results;
  905. // Speed-up: Sizzle(".CLASS")
  906. } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
  907. push.apply( results, context.getElementsByClassName( m ) );
  908. return results;
  909. }
  910. }
  911. // QSA path
  912. if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
  913. nid = old = expando;
  914. newContext = context;
  915. newSelector = nodeType === 9 && selector;
  916. // qSA works strangely on Element-rooted queries
  917. // We can work around this by specifying an extra ID on the root
  918. // and working up from there (Thanks to Andrew Dupont for the technique)
  919. // IE 8 doesn't work on object elements
  920. if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
  921. groups = tokenize( selector );
  922. if ( (old = context.getAttribute("id")) ) {
  923. nid = old.replace( rescape, "\\$&" );
  924. } else {
  925. context.setAttribute( "id", nid );
  926. }
  927. nid = "[id='" + nid + "'] ";
  928. i = groups.length;
  929. while ( i-- ) {
  930. groups[i] = nid + toSelector( groups[i] );
  931. }
  932. newContext = rsibling.test( selector ) && context.parentNode || context;
  933. newSelector = groups.join(",");
  934. }
  935. if ( newSelector ) {
  936. try {
  937. push.apply( results,
  938. newContext.querySelectorAll( newSelector )
  939. );
  940. return results;
  941. } catch(qsaError) {
  942. } finally {
  943. if ( !old ) {
  944. context.removeAttribute("id");
  945. }
  946. }
  947. }
  948. }
  949. }
  950. // All others
  951. return select( selector.replace( rtrim, "$1" ), context, results, seed );
  952. }
  953. /**
  954. * Create key-value caches of limited size
  955. * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
  956. * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
  957. * deleting the oldest entry
  958. */
  959. function createCache() {
  960. var keys = [];
  961. function cache( key, value ) {
  962. // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
  963. if ( keys.push( key += " " ) > Expr.cacheLength ) {
  964. // Only keep the most recent entries
  965. delete cache[ keys.shift() ];
  966. }
  967. return (cache[ key ] = value);
  968. }
  969. return cache;
  970. }
  971. /**
  972. * Mark a function for special use by Sizzle
  973. * @param {Function} fn The function to mark
  974. */
  975. function markFunction( fn ) {
  976. fn[ expando ] = true;
  977. return fn;
  978. }
  979. /**
  980. * Support testing using an element
  981. * @param {Function} fn Passed the created div and expects a boolean result
  982. */
  983. function assert( fn ) {
  984. var div = document.createElement("div");
  985. try {
  986. return !!fn( div );
  987. } catch (e) {
  988. return false;
  989. } finally {
  990. // Remove from its parent by default
  991. if ( div.parentNode ) {
  992. div.parentNode.removeChild( div );
  993. }
  994. // release memory in IE
  995. div = null;
  996. }
  997. }
  998. /**
  999. * Adds the same handler for all of the specified attrs
  1000. * @param {String} attrs Pipe-separated list of attributes
  1001. * @param {Function} handler The method that will be applied
  1002. */
  1003. function addHandle( attrs, handler ) {
  1004. var arr = attrs.split("|"),
  1005. i = attrs.length;
  1006. while ( i-- ) {
  1007. Expr.attrHandle[ arr[i] ] = handler;
  1008. }
  1009. }
  1010. /**
  1011. * Checks document order of two siblings
  1012. * @param {Element} a
  1013. * @param {Element} b
  1014. * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
  1015. */
  1016. function siblingCheck( a, b ) {
  1017. var cur = b && a,
  1018. diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
  1019. ( ~b.sourceIndex || MAX_NEGATIVE ) -
  1020. ( ~a.sourceIndex || MAX_NEGATIVE );
  1021. // Use IE sourceIndex if available on both nodes
  1022. if ( diff ) {
  1023. return diff;
  1024. }
  1025. // Check if b follows a
  1026. if ( cur ) {
  1027. while ( (cur = cur.nextSibling) ) {
  1028. if ( cur === b ) {
  1029. return -1;
  1030. }
  1031. }
  1032. }
  1033. return a ? 1 : -1;
  1034. }
  1035. /**
  1036. * Returns a function to use in pseudos for input types
  1037. * @param {String} type
  1038. */
  1039. function createInputPseudo( type ) {
  1040. return function( elem ) {
  1041. var name = elem.nodeName.toLowerCase();
  1042. return name === "input" && elem.type === type;
  1043. };
  1044. }
  1045. /**
  1046. * Returns a function to use in pseudos for buttons
  1047. * @param {String} type
  1048. */
  1049. function createButtonPseudo( type ) {
  1050. return function( elem ) {
  1051. var name = elem.nodeName.toLowerCase();
  1052. return (name === "input" || name === "button") && elem.type === type;
  1053. };
  1054. }
  1055. /**
  1056. * Returns a function to use in pseudos for positionals
  1057. * @param {Function} fn
  1058. */
  1059. function createPositionalPseudo( fn ) {
  1060. return markFunction(function( argument ) {
  1061. argument = +argument;
  1062. return markFunction(function( seed, matches ) {
  1063. var j,
  1064. matchIndexes = fn( [], seed.length, argument ),
  1065. i = matchIndexes.length;
  1066. // Match elements found at the specified indexes
  1067. while ( i-- ) {
  1068. if ( seed[ (j = matchIndexes[i]) ] ) {
  1069. seed[j] = !(matches[j] = seed[j]);
  1070. }
  1071. }
  1072. });
  1073. });
  1074. }
  1075. /**
  1076. * Detect xml
  1077. * @param {Element|Object} elem An element or a document
  1078. */
  1079. isXML = Sizzle.isXML = function( elem ) {
  1080. // documentElement is verified for cases where it doesn't yet exist
  1081. // (such as loading iframes in IE - #4833)
  1082. var documentElement = elem && (elem.ownerDocument || elem).documentElement;
  1083. return documentElement ? documentElement.nodeName !== "HTML" : false;
  1084. };
  1085. // Expose support vars for convenience
  1086. support = Sizzle.support = {};
  1087. /**
  1088. * Sets document-related variables once based on the current document
  1089. * @param {Element|Object} [doc] An element or document object to use to set the document
  1090. * @returns {Object} Returns the current document
  1091. */
  1092. setDocument = Sizzle.setDocument = function( node ) {
  1093. var doc = node ? node.ownerDocument || node : preferredDoc,
  1094. parent = doc.defaultView;
  1095. // If no document and documentElement is available, return
  1096. if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
  1097. return document;
  1098. }
  1099. // Set our document
  1100. document = doc;
  1101. docElem = doc.documentElement;
  1102. // Support tests
  1103. documentIsHTML = !isXML( doc );
  1104. // Support: IE>8
  1105. // If iframe document is assigned to "document" variable and if iframe has been reloaded,
  1106. // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936
  1107. // IE6-8 do not support the defaultView property so parent will be undefined
  1108. if ( parent && parent.attachEvent && parent !== parent.top ) {
  1109. parent.attachEvent( "onbeforeunload", function() {
  1110. setDocument();
  1111. });
  1112. }
  1113. /* Attributes
  1114. ---------------------------------------------------------------------- */
  1115. // Support: IE<8
  1116. // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)
  1117. support.attributes = assert(function( div ) {
  1118. div.className = "i";
  1119. return !div.getAttribute("className");
  1120. });
  1121. /* getElement(s)By*
  1122. ---------------------------------------------------------------------- */
  1123. // Check if getElementsByTagName("*") returns only elements
  1124. support.getElementsByTagName = assert(function( div ) {
  1125. div.appendChild( doc.createComment("") );
  1126. return !div.getElementsByTagName("*").length;
  1127. });
  1128. // Check if getElementsByClassName can be trusted
  1129. support.getElementsByClassName = assert(function( div ) {
  1130. div.innerHTML = "<div class='a'></div><div class='a i'></div>";
  1131. // Support: Safari<4
  1132. // Catch class over-caching
  1133. div.firstChild.className = "i";
  1134. // Support: Opera<10
  1135. // Catch gEBCN failure to find non-leading classes
  1136. return div.getElementsByClassName("i").length === 2;
  1137. });
  1138. // Support: IE<10
  1139. // Check if getElementById returns elements by name
  1140. // The broken getElementById methods don't pick up programatically-set names,
  1141. // so use a roundabout getElementsByName test
  1142. support.getById = assert(function( div ) {
  1143. docElem.appendChild( div ).id = expando;
  1144. return !doc.getElementsByName || !doc.getElementsByName( expando ).length;
  1145. });
  1146. // ID find and filter
  1147. if ( support.getById ) {
  1148. Expr.find["ID"] = function( id, context ) {
  1149. if ( typeof context.getElementById !== strundefined && documentIsHTML ) {
  1150. var m = context.getElementById( id );
  1151. // Check parentNode to catch when Blackberry 4.6 returns
  1152. // nodes that are no longer in the document #6963
  1153. return m && m.parentNode ? [m] : [];
  1154. }
  1155. };
  1156. Expr.filter["ID"] = function( id ) {
  1157. var attrId = id.replace( runescape, funescape );
  1158. return function( elem ) {
  1159. return elem.getAttribute("id") === attrId;
  1160. };
  1161. };
  1162. } else {
  1163. // Support: IE6/7
  1164. // getElementById is not reliable as a find shortcut
  1165. delete Expr.find["ID"];
  1166. Expr.filter["ID"] = function( id ) {
  1167. var attrId = id.replace( runescape, funescape );
  1168. return function( elem ) {
  1169. var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
  1170. return node && node.value === attrId;
  1171. };
  1172. };
  1173. }
  1174. // Tag
  1175. Expr.find["TAG"] = support.getElementsByTagName ?
  1176. function( tag, context ) {
  1177. if ( typeof context.getElementsByTagName !== strundefined ) {
  1178. return context.getElementsByTagName( tag );
  1179. }
  1180. } :
  1181. function( tag, context ) {
  1182. var elem,
  1183. tmp = [],
  1184. i = 0,
  1185. results = context.getElementsByTagName( tag );
  1186. // Filter out possible comments
  1187. if ( tag === "*" ) {
  1188. while ( (elem = results[i++]) ) {
  1189. if ( elem.nodeType === 1 ) {
  1190. tmp.push( elem );
  1191. }
  1192. }
  1193. return tmp;
  1194. }
  1195. return results;
  1196. };
  1197. // Class
  1198. Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
  1199. if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {
  1200. return context.getElementsByClassName( className );
  1201. }
  1202. };
  1203. /* QSA/matchesSelector
  1204. ---------------------------------------------------------------------- */
  1205. // QSA and matchesSelector support
  1206. // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
  1207. rbuggyMatches = [];
  1208. // qSa(:focus) reports false when true (Chrome 21)
  1209. // We allow this because of a bug in IE8/9 that throws an error
  1210. // whenever `document.activeElement` is accessed on an iframe
  1211. // So, we allow :focus to pass through QSA all the time to avoid the IE error
  1212. // See http://bugs.jquery.com/ticket/13378
  1213. rbuggyQSA = [];
  1214. if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {
  1215. // Build QSA regex
  1216. // Regex strategy adopted from Diego Perini
  1217. assert(function( div ) {
  1218. // Select is set to empty string on purpose
  1219. // This is to test IE's treatment of not explicitly
  1220. // setting a boolean content attribute,
  1221. // since its presence should be enough
  1222. // http://bugs.jquery.com/ticket/12359
  1223. div.innerHTML = "<select><option selected=''></option></select>";
  1224. // Support: IE8
  1225. // Boolean attributes and "value" are not treated correctly
  1226. if ( !div.querySelectorAll("[selected]").length ) {
  1227. rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
  1228. }
  1229. // Webkit/Opera - :checked should return selected option elements
  1230. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1231. // IE8 throws error here and will not see later tests
  1232. if ( !div.querySelectorAll(":checked").length ) {
  1233. rbuggyQSA.push(":checked");
  1234. }
  1235. });
  1236. assert(function( div ) {
  1237. // Support: Opera 10-12/IE8
  1238. // ^= $= *= and empty values
  1239. // Should not select anything
  1240. // Support: Windows 8 Native Apps
  1241. // The type attribute is restricted during .innerHTML assignment
  1242. var input = doc.createElement("input");
  1243. input.setAttribute( "type", "hidden" );
  1244. div.appendChild( input ).setAttribute( "t", "" );
  1245. if ( div.querySelectorAll("[t^='']").length ) {
  1246. rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
  1247. }
  1248. // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
  1249. // IE8 throws error here and will not see later tests
  1250. if ( !div.querySelectorAll(":enabled").length ) {
  1251. rbuggyQSA.push( ":enabled", ":disabled" );
  1252. }
  1253. // Opera 10-11 does not throw on post-comma invalid pseudos
  1254. div.querySelectorAll("*,:x");
  1255. rbuggyQSA.push(",.*:");
  1256. });
  1257. }
  1258. if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||
  1259. docElem.mozMatchesSelector ||
  1260. docElem.oMatchesSelector ||
  1261. docElem.msMatchesSelector) )) ) {
  1262. assert(function( div ) {
  1263. // Check to see if it's possible to do matchesSelector
  1264. // on a disconnected node (IE 9)
  1265. support.disconnectedMatch = matches.call( div, "div" );
  1266. // This should fail with an exception
  1267. // Gecko does not error, returns false instead
  1268. matches.call( div, "[s!='']:x" );
  1269. rbuggyMatches.push( "!=", pseudos );
  1270. });
  1271. }
  1272. rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
  1273. rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
  1274. /* Contains
  1275. ---------------------------------------------------------------------- */
  1276. // Element contains another
  1277. // Purposefully does not implement inclusive descendent
  1278. // As in, an element does not contain itself
  1279. contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?
  1280. function( a, b ) {
  1281. var adown = a.nodeType === 9 ? a.documentElement : a,
  1282. bup = b && b.parentNode;
  1283. return a === bup || !!( bup && bup.nodeType === 1 && (
  1284. adown.contains ?
  1285. adown.contains( bup ) :
  1286. a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
  1287. ));
  1288. } :
  1289. function( a, b ) {
  1290. if ( b ) {
  1291. while ( (b = b.parentNode) ) {
  1292. if ( b === a ) {
  1293. return true;
  1294. }
  1295. }
  1296. }
  1297. return false;
  1298. };
  1299. /* Sorting
  1300. ---------------------------------------------------------------------- */
  1301. // Document order sorting
  1302. sortOrder = docElem.compareDocumentPosition ?
  1303. function( a, b ) {
  1304. // Flag for duplicate removal
  1305. if ( a === b ) {
  1306. hasDuplicate = true;
  1307. return 0;
  1308. }
  1309. var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );
  1310. if ( compare ) {
  1311. // Disconnected nodes
  1312. if ( compare & 1 ||
  1313. (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
  1314. // Choose the first element that is related to our preferred document
  1315. if ( a === doc || contains(preferredDoc, a) ) {
  1316. return -1;
  1317. }
  1318. if ( b === doc || contains(preferredDoc, b) ) {
  1319. return 1;
  1320. }
  1321. // Maintain original order
  1322. return sortInput ?
  1323. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  1324. 0;
  1325. }
  1326. return compare & 4 ? -1 : 1;
  1327. }
  1328. // Not directly comparable, sort on existence of method
  1329. return a.compareDocumentPosition ? -1 : 1;
  1330. } :
  1331. function( a, b ) {
  1332. var cur,
  1333. i = 0,
  1334. aup = a.parentNode,
  1335. bup = b.parentNode,
  1336. ap = [ a ],
  1337. bp = [ b ];
  1338. // Exit early if the nodes are identical
  1339. if ( a === b ) {
  1340. hasDuplicate = true;
  1341. return 0;
  1342. // Parentless nodes are either documents or disconnected
  1343. } else if ( !aup || !bup ) {
  1344. return a === doc ? -1 :
  1345. b === doc ? 1 :
  1346. aup ? -1 :
  1347. bup ? 1 :
  1348. sortInput ?
  1349. ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :
  1350. 0;
  1351. // If the nodes are siblings, we can do a quick check
  1352. } else if ( aup === bup ) {
  1353. return siblingCheck( a, b );
  1354. }
  1355. // Otherwise we need full lists of their ancestors for comparison
  1356. cur = a;
  1357. while ( (cur = cur.parentNode) ) {
  1358. ap.unshift( cur );
  1359. }
  1360. cur = b;
  1361. while ( (cur = cur.parentNode) ) {
  1362. bp.unshift( cur );
  1363. }
  1364. // Walk down the tree looking for a discrepancy
  1365. while ( ap[i] === bp[i] ) {
  1366. i++;
  1367. }
  1368. return i ?
  1369. // Do a sibling check if the nodes have a common ancestor
  1370. siblingCheck( ap[i], bp[i] ) :
  1371. // Otherwise nodes in our document sort first
  1372. ap[i] === preferredDoc ? -1 :
  1373. bp[i] === preferredDoc ? 1 :
  1374. 0;
  1375. };
  1376. return doc;
  1377. };
  1378. Sizzle.matches = function( expr, elements ) {
  1379. return Sizzle( expr, null, null, elements );
  1380. };
  1381. Sizzle.matchesSelector = function( elem, expr ) {
  1382. // Set document vars if needed
  1383. if ( ( elem.ownerDocument || elem ) !== document ) {
  1384. setDocument( elem );
  1385. }
  1386. // Make sure that attribute selectors are quoted
  1387. expr = expr.replace( rattributeQuotes, "='$1']" );
  1388. if ( support.matchesSelector && documentIsHTML &&
  1389. ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
  1390. ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
  1391. try {
  1392. var ret = matches.call( elem, expr );
  1393. // IE 9's matchesSelector returns false on disconnected nodes
  1394. if ( ret || support.disconnectedMatch ||
  1395. // As well, disconnected nodes are said to be in a document
  1396. // fragment in IE 9
  1397. elem.document && elem.document.nodeType !== 11 ) {
  1398. return ret;
  1399. }
  1400. } catch(e) {}
  1401. }
  1402. return Sizzle( expr, document, null, [elem] ).length > 0;
  1403. };
  1404. Sizzle.contains = function( context, elem ) {
  1405. // Set document vars if needed
  1406. if ( ( context.ownerDocument || context ) !== document ) {
  1407. setDocument( context );
  1408. }
  1409. return contains( context, elem );
  1410. };
  1411. Sizzle.attr = function( elem, name ) {
  1412. // Set document vars if needed
  1413. if ( ( elem.ownerDocument || elem ) !== document ) {
  1414. setDocument( elem );
  1415. }
  1416. var fn = Expr.attrHandle[ name.toLowerCase() ],
  1417. // Don't get fooled by Object.prototype properties (jQuery #13807)
  1418. val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
  1419. fn( elem, name, !documentIsHTML ) :
  1420. undefined;
  1421. return val === undefined ?
  1422. support.attributes || !documentIsHTML ?
  1423. elem.getAttribute( name ) :
  1424. (val = elem.getAttributeNode(name)) && val.specified ?
  1425. val.value :
  1426. null :
  1427. val;
  1428. };
  1429. Sizzle.error = function( msg ) {
  1430. throw new Error( "Syntax error, unrecognized expression: " + msg );
  1431. };
  1432. /**
  1433. * Document sorting and removing duplicates
  1434. * @param {ArrayLike} results
  1435. */
  1436. Sizzle.uniqueSort = function( results ) {
  1437. var elem,
  1438. duplicates = [],
  1439. j = 0,
  1440. i = 0;
  1441. // Unless we *know* we can detect duplicates, assume their presence
  1442. hasDuplicate = !support.detectDuplicates;
  1443. sortInput = !support.sortStable && results.slice( 0 );
  1444. results.sort( sortOrder );
  1445. if ( hasDuplicate ) {
  1446. while ( (elem = results[i++]) ) {
  1447. if ( elem === results[ i ] ) {
  1448. j = duplicates.push( i );
  1449. }
  1450. }
  1451. while ( j-- ) {
  1452. results.splice( duplicates[ j ], 1 );
  1453. }
  1454. }
  1455. return results;
  1456. };
  1457. /**
  1458. * Utility function for retrieving the text value of an array of DOM nodes
  1459. * @param {Array|Element} elem
  1460. */
  1461. getText = Sizzle.getText = function( elem ) {
  1462. var node,
  1463. ret = "",
  1464. i = 0,
  1465. nodeType = elem.nodeType;
  1466. if ( !nodeType ) {
  1467. // If no nodeType, this is expected to be an array
  1468. for ( ; (node = elem[i]); i++ ) {
  1469. // Do not traverse comment nodes
  1470. ret += getText( node );
  1471. }
  1472. } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
  1473. // Use textContent for elements
  1474. // innerText usage removed for consistency of new lines (see #11153)
  1475. if ( typeof elem.textContent === "string" ) {
  1476. return elem.textContent;
  1477. } else {
  1478. // Traverse its children
  1479. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1480. ret += getText( elem );
  1481. }
  1482. }
  1483. } else if ( nodeType === 3 || nodeType === 4 ) {
  1484. return elem.nodeValue;
  1485. }
  1486. // Do not include comment or processing instruction nodes
  1487. return ret;
  1488. };
  1489. Expr = Sizzle.selectors = {
  1490. // Can be adjusted by the user
  1491. cacheLength: 50,
  1492. createPseudo: markFunction,
  1493. match: matchExpr,
  1494. attrHandle: {},
  1495. find: {},
  1496. relative: {
  1497. ">": { dir: "parentNode", first: true },
  1498. " ": { dir: "parentNode" },
  1499. "+": { dir: "previousSibling", first: true },
  1500. "~": { dir: "previousSibling" }
  1501. },
  1502. preFilter: {
  1503. "ATTR": function( match ) {
  1504. match[1] = match[1].replace( runescape, funescape );
  1505. // Move the given value to match[3] whether quoted or unquoted
  1506. match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
  1507. if ( match[2] === "~=" ) {
  1508. match[3] = " " + match[3] + " ";
  1509. }
  1510. return match.slice( 0, 4 );
  1511. },
  1512. "CHILD": function( match ) {
  1513. /* matches from matchExpr["CHILD"]
  1514. 1 type (only|nth|...)
  1515. 2 what (child|of-type)
  1516. 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
  1517. 4 xn-component of xn+y argument ([+-]?\d*n|)
  1518. 5 sign of xn-component
  1519. 6 x of xn-component
  1520. 7 sign of y-component
  1521. 8 y of y-component
  1522. */
  1523. match[1] = match[1].toLowerCase();
  1524. if ( match[1].slice( 0, 3 ) === "nth" ) {
  1525. // nth-* requires argument
  1526. if ( !match[3] ) {
  1527. Sizzle.error( match[0] );
  1528. }
  1529. // numeric x and y parameters for Expr.filter.CHILD
  1530. // remember that false/true cast respectively to 0/1
  1531. match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
  1532. match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
  1533. // other types prohibit arguments
  1534. } else if ( match[3] ) {
  1535. Sizzle.error( match[0] );
  1536. }
  1537. return match;
  1538. },
  1539. "PSEUDO": function( match ) {
  1540. var excess,
  1541. unquoted = !match[5] && match[2];
  1542. if ( matchExpr["CHILD"].test( match[0] ) ) {
  1543. return null;
  1544. }
  1545. // Accept quoted arguments as-is
  1546. if ( match[3] && match[4] !== undefined ) {
  1547. match[2] = match[4];
  1548. // Strip excess characters from unquoted arguments
  1549. } else if ( unquoted && rpseudo.test( unquoted ) &&
  1550. // Get excess from tokenize (recursively)
  1551. (excess = tokenize( unquoted, true )) &&
  1552. // advance to the next closing parenthesis
  1553. (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
  1554. // excess is a negative index
  1555. match[0] = match[0].slice( 0, excess );
  1556. match[2] = unquoted.slice( 0, excess );
  1557. }
  1558. // Return only captures needed by the pseudo filter method (type and argument)
  1559. return match.slice( 0, 3 );
  1560. }
  1561. },
  1562. filter: {
  1563. "TAG": function( nodeNameSelector ) {
  1564. var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
  1565. return nodeNameSelector === "*" ?
  1566. function() { return true; } :
  1567. function( elem ) {
  1568. return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
  1569. };
  1570. },
  1571. "CLASS": function( className ) {
  1572. var pattern = classCache[ className + " " ];
  1573. return pattern ||
  1574. (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
  1575. classCache( className, function( elem ) {
  1576. return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" );
  1577. });
  1578. },
  1579. "ATTR": function( name, operator, check ) {
  1580. return function( elem ) {
  1581. var result = Sizzle.attr( elem, name );
  1582. if ( result == null ) {
  1583. return operator === "!=";
  1584. }
  1585. if ( !operator ) {
  1586. return true;
  1587. }
  1588. result += "";
  1589. return operator === "=" ? result === check :
  1590. operator === "!=" ? result !== check :
  1591. operator === "^=" ? check && result.indexOf( check ) === 0 :
  1592. operator === "*=" ? check && result.indexOf( check ) > -1 :
  1593. operator === "$=" ? check && result.slice( -check.length ) === check :
  1594. operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
  1595. operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
  1596. false;
  1597. };
  1598. },
  1599. "CHILD": function( type, what, argument, first, last ) {
  1600. var simple = type.slice( 0, 3 ) !== "nth",
  1601. forward = type.slice( -4 ) !== "last",
  1602. ofType = what === "of-type";
  1603. return first === 1 && last === 0 ?
  1604. // Shortcut for :nth-*(n)
  1605. function( elem ) {
  1606. return !!elem.parentNode;
  1607. } :
  1608. function( elem, context, xml ) {
  1609. var cache, outerCache, node, diff, nodeIndex, start,
  1610. dir = simple !== forward ? "nextSibling" : "previousSibling",
  1611. parent = elem.parentNode,
  1612. name = ofType && elem.nodeName.toLowerCase(),
  1613. useCache = !xml && !ofType;
  1614. if ( parent ) {
  1615. // :(first|last|only)-(child|of-type)
  1616. if ( simple ) {
  1617. while ( dir ) {
  1618. node = elem;
  1619. while ( (node = node[ dir ]) ) {
  1620. if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
  1621. return false;
  1622. }
  1623. }
  1624. // Reverse direction for :only-* (if we haven't yet done so)
  1625. start = dir = type === "only" && !start && "nextSibling";
  1626. }
  1627. return true;
  1628. }
  1629. start = [ forward ? parent.firstChild : parent.lastChild ];
  1630. // non-xml :nth-child(...) stores cache data on `parent`
  1631. if ( forward && useCache ) {
  1632. // Seek `elem` from a previously-cached index
  1633. outerCache = parent[ expando ] || (parent[ expando ] = {});
  1634. cache = outerCache[ type ] || [];
  1635. nodeIndex = cache[0] === dirruns && cache[1];
  1636. diff = cache[0] === dirruns && cache[2];
  1637. node = nodeIndex && parent.childNodes[ nodeIndex ];
  1638. while ( (node = ++nodeIndex && node && node[ dir ] ||
  1639. // Fallback to seeking `elem` from the start
  1640. (diff = nodeIndex = 0) || start.pop()) ) {
  1641. // When found, cache indexes on `parent` and break
  1642. if ( node.nodeType === 1 && ++diff && node === elem ) {
  1643. outerCache[ type ] = [ dirruns, nodeIndex, diff ];
  1644. break;
  1645. }
  1646. }
  1647. // Use previously-cached element index if available
  1648. } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
  1649. diff = cache[1];
  1650. // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
  1651. } else {
  1652. // Use the same loop as above to seek `elem` from the start
  1653. while ( (node = ++nodeIndex && node && node[ dir ] ||
  1654. (diff = nodeIndex = 0) || start.pop()) ) {
  1655. if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
  1656. // Cache the index of each encountered element
  1657. if ( useCache ) {
  1658. (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
  1659. }
  1660. if ( node === elem ) {
  1661. break;
  1662. }
  1663. }
  1664. }
  1665. }
  1666. // Incorporate the offset, then check against cycle size
  1667. diff -= last;
  1668. return diff === first || ( diff % first === 0 && diff / first >= 0 );
  1669. }
  1670. };
  1671. },
  1672. "PSEUDO": function( pseudo, argument ) {
  1673. // pseudo-class names are case-insensitive
  1674. // http://www.w3.org/TR/selectors/#pseudo-classes
  1675. // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
  1676. // Remember that setFilters inherits from pseudos
  1677. var args,
  1678. fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
  1679. Sizzle.error( "unsupported pseudo: " + pseudo );
  1680. // The user may use createPseudo to indicate that
  1681. // arguments are needed to create the filter function
  1682. // just as Sizzle does
  1683. if ( fn[ expando ] ) {
  1684. return fn( argument );
  1685. }
  1686. // But maintain support for old signatures
  1687. if ( fn.length > 1 ) {
  1688. args = [ pseudo, pseudo, "", argument ];
  1689. return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
  1690. markFunction(function( seed, matches ) {
  1691. var idx,
  1692. matched = fn( seed, argument ),
  1693. i = matched.length;
  1694. while ( i-- ) {
  1695. idx = indexOf.call( seed, matched[i] );
  1696. seed[ idx ] = !( matches[ idx ] = matched[i] );
  1697. }
  1698. }) :
  1699. function( elem ) {
  1700. return fn( elem, 0, args );
  1701. };
  1702. }
  1703. return fn;
  1704. }
  1705. },
  1706. pseudos: {
  1707. // Potentially complex pseudos
  1708. "not": markFunction(function( selector ) {
  1709. // Trim the selector passed to compile
  1710. // to avoid treating leading and trailing
  1711. // spaces as combinators
  1712. var input = [],
  1713. results = [],
  1714. matcher = compile( selector.replace( rtrim, "$1" ) );
  1715. return matcher[ expando ] ?
  1716. markFunction(function( seed, matches, context, xml ) {
  1717. var elem,
  1718. unmatched = matcher( seed, null, xml, [] ),
  1719. i = seed.length;
  1720. // Match elements unmatched by `matcher`
  1721. while ( i-- ) {
  1722. if ( (elem = unmatched[i]) ) {
  1723. seed[i] = !(matches[i] = elem);
  1724. }
  1725. }
  1726. }) :
  1727. function( elem, context, xml ) {
  1728. input[0] = elem;
  1729. matcher( input, null, xml, results );
  1730. return !results.pop();
  1731. };
  1732. }),
  1733. "has": markFunction(function( selector ) {
  1734. return function( elem ) {
  1735. return Sizzle( selector, elem ).length > 0;
  1736. };
  1737. }),
  1738. "contains": markFunction(function( text ) {
  1739. return function( elem ) {
  1740. return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
  1741. };
  1742. }),
  1743. // "Whether an element is represented by a :lang() selector
  1744. // is based solely on the element's language value
  1745. // being equal to the identifier C,
  1746. // or beginning with the identifier C immediately followed by "-".
  1747. // The matching of C against the element's language value is performed case-insensitively.
  1748. // The identifier C does not have to be a valid language name."
  1749. // http://www.w3.org/TR/selectors/#lang-pseudo
  1750. "lang": markFunction( function( lang ) {
  1751. // lang value must be a valid identifier
  1752. if ( !ridentifier.test(lang || "") ) {
  1753. Sizzle.error( "unsupported lang: " + lang );
  1754. }
  1755. lang = lang.replace( runescape, funescape ).toLowerCase();
  1756. return function( elem ) {
  1757. var elemLang;
  1758. do {
  1759. if ( (elemLang = documentIsHTML ?
  1760. elem.lang :
  1761. elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
  1762. elemLang = elemLang.toLowerCase();
  1763. return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
  1764. }
  1765. } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
  1766. return false;
  1767. };
  1768. }),
  1769. // Miscellaneous
  1770. "target": function( elem ) {
  1771. var hash = window.location && window.location.hash;
  1772. return hash && hash.slice( 1 ) === elem.id;
  1773. },
  1774. "root": function( elem ) {
  1775. return elem === docElem;
  1776. },
  1777. "focus": function( elem ) {
  1778. return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
  1779. },
  1780. // Boolean properties
  1781. "enabled": function( elem ) {
  1782. return elem.disabled === false;
  1783. },
  1784. "disabled": function( elem ) {
  1785. return elem.disabled === true;
  1786. },
  1787. "checked": function( elem ) {
  1788. // In CSS3, :checked should return both checked and selected elements
  1789. // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
  1790. var nodeName = elem.nodeName.toLowerCase();
  1791. return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
  1792. },
  1793. "selected": function( elem ) {
  1794. // Accessing this property makes selected-by-default
  1795. // options in Safari work properly
  1796. if ( elem.parentNode ) {
  1797. elem.parentNode.selectedIndex;
  1798. }
  1799. return elem.selected === true;
  1800. },
  1801. // Contents
  1802. "empty": function( elem ) {
  1803. // http://www.w3.org/TR/selectors/#empty-pseudo
  1804. // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),
  1805. // not comment, processing instructions, or others
  1806. // Thanks to Diego Perini for the nodeName shortcut
  1807. // Greater than "@" means alpha characters (specifically not starting with "#" or "?")
  1808. for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
  1809. if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
  1810. return false;
  1811. }
  1812. }
  1813. return true;
  1814. },
  1815. "parent": function( elem ) {
  1816. return !Expr.pseudos["empty"]( elem );
  1817. },
  1818. // Element/input types
  1819. "header": function( elem ) {
  1820. return rheader.test( elem.nodeName );
  1821. },
  1822. "input": function( elem ) {
  1823. return rinputs.test( elem.nodeName );
  1824. },
  1825. "button": function( elem ) {
  1826. var name = elem.nodeName.toLowerCase();
  1827. return name === "input" && elem.type === "button" || name === "button";
  1828. },
  1829. "text": function( elem ) {
  1830. var attr;
  1831. // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)
  1832. // use getAttribute instead to test this case
  1833. return elem.nodeName.toLowerCase() === "input" &&
  1834. elem.type === "text" &&
  1835. ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
  1836. },
  1837. // Position-in-collection
  1838. "first": createPositionalPseudo(function() {
  1839. return [ 0 ];
  1840. }),
  1841. "last": createPositionalPseudo(function( matchIndexes, length ) {
  1842. return [ length - 1 ];
  1843. }),
  1844. "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1845. return [ argument < 0 ? argument + length : argument ];
  1846. }),
  1847. "even": createPositionalPseudo(function( matchIndexes, length ) {
  1848. var i = 0;
  1849. for ( ; i < length; i += 2 ) {
  1850. matchIndexes.push( i );
  1851. }
  1852. return matchIndexes;
  1853. }),
  1854. "odd": createPositionalPseudo(function( matchIndexes, length ) {
  1855. var i = 1;
  1856. for ( ; i < length; i += 2 ) {
  1857. matchIndexes.push( i );
  1858. }
  1859. return matchIndexes;
  1860. }),
  1861. "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1862. var i = argument < 0 ? argument + length : argument;
  1863. for ( ; --i >= 0; ) {
  1864. matchIndexes.push( i );
  1865. }
  1866. return matchIndexes;
  1867. }),
  1868. "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
  1869. var i = argument < 0 ? argument + length : argument;
  1870. for ( ; ++i < length; ) {
  1871. matchIndexes.push( i );
  1872. }
  1873. return matchIndexes;
  1874. })
  1875. }
  1876. };
  1877. Expr.pseudos["nth"] = Expr.pseudos["eq"];
  1878. // Add button/input type pseudos
  1879. for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
  1880. Expr.pseudos[ i ] = createInputPseudo( i );
  1881. }
  1882. for ( i in { submit: true, reset: true } ) {
  1883. Expr.pseudos[ i ] = createButtonPseudo( i );
  1884. }
  1885. // Easy API for creating new setFilters
  1886. function setFilters() {}
  1887. setFilters.prototype = Expr.filters = Expr.pseudos;
  1888. Expr.setFilters = new setFilters();
  1889. function tokenize( selector, parseOnly ) {
  1890. var matched, match, tokens, type,
  1891. soFar, groups, preFilters,
  1892. cached = tokenCache[ selector + " " ];
  1893. if ( cached ) {
  1894. return parseOnly ? 0 : cached.slice( 0 );
  1895. }
  1896. soFar = selector;
  1897. groups = [];
  1898. preFilters = Expr.preFilter;
  1899. while ( soFar ) {
  1900. // Comma and first run
  1901. if ( !matched || (match = rcomma.exec( soFar )) ) {
  1902. if ( match ) {
  1903. // Don't consume trailing commas as valid
  1904. soFar = soFar.slice( match[0].length ) || soFar;
  1905. }
  1906. groups.push( tokens = [] );
  1907. }
  1908. matched = false;
  1909. // Combinators
  1910. if ( (match = rcombinators.exec( soFar )) ) {
  1911. matched = match.shift();
  1912. tokens.push({
  1913. value: matched,
  1914. // Cast descendant combinators to space
  1915. type: match[0].replace( rtrim, " " )
  1916. });
  1917. soFar = soFar.slice( matched.length );
  1918. }
  1919. // Filters
  1920. for ( type in Expr.filter ) {
  1921. if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
  1922. (match = preFilters[ type ]( match ))) ) {
  1923. matched = match.shift();
  1924. tokens.push({
  1925. value: matched,
  1926. type: type,
  1927. matches: match
  1928. });
  1929. soFar = soFar.slice( matched.length );
  1930. }
  1931. }
  1932. if ( !matched ) {
  1933. break;
  1934. }
  1935. }
  1936. // Return the length of the invalid excess
  1937. // if we're just parsing
  1938. // Otherwise, throw an error or return tokens
  1939. return parseOnly ?
  1940. soFar.length :
  1941. soFar ?
  1942. Sizzle.error( selector ) :
  1943. // Cache the tokens
  1944. tokenCache( selector, groups ).slice( 0 );
  1945. }
  1946. function toSelector( tokens ) {
  1947. var i = 0,
  1948. len = tokens.length,
  1949. selector = "";
  1950. for ( ; i < len; i++ ) {
  1951. selector += tokens[i].value;
  1952. }
  1953. return selector;
  1954. }
  1955. function addCombinator( matcher, combinator, base ) {
  1956. var dir = combinator.dir,
  1957. checkNonElements = base && dir === "parentNode",
  1958. doneName = done++;
  1959. return combinator.first ?
  1960. // Check against closest ancestor/preceding element
  1961. function( elem, context, xml ) {
  1962. while ( (elem = elem[ dir ]) ) {
  1963. if ( elem.nodeType === 1 || checkNonElements ) {
  1964. return matcher( elem, context, xml );
  1965. }
  1966. }
  1967. } :
  1968. // Check against all ancestor/preceding elements
  1969. function( elem, context, xml ) {
  1970. var data, cache, outerCache,
  1971. dirkey = dirruns + " " + doneName;
  1972. // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
  1973. if ( xml ) {
  1974. while ( (elem = elem[ dir ]) ) {
  1975. if ( elem.nodeType === 1 || checkNonElements ) {
  1976. if ( matcher( elem, context, xml ) ) {
  1977. return true;
  1978. }
  1979. }
  1980. }
  1981. } else {
  1982. while ( (elem = elem[ dir ]) ) {
  1983. if ( elem.nodeType === 1 || checkNonElements ) {
  1984. outerCache = elem[ expando ] || (elem[ expando ] = {});
  1985. if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
  1986. if ( (data = cache[1]) === true || data === cachedruns ) {
  1987. return data === true;
  1988. }
  1989. } else {
  1990. cache = outerCache[ dir ] = [ dirkey ];
  1991. cache[1] = matcher( elem, context, xml ) || cachedruns;
  1992. if ( cache[1] === true ) {
  1993. return true;
  1994. }
  1995. }
  1996. }
  1997. }
  1998. }
  1999. };
  2000. }
  2001. function elementMatcher( matchers ) {
  2002. return matchers.length > 1 ?
  2003. function( elem, context, xml ) {
  2004. var i = matchers.length;
  2005. while ( i-- ) {
  2006. if ( !matchers[i]( elem, context, xml ) ) {
  2007. return false;
  2008. }
  2009. }
  2010. return true;
  2011. } :
  2012. matchers[0];
  2013. }
  2014. function condense( unmatched, map, filter, context, xml ) {
  2015. var elem,
  2016. newUnmatched = [],
  2017. i = 0,
  2018. len = unmatched.length,
  2019. mapped = map != null;
  2020. for ( ; i < len; i++ ) {
  2021. if ( (elem = unmatched[i]) ) {
  2022. if ( !filter || filter( elem, context, xml ) ) {
  2023. newUnmatched.push( elem );
  2024. if ( mapped ) {
  2025. map.push( i );
  2026. }
  2027. }
  2028. }
  2029. }
  2030. return newUnmatched;
  2031. }
  2032. function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
  2033. if ( postFilter && !postFilter[ expando ] ) {
  2034. postFilter = setMatcher( postFilter );
  2035. }
  2036. if ( postFinder && !postFinder[ expando ] ) {
  2037. postFinder = setMatcher( postFinder, postSelector );
  2038. }
  2039. return markFunction(function( seed, results, context, xml ) {
  2040. var temp, i, elem,
  2041. preMap = [],
  2042. postMap = [],
  2043. preexisting = results.length,
  2044. // Get initial elements from seed or context
  2045. elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
  2046. // Prefilter to get matcher input, preserving a map for seed-results synchronization
  2047. matcherIn = preFilter && ( seed || !selector ) ?
  2048. condense( elems, preMap, preFilter, context, xml ) :
  2049. elems,
  2050. matcherOut = matcher ?
  2051. // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
  2052. postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
  2053. // ...intermediate processing is necessary
  2054. [] :
  2055. // ...otherwise use results directly
  2056. results :
  2057. matcherIn;
  2058. // Find primary matches
  2059. if ( matcher ) {
  2060. matcher( matcherIn, matcherOut, context, xml );
  2061. }
  2062. // Apply postFilter
  2063. if ( postFilter ) {
  2064. temp = condense( matcherOut, postMap );
  2065. postFilter( temp, [], context, xml );
  2066. // Un-match failing elements by moving them back to matcherIn
  2067. i = temp.length;
  2068. while ( i-- ) {
  2069. if ( (elem = temp[i]) ) {
  2070. matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
  2071. }
  2072. }
  2073. }
  2074. if ( seed ) {
  2075. if ( postFinder || preFilter ) {
  2076. if ( postFinder ) {
  2077. // Get the final matcherOut by condensing this intermediate into postFinder contexts
  2078. temp = [];
  2079. i = matcherOut.length;
  2080. while ( i-- ) {
  2081. if ( (elem = matcherOut[i]) ) {
  2082. // Restore matcherIn since elem is not yet a final match
  2083. temp.push( (matcherIn[i] = elem) );
  2084. }
  2085. }
  2086. postFinder( null, (matcherOut = []), temp, xml );
  2087. }
  2088. // Move matched elements from seed to results to keep them synchronized
  2089. i = matcherOut.length;
  2090. while ( i-- ) {
  2091. if ( (elem = matcherOut[i]) &&
  2092. (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {
  2093. seed[temp] = !(results[temp] = elem);
  2094. }
  2095. }
  2096. }
  2097. // Add elements to results, through postFinder if defined
  2098. } else {
  2099. matcherOut = condense(
  2100. matcherOut === results ?
  2101. matcherOut.splice( preexisting, matcherOut.length ) :
  2102. matcherOut
  2103. );
  2104. if ( postFinder ) {
  2105. postFinder( null, results, matcherOut, xml );
  2106. } else {
  2107. push.apply( results, matcherOut );
  2108. }
  2109. }
  2110. });
  2111. }
  2112. function matcherFromTokens( tokens ) {
  2113. var checkContext, matcher, j,
  2114. len = tokens.length,
  2115. leadingRelative = Expr.relative[ tokens[0].type ],
  2116. implicitRelative = leadingRelative || Expr.relative[" "],
  2117. i = leadingRelative ? 1 : 0,
  2118. // The foundational matcher ensures that elements are reachable from top-level context(s)
  2119. matchContext = addCombinator( function( elem ) {
  2120. return elem === checkContext;
  2121. }, implicitRelative, true ),
  2122. matchAnyContext = addCombinator( function( elem ) {
  2123. return indexOf.call( checkContext, elem ) > -1;
  2124. }, implicitRelative, true ),
  2125. matchers = [ function( elem, context, xml ) {
  2126. return ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
  2127. (checkContext = context).nodeType ?
  2128. matchContext( elem, context, xml ) :
  2129. matchAnyContext( elem, context, xml ) );
  2130. } ];
  2131. for ( ; i < len; i++ ) {
  2132. if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
  2133. matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
  2134. } else {
  2135. matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
  2136. // Return special upon seeing a positional matcher
  2137. if ( matcher[ expando ] ) {
  2138. // Find the next relative operator (if any) for proper handling
  2139. j = ++i;
  2140. for ( ; j < len; j++ ) {
  2141. if ( Expr.relative[ tokens[j].type ] ) {
  2142. break;
  2143. }
  2144. }
  2145. return setMatcher(
  2146. i > 1 && elementMatcher( matchers ),
  2147. i > 1 && toSelector(
  2148. // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  2149. tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
  2150. ).replace( rtrim, "$1" ),
  2151. matcher,
  2152. i < j && matcherFromTokens( tokens.slice( i, j ) ),
  2153. j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
  2154. j < len && toSelector( tokens )
  2155. );
  2156. }
  2157. matchers.push( matcher );
  2158. }
  2159. }
  2160. return elementMatcher( matchers );
  2161. }
  2162. function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  2163. // A counter to specify which element is currently being matched
  2164. var matcherCachedRuns = 0,
  2165. bySet = setMatchers.length > 0,
  2166. byElement = elementMatchers.length > 0,
  2167. superMatcher = function( seed, context, xml, results, expandContext ) {
  2168. var elem, j, matcher,
  2169. setMatched = [],
  2170. matchedCount = 0,
  2171. i = "0",
  2172. unmatched = seed && [],
  2173. outermost = expandContext != null,
  2174. contextBackup = outermostContext,
  2175. // We must always have either seed elements or context
  2176. elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ),
  2177. // Use integer dirruns iff this is the outermost matcher
  2178. dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
  2179. if ( outermost ) {
  2180. outermostContext = context !== document && context;
  2181. cachedruns = matcherCachedRuns;
  2182. }
  2183. // Add elements passing elementMatchers directly to results
  2184. // Keep `i` a string if there are no elements so `matchedCount` will be "00" below
  2185. for ( ; (elem = elems[i]) != null; i++ ) {
  2186. if ( byElement && elem ) {
  2187. j = 0;
  2188. while ( (matcher = elementMatchers[j++]) ) {
  2189. if ( matcher( elem, context, xml ) ) {
  2190. results.push( elem );
  2191. break;
  2192. }
  2193. }
  2194. if ( outermost ) {
  2195. dirruns = dirrunsUnique;
  2196. cachedruns = ++matcherCachedRuns;
  2197. }
  2198. }
  2199. // Track unmatched elements for set filters
  2200. if ( bySet ) {
  2201. // They will have gone through all possible matchers
  2202. if ( (elem = !matcher && elem) ) {
  2203. matchedCount--;
  2204. }
  2205. // Lengthen the array for every element, matched or not
  2206. if ( seed ) {
  2207. unmatched.push( elem );
  2208. }
  2209. }
  2210. }
  2211. // Apply set filters to unmatched elements
  2212. matchedCount += i;
  2213. if ( bySet && i !== matchedCount ) {
  2214. j = 0;
  2215. while ( (matcher = setMatchers[j++]) ) {
  2216. matcher( unmatched, setMatched, context, xml );
  2217. }
  2218. if ( seed ) {
  2219. // Reintegrate element matches to eliminate the need for sorting
  2220. if ( matchedCount > 0 ) {
  2221. while ( i-- ) {
  2222. if ( !(unmatched[i] || setMatched[i]) ) {
  2223. setMatched[i] = pop.call( results );
  2224. }
  2225. }
  2226. }
  2227. // Discard index placeholder values to get only actual matches
  2228. setMatched = condense( setMatched );
  2229. }
  2230. // Add matches to results
  2231. push.apply( results, setMatched );
  2232. // Seedless set matches succeeding multiple successful matchers stipulate sorting
  2233. if ( outermost && !seed && setMatched.length > 0 &&
  2234. ( matchedCount + setMatchers.length ) > 1 ) {
  2235. Sizzle.uniqueSort( results );
  2236. }
  2237. }
  2238. // Override manipulation of globals by nested matchers
  2239. if ( outermost ) {
  2240. dirruns = dirrunsUnique;
  2241. outermostContext = contextBackup;
  2242. }
  2243. return unmatched;
  2244. };
  2245. return bySet ?
  2246. markFunction( superMatcher ) :
  2247. superMatcher;
  2248. }
  2249. compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
  2250. var i,
  2251. setMatchers = [],
  2252. elementMatchers = [],
  2253. cached = compilerCache[ selector + " " ];
  2254. if ( !cached ) {
  2255. // Generate a function of recursive functions that can be used to check each element
  2256. if ( !group ) {
  2257. group = tokenize( selector );
  2258. }
  2259. i = group.length;
  2260. while ( i-- ) {
  2261. cached = matcherFromTokens( group[i] );
  2262. if ( cached[ expando ] ) {
  2263. setMatchers.push( cached );
  2264. } else {
  2265. elementMatchers.push( cached );
  2266. }
  2267. }
  2268. // Cache the compiled function
  2269. cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
  2270. }
  2271. return cached;
  2272. };
  2273. function multipleContexts( selector, contexts, results ) {
  2274. var i = 0,
  2275. len = contexts.length;
  2276. for ( ; i < len; i++ ) {
  2277. Sizzle( selector, contexts[i], results );
  2278. }
  2279. return results;
  2280. }
  2281. function select( selector, context, results, seed ) {
  2282. var i, tokens, token, type, find,
  2283. match = tokenize( selector );
  2284. if ( !seed ) {
  2285. // Try to minimize operations if there is only one group
  2286. if ( match.length === 1 ) {
  2287. // Take a shortcut and set the context if the root selector is an ID
  2288. tokens = match[0] = match[0].slice( 0 );
  2289. if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
  2290. support.getById && context.nodeType === 9 && documentIsHTML &&
  2291. Expr.relative[ tokens[1].type ] ) {
  2292. context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
  2293. if ( !context ) {
  2294. return results;
  2295. }
  2296. selector = selector.slice( tokens.shift().value.length );
  2297. }
  2298. // Fetch a seed set for right-to-left matching
  2299. i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
  2300. while ( i-- ) {
  2301. token = tokens[i];
  2302. // Abort if we hit a combinator
  2303. if ( Expr.relative[ (type = token.type) ] ) {
  2304. break;
  2305. }
  2306. if ( (find = Expr.find[ type ]) ) {
  2307. // Search, expanding context for leading sibling combinators
  2308. if ( (seed = find(
  2309. token.matches[0].replace( runescape, funescape ),
  2310. rsibling.test( tokens[0].type ) && context.parentNode || context
  2311. )) ) {
  2312. // If seed is empty or no tokens remain, we can return early
  2313. tokens.splice( i, 1 );
  2314. selector = seed.length && toSelector( tokens );
  2315. if ( !selector ) {
  2316. push.apply( results, seed );
  2317. return results;
  2318. }
  2319. break;
  2320. }
  2321. }
  2322. }
  2323. }
  2324. }
  2325. // Compile and execute a filtering function
  2326. // Provide `match` to avoid retokenization if we modified the selector above
  2327. compile( selector, match )(
  2328. seed,
  2329. context,
  2330. !documentIsHTML,
  2331. results,
  2332. rsibling.test( selector )
  2333. );
  2334. return results;
  2335. }
  2336. // One-time assignments
  2337. // Sort stability
  2338. support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
  2339. // Support: Chrome<14
  2340. // Always assume duplicates if they aren't passed to the comparison function
  2341. support.detectDuplicates = hasDuplicate;
  2342. // Initialize against the default document
  2343. setDocument();
  2344. // Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
  2345. // Detached nodes confoundingly follow *each other*
  2346. support.sortDetached = assert(function( div1 ) {
  2347. // Should return 1, but returns 4 (following)
  2348. return div1.compareDocumentPosition( document.createElement("div") ) & 1;
  2349. });
  2350. // Support: IE<8
  2351. // Prevent attribute/property "interpolation"
  2352. // http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
  2353. if ( !assert(function( div ) {
  2354. div.innerHTML = "<a href='#'></a>";
  2355. return div.firstChild.getAttribute("href") === "#" ;
  2356. }) ) {
  2357. addHandle( "type|href|height|width", function( elem, name, isXML ) {
  2358. if ( !isXML ) {
  2359. return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
  2360. }
  2361. });
  2362. }
  2363. // Support: IE<9
  2364. // Use defaultValue in place of getAttribute("value")
  2365. if ( !support.attributes || !assert(function( div ) {
  2366. div.innerHTML = "<input/>";
  2367. div.firstChild.setAttribute( "value", "" );
  2368. return div.firstChild.getAttribute( "value" ) === "";
  2369. }) ) {
  2370. addHandle( "value", function( elem, name, isXML ) {
  2371. if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
  2372. return elem.defaultValue;
  2373. }
  2374. });
  2375. }
  2376. // Support: IE<9
  2377. // Use getAttributeNode to fetch booleans when getAttribute lies
  2378. if ( !assert(function( div ) {
  2379. return div.getAttribute("disabled") == null;
  2380. }) ) {
  2381. addHandle( booleans, function( elem, name, isXML ) {
  2382. var val;
  2383. if ( !isXML ) {
  2384. return (val = elem.getAttributeNode( name )) && val.specified ?
  2385. val.value :
  2386. elem[ name ] === true ? name.toLowerCase() : null;
  2387. }
  2388. });
  2389. }
  2390. jQuery.find = Sizzle;
  2391. jQuery.expr = Sizzle.selectors;
  2392. jQuery.expr[":"] = jQuery.expr.pseudos;
  2393. jQuery.unique = Sizzle.uniqueSort;
  2394. jQuery.text = Sizzle.getText;
  2395. jQuery.isXMLDoc = Sizzle.isXML;
  2396. jQuery.contains = Sizzle.contains;
  2397. })( window );
  2398. // String to Object options format cache
  2399. var optionsCache = {};
  2400. // Convert String-formatted options into Object-formatted ones and store in cache
  2401. function createOptions( options ) {
  2402. var object = optionsCache[ options ] = {};
  2403. jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {
  2404. object[ flag ] = true;
  2405. });
  2406. return object;
  2407. }
  2408. /*
  2409. * Create a callback list using the following parameters:
  2410. *
  2411. * options: an optional list of space-separated options that will change how
  2412. * the callback list behaves or a more traditional option object
  2413. *
  2414. * By default a callback list will act like an event callback list and can be
  2415. * "fired" multiple times.
  2416. *
  2417. * Possible options:
  2418. *
  2419. * once: will ensure the callback list can only be fired once (like a Deferred)
  2420. *
  2421. * memory: will keep track of previous values and will call any callback added
  2422. * after the list has been fired right away with the latest "memorized"
  2423. * values (like a Deferred)
  2424. *
  2425. * unique: will ensure a callback can only be added once (no duplicate in the list)
  2426. *
  2427. * stopOnFalse: interrupt callings when a callback returns false
  2428. *
  2429. */
  2430. jQuery.Callbacks = function( options ) {
  2431. // Convert options from String-formatted to Object-formatted if needed
  2432. // (we check in cache first)
  2433. options = typeof options === "string" ?
  2434. ( optionsCache[ options ] || createOptions( options ) ) :
  2435. jQuery.extend( {}, options );
  2436. var // Last fire value (for non-forgettable lists)
  2437. memory,
  2438. // Flag to know if list was already fired
  2439. fired,
  2440. // Flag to know if list is currently firing
  2441. firing,
  2442. // First callback to fire (used internally by add and fireWith)
  2443. firingStart,
  2444. // End of the loop when firing
  2445. firingLength,
  2446. // Index of currently firing callback (modified by remove if needed)
  2447. firingIndex,
  2448. // Actual callback list
  2449. list = [],
  2450. // Stack of fire calls for repeatable lists
  2451. stack = !options.once && [],
  2452. // Fire callbacks
  2453. fire = function( data ) {
  2454. memory = options.memory && data;
  2455. fired = true;
  2456. firingIndex = firingStart || 0;
  2457. firingStart = 0;
  2458. firingLength = list.length;
  2459. firing = true;
  2460. for ( ; list && firingIndex < firingLength; firingIndex++ ) {
  2461. if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {
  2462. memory = false; // To prevent further calls using add
  2463. break;
  2464. }
  2465. }
  2466. firing = false;
  2467. if ( list ) {
  2468. if ( stack ) {
  2469. if ( stack.length ) {
  2470. fire( stack.shift() );
  2471. }
  2472. } else if ( memory ) {
  2473. list = [];
  2474. } else {
  2475. self.disable();
  2476. }
  2477. }
  2478. },
  2479. // Actual Callbacks object
  2480. self = {
  2481. // Add a callback or a collection of callbacks to the list
  2482. add: function() {
  2483. if ( list ) {
  2484. // First, we save the current length
  2485. var start = list.length;
  2486. (function add( args ) {
  2487. jQuery.each( args, function( _, arg ) {
  2488. var type = jQuery.type( arg );
  2489. if ( type === "function" ) {
  2490. if ( !options.unique || !self.has( arg ) ) {
  2491. list.push( arg );
  2492. }
  2493. } else if ( arg && arg.length && type !== "string" ) {
  2494. // Inspect recursively
  2495. add( arg );
  2496. }
  2497. });
  2498. })( arguments );
  2499. // Do we need to add the callbacks to the
  2500. // current firing batch?
  2501. if ( firing ) {
  2502. firingLength = list.length;
  2503. // With memory, if we're not firing then
  2504. // we should call right away
  2505. } else if ( memory ) {
  2506. firingStart = start;
  2507. fire( memory );
  2508. }
  2509. }
  2510. return this;
  2511. },
  2512. // Remove a callback from the list
  2513. remove: function() {
  2514. if ( list ) {
  2515. jQuery.each( arguments, function( _, arg ) {
  2516. var index;
  2517. while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
  2518. list.splice( index, 1 );
  2519. // Handle firing indexes
  2520. if ( firing ) {
  2521. if ( index <= firingLength ) {
  2522. firingLength--;
  2523. }
  2524. if ( index <= firingIndex ) {
  2525. firingIndex--;
  2526. }
  2527. }
  2528. }
  2529. });
  2530. }
  2531. return this;
  2532. },
  2533. // Check if a given callback is in the list.
  2534. // If no argument is given, return whether or not list has callbacks attached.
  2535. has: function( fn ) {
  2536. return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
  2537. },
  2538. // Remove all callbacks from the list
  2539. empty: function() {
  2540. list = [];
  2541. firingLength = 0;
  2542. return this;
  2543. },
  2544. // Have the list do nothing anymore
  2545. disable: function() {
  2546. list = stack = memory = undefined;
  2547. return this;
  2548. },
  2549. // Is it disabled?
  2550. disabled: function() {
  2551. return !list;
  2552. },
  2553. // Lock the list in its current state
  2554. lock: function() {
  2555. stack = undefined;
  2556. if ( !memory ) {
  2557. self.disable();
  2558. }
  2559. return this;
  2560. },
  2561. // Is it locked?
  2562. locked: function() {
  2563. return !stack;
  2564. },
  2565. // Call all callbacks with the given context and arguments
  2566. fireWith: function( context, args ) {
  2567. if ( list && ( !fired || stack ) ) {
  2568. args = args || [];
  2569. args = [ context, args.slice ? args.slice() : args ];
  2570. if ( firing ) {
  2571. stack.push( args );
  2572. } else {
  2573. fire( args );
  2574. }
  2575. }
  2576. return this;
  2577. },
  2578. // Call all the callbacks with the given arguments
  2579. fire: function() {
  2580. self.fireWith( this, arguments );
  2581. return this;
  2582. },
  2583. // To know if the callbacks have already been called at least once
  2584. fired: function() {
  2585. return !!fired;
  2586. }
  2587. };
  2588. return self;
  2589. };
  2590. jQuery.extend({
  2591. Deferred: function( func ) {
  2592. var tuples = [
  2593. // action, add listener, listener list, final state
  2594. [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ],
  2595. [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ],
  2596. [ "notify", "progress", jQuery.Callbacks("memory") ]
  2597. ],
  2598. state = "pending",
  2599. promise = {
  2600. state: function() {
  2601. return state;
  2602. },
  2603. always: function() {
  2604. deferred.done( arguments ).fail( arguments );
  2605. return this;
  2606. },
  2607. then: function( /* fnDone, fnFail, fnProgress */ ) {
  2608. var fns = arguments;
  2609. return jQuery.Deferred(function( newDefer ) {
  2610. jQuery.each( tuples, function( i, tuple ) {
  2611. var action = tuple[ 0 ],
  2612. fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
  2613. // deferred[ done | fail | progress ] for forwarding actions to newDefer
  2614. deferred[ tuple[1] ](function() {
  2615. var returned = fn && fn.apply( this, arguments );
  2616. if ( returned && jQuery.isFunction( returned.promise ) ) {
  2617. returned.promise()
  2618. .done( newDefer.resolve )
  2619. .fail( newDefer.reject )
  2620. .progress( newDefer.notify );
  2621. } else {
  2622. newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
  2623. }
  2624. });
  2625. });
  2626. fns = null;
  2627. }).promise();
  2628. },
  2629. // Get a promise for this deferred
  2630. // If obj is provided, the promise aspect is added to the object
  2631. promise: function( obj ) {
  2632. return obj != null ? jQuery.extend( obj, promise ) : promise;
  2633. }
  2634. },
  2635. deferred = {};
  2636. // Keep pipe for back-compat
  2637. promise.pipe = promise.then;
  2638. // Add list-specific methods
  2639. jQuery.each( tuples, function( i, tuple ) {
  2640. var list = tuple[ 2 ],
  2641. stateString = tuple[ 3 ];
  2642. // promise[ done | fail | progress ] = list.add
  2643. promise[ tuple[1] ] = list.add;
  2644. // Handle state
  2645. if ( stateString ) {
  2646. list.add(function() {
  2647. // state = [ resolved | rejected ]
  2648. state = stateString;
  2649. // [ reject_list | resolve_list ].disable; progress_list.lock
  2650. }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
  2651. }
  2652. // deferred[ resolve | reject | notify ]
  2653. deferred[ tuple[0] ] = function() {
  2654. deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
  2655. return this;
  2656. };
  2657. deferred[ tuple[0] + "With" ] = list.fireWith;
  2658. });
  2659. // Make the deferred a promise
  2660. promise.promise( deferred );
  2661. // Call given func if any
  2662. if ( func ) {
  2663. func.call( deferred, deferred );
  2664. }
  2665. // All done!
  2666. return deferred;
  2667. },
  2668. // Deferred helper
  2669. when: function( subordinate /* , ..., subordinateN */ ) {
  2670. var i = 0,
  2671. resolveValues = core_slice.call( arguments ),
  2672. length = resolveValues.length,
  2673. // the count of uncompleted subordinates
  2674. remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
  2675. // the master Deferred. If resolveValues consist of only a single Deferred, just use that.
  2676. deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
  2677. // Update function for both resolve and progress values
  2678. updateFunc = function( i, contexts, values ) {
  2679. return function( value ) {
  2680. contexts[ i ] = this;
  2681. values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;
  2682. if( values === progressValues ) {
  2683. deferred.notifyWith( contexts, values );
  2684. } else if ( !( --remaining ) ) {
  2685. deferred.resolveWith( contexts, values );
  2686. }
  2687. };
  2688. },
  2689. progressValues, progressContexts, resolveContexts;
  2690. // add listeners to Deferred subordinates; treat others as resolved
  2691. if ( length > 1 ) {
  2692. progressValues = new Array( length );
  2693. progressContexts = new Array( length );
  2694. resolveContexts = new Array( length );
  2695. for ( ; i < length; i++ ) {
  2696. if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
  2697. resolveValues[ i ].promise()
  2698. .done( updateFunc( i, resolveContexts, resolveValues ) )
  2699. .fail( deferred.reject )
  2700. .progress( updateFunc( i, progressContexts, progressValues ) );
  2701. } else {
  2702. --remaining;
  2703. }
  2704. }
  2705. }
  2706. // if we're not waiting on anything, resolve the master
  2707. if ( !remaining ) {
  2708. deferred.resolveWith( resolveContexts, resolveValues );
  2709. }
  2710. return deferred.promise();
  2711. }
  2712. });
  2713. jQuery.support = (function( support ) {
  2714. var input = document.createElement("input"),
  2715. fragment = document.createDocumentFragment(),
  2716. div = document.createElement("div"),
  2717. select = document.createElement("select"),
  2718. opt = select.appendChild( document.createElement("option") );
  2719. // Finish early in limited environments
  2720. if ( !input.type ) {
  2721. return support;
  2722. }
  2723. input.type = "checkbox";
  2724. // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
  2725. // Check the default checkbox/radio value ("" on old WebKit; "on" elsewhere)
  2726. support.checkOn = input.value !== "";
  2727. // Must access the parent to make an option select properly
  2728. // Support: IE9, IE10
  2729. support.optSelected = opt.selected;
  2730. // Will be defined later
  2731. support.reliableMarginRight = true;
  2732. support.boxSizingReliable = true;
  2733. support.pixelPosition = false;
  2734. // Make sure checked status is properly cloned
  2735. // Support: IE9, IE10
  2736. input.checked = true;
  2737. support.noCloneChecked = input.cloneNode( true ).checked;
  2738. // Make sure that the options inside disabled selects aren't marked as disabled
  2739. // (WebKit marks them as disabled)
  2740. select.disabled = true;
  2741. support.optDisabled = !opt.disabled;
  2742. // Check if an input maintains its value after becoming a radio
  2743. // Support: IE9, IE10
  2744. input = document.createElement("input");
  2745. input.value = "t";
  2746. input.type = "radio";
  2747. support.radioValue = input.value === "t";
  2748. // #11217 - WebKit loses check when the name is after the checked attribute
  2749. input.setAttribute( "checked", "t" );
  2750. input.setAttribute( "name", "t" );
  2751. fragment.appendChild( input );
  2752. // Support: Safari 5.1, Android 4.x, Android 2.3
  2753. // old WebKit doesn't clone checked state correctly in fragments
  2754. support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
  2755. // Support: Firefox, Chrome, Safari
  2756. // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
  2757. support.focusinBubbles = "onfocusin" in window;
  2758. div.style.backgroundClip = "content-box";
  2759. div.cloneNode( true ).style.backgroundClip = "";
  2760. support.clearCloneStyle = div.style.backgroundClip === "content-box";
  2761. // Run tests that need a body at doc ready
  2762. jQuery(function() {
  2763. var container, marginDiv,
  2764. // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
  2765. divReset = "padding:0;margin:0;border:0;display:block;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box",
  2766. body = document.getElementsByTagName("body")[ 0 ];
  2767. if ( !body ) {
  2768. // Return for frameset docs that don't have a body
  2769. return;
  2770. }
  2771. container = document.createElement("div");
  2772. container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
  2773. // Check box-sizing and margin behavior.
  2774. body.appendChild( container ).appendChild( div );
  2775. div.innerHTML = "";
  2776. // Support: Firefox, Android 2.3 (Prefixed box-sizing versions).
  2777. div.style.cssText = "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%";
  2778. // Workaround failing boxSizing test due to offsetWidth returning wrong value
  2779. // with some non-1 values of body zoom, ticket #13543
  2780. jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {
  2781. support.boxSizing = div.offsetWidth === 4;
  2782. });
  2783. // Use window.getComputedStyle because jsdom on node.js will break without it.
  2784. if ( window.getComputedStyle ) {
  2785. support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
  2786. support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
  2787. // Support: Android 2.3
  2788. // Check if div with explicit width and no margin-right incorrectly
  2789. // gets computed margin-right based on width of container. (#3333)
  2790. // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  2791. marginDiv = div.appendChild( document.createElement("div") );
  2792. marginDiv.style.cssText = div.style.cssText = divReset;
  2793. marginDiv.style.marginRight = marginDiv.style.width = "0";
  2794. div.style.width = "1px";
  2795. support.reliableMarginRight =
  2796. !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
  2797. }
  2798. body.removeChild( container );
  2799. });
  2800. return support;
  2801. })( {} );
  2802. /*
  2803. Implementation Summary
  2804. 1. Enforce API surface and semantic compatibility with 1.9.x branch
  2805. 2. Improve the module's maintainability by reducing the storage
  2806. paths to a single mechanism.
  2807. 3. Use the same single mechanism to support "private" and "user" data.
  2808. 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
  2809. 5. Avoid exposing implementation details on user objects (eg. expando properties)
  2810. 6. Provide a clear path for implementation upgrade to WeakMap in 2014
  2811. */
  2812. var data_user, data_priv,
  2813. rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
  2814. rmultiDash = /([A-Z])/g;
  2815. function Data() {
  2816. // Support: Android < 4,
  2817. // Old WebKit does not have Object.preventExtensions/freeze method,
  2818. // return new empty object instead with no [[set]] accessor
  2819. Object.defineProperty( this.cache = {}, 0, {
  2820. get: function() {
  2821. return {};
  2822. }
  2823. });
  2824. this.expando = jQuery.expando + Math.random();
  2825. }
  2826. Data.uid = 1;
  2827. Data.accepts = function( owner ) {
  2828. // Accepts only:
  2829. // - Node
  2830. // - Node.ELEMENT_NODE
  2831. // - Node.DOCUMENT_NODE
  2832. // - Object
  2833. // - Any
  2834. return owner.nodeType ?
  2835. owner.nodeType === 1 || owner.nodeType === 9 : true;
  2836. };
  2837. Data.prototype = {
  2838. key: function( owner ) {
  2839. // We can accept data for non-element nodes in modern browsers,
  2840. // but we should not, see #8335.
  2841. // Always return the key for a frozen object.
  2842. if ( !Data.accepts( owner ) ) {
  2843. return 0;
  2844. }
  2845. var descriptor = {},
  2846. // Check if the owner object already has a cache key
  2847. unlock = owner[ this.expando ];
  2848. // If not, create one
  2849. if ( !unlock ) {
  2850. unlock = Data.uid++;
  2851. // Secure it in a non-enumerable, non-writable property
  2852. try {
  2853. descriptor[ this.expando ] = { value: unlock };
  2854. Object.defineProperties( owner, descriptor );
  2855. // Support: Android < 4
  2856. // Fallback to a less secure definition
  2857. } catch ( e ) {
  2858. descriptor[ this.expando ] = unlock;
  2859. jQuery.extend( owner, descriptor );
  2860. }
  2861. }
  2862. // Ensure the cache object
  2863. if ( !this.cache[ unlock ] ) {
  2864. this.cache[ unlock ] = {};
  2865. }
  2866. return unlock;
  2867. },
  2868. set: function( owner, data, value ) {
  2869. var prop,
  2870. // There may be an unlock assigned to this node,
  2871. // if there is no entry for this "owner", create one inline
  2872. // and set the unlock as though an owner entry had always existed
  2873. unlock = this.key( owner ),
  2874. cache = this.cache[ unlock ];
  2875. // Handle: [ owner, key, value ] args
  2876. if ( typeof data === "string" ) {
  2877. cache[ data ] = value;
  2878. // Handle: [ owner, { properties } ] args
  2879. } else {
  2880. // Fresh assignments by object are shallow copied
  2881. if ( jQuery.isEmptyObject( cache ) ) {
  2882. jQuery.extend( this.cache[ unlock ], data );
  2883. // Otherwise, copy the properties one-by-one to the cache object
  2884. } else {
  2885. for ( prop in data ) {
  2886. cache[ prop ] = data[ prop ];
  2887. }
  2888. }
  2889. }
  2890. return cache;
  2891. },
  2892. get: function( owner, key ) {
  2893. // Either a valid cache is found, or will be created.
  2894. // New caches will be created and the unlock returned,
  2895. // allowing direct access to the newly created
  2896. // empty data object. A valid owner object must be provided.
  2897. var cache = this.cache[ this.key( owner ) ];
  2898. return key === undefined ?
  2899. cache : cache[ key ];
  2900. },
  2901. access: function( owner, key, value ) {
  2902. var stored;
  2903. // In cases where either:
  2904. //
  2905. // 1. No key was specified
  2906. // 2. A string key was specified, but no value provided
  2907. //
  2908. // Take the "read" path and allow the get method to determine
  2909. // which value to return, respectively either:
  2910. //
  2911. // 1. The entire cache object
  2912. // 2. The data stored at the key
  2913. //
  2914. if ( key === undefined ||
  2915. ((key && typeof key === "string") && value === undefined) ) {
  2916. stored = this.get( owner, key );
  2917. return stored !== undefined ?
  2918. stored : this.get( owner, jQuery.camelCase(key) );
  2919. }
  2920. // [*]When the key is not a string, or both a key and value
  2921. // are specified, set or extend (existing objects) with either:
  2922. //
  2923. // 1. An object of properties
  2924. // 2. A key and value
  2925. //
  2926. this.set( owner, key, value );
  2927. // Since the "set" path can have two possible entry points
  2928. // return the expected data based on which path was taken[*]
  2929. return value !== undefined ? value : key;
  2930. },
  2931. remove: function( owner, key ) {
  2932. var i, name, camel,
  2933. unlock = this.key( owner ),
  2934. cache = this.cache[ unlock ];
  2935. if ( key === undefined ) {
  2936. this.cache[ unlock ] = {};
  2937. } else {
  2938. // Support array or space separated string of keys
  2939. if ( jQuery.isArray( key ) ) {
  2940. // If "name" is an array of keys...
  2941. // When data is initially created, via ("key", "val") signature,
  2942. // keys will be converted to camelCase.
  2943. // Since there is no way to tell _how_ a key was added, remove
  2944. // both plain key and camelCase key. #12786
  2945. // This will only penalize the array argument path.
  2946. name = key.concat( key.map( jQuery.camelCase ) );
  2947. } else {
  2948. camel = jQuery.camelCase( key );
  2949. // Try the string as a key before any manipulation
  2950. if ( key in cache ) {
  2951. name = [ key, camel ];
  2952. } else {
  2953. // If a key with the spaces exists, use it.
  2954. // Otherwise, create an array by matching non-whitespace
  2955. name = camel;
  2956. name = name in cache ?
  2957. [ name ] : ( name.match( core_rnotwhite ) || [] );
  2958. }
  2959. }
  2960. i = name.length;
  2961. while ( i-- ) {
  2962. delete cache[ name[ i ] ];
  2963. }
  2964. }
  2965. },
  2966. hasData: function( owner ) {
  2967. return !jQuery.isEmptyObject(
  2968. this.cache[ owner[ this.expando ] ] || {}
  2969. );
  2970. },
  2971. discard: function( owner ) {
  2972. if ( owner[ this.expando ] ) {
  2973. delete this.cache[ owner[ this.expando ] ];
  2974. }
  2975. }
  2976. };
  2977. // These may be used throughout the jQuery core codebase
  2978. data_user = new Data();
  2979. data_priv = new Data();
  2980. jQuery.extend({
  2981. acceptData: Data.accepts,
  2982. hasData: function( elem ) {
  2983. return data_user.hasData( elem ) || data_priv.hasData( elem );
  2984. },
  2985. data: function( elem, name, data ) {
  2986. return data_user.access( elem, name, data );
  2987. },
  2988. removeData: function( elem, name ) {
  2989. data_user.remove( elem, name );
  2990. },
  2991. // TODO: Now that all calls to _data and _removeData have been replaced
  2992. // with direct calls to data_priv methods, these can be deprecated.
  2993. _data: function( elem, name, data ) {
  2994. return data_priv.access( elem, name, data );
  2995. },
  2996. _removeData: function( elem, name ) {
  2997. data_priv.remove( elem, name );
  2998. }
  2999. });
  3000. jQuery.fn.extend({
  3001. data: function( key, value ) {
  3002. var attrs, name,
  3003. elem = this[ 0 ],
  3004. i = 0,
  3005. data = null;
  3006. // Gets all values
  3007. if ( key === undefined ) {
  3008. if ( this.length ) {
  3009. data = data_user.get( elem );
  3010. if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) {
  3011. attrs = elem.attributes;
  3012. for ( ; i < attrs.length; i++ ) {
  3013. name = attrs[ i ].name;
  3014. if ( name.indexOf( "data-" ) === 0 ) {
  3015. name = jQuery.camelCase( name.slice(5) );
  3016. dataAttr( elem, name, data[ name ] );
  3017. }
  3018. }
  3019. data_priv.set( elem, "hasDataAttrs", true );
  3020. }
  3021. }
  3022. return data;
  3023. }
  3024. // Sets multiple values
  3025. if ( typeof key === "object" ) {
  3026. return this.each(function() {
  3027. data_user.set( this, key );
  3028. });
  3029. }
  3030. return jQuery.access( this, function( value ) {
  3031. var data,
  3032. camelKey = jQuery.camelCase( key );
  3033. // The calling jQuery object (element matches) is not empty
  3034. // (and therefore has an element appears at this[ 0 ]) and the
  3035. // `value` parameter was not undefined. An empty jQuery object
  3036. // will result in `undefined` for elem = this[ 0 ] which will
  3037. // throw an exception if an attempt to read a data cache is made.
  3038. if ( elem && value === undefined ) {
  3039. // Attempt to get data from the cache
  3040. // with the key as-is
  3041. data = data_user.get( elem, key );
  3042. if ( data !== undefined ) {
  3043. return data;
  3044. }
  3045. // Attempt to get data from the cache
  3046. // with the key camelized
  3047. data = data_user.get( elem, camelKey );
  3048. if ( data !== undefined ) {
  3049. return data;
  3050. }
  3051. // Attempt to "discover" the data in
  3052. // HTML5 custom data-* attrs
  3053. data = dataAttr( elem, camelKey, undefined );
  3054. if ( data !== undefined ) {
  3055. return data;
  3056. }
  3057. // We tried really hard, but the data doesn't exist.
  3058. return;
  3059. }
  3060. // Set the data...
  3061. this.each(function() {
  3062. // First, attempt to store a copy or reference of any
  3063. // data that might've been store with a camelCased key.
  3064. var data = data_user.get( this, camelKey );
  3065. // For HTML5 data-* attribute interop, we have to
  3066. // store property names with dashes in a camelCase form.
  3067. // This might not apply to all properties...*
  3068. data_user.set( this, camelKey, value );
  3069. // *... In the case of properties that might _actually_
  3070. // have dashes, we need to also store a copy of that
  3071. // unchanged property.
  3072. if ( key.indexOf("-") !== -1 && data !== undefined ) {
  3073. data_user.set( this, key, value );
  3074. }
  3075. });
  3076. }, null, value, arguments.length > 1, null, true );
  3077. },
  3078. removeData: function( key ) {
  3079. return this.each(function() {
  3080. data_user.remove( this, key );
  3081. });
  3082. }
  3083. });
  3084. function dataAttr( elem, key, data ) {
  3085. var name;
  3086. // If nothing was found internally, try to fetch any
  3087. // data from the HTML5 data-* attribute
  3088. if ( data === undefined && elem.nodeType === 1 ) {
  3089. name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase();
  3090. data = elem.getAttribute( name );
  3091. if ( typeof data === "string" ) {
  3092. try {
  3093. data = data === "true" ? true :
  3094. data === "false" ? false :
  3095. data === "null" ? null :
  3096. // Only convert to a number if it doesn't change the string
  3097. +data + "" === data ? +data :
  3098. rbrace.test( data ) ? JSON.parse( data ) :
  3099. data;
  3100. } catch( e ) {}
  3101. // Make sure we set the data so it isn't changed later
  3102. data_user.set( elem, key, data );
  3103. } else {
  3104. data = undefined;
  3105. }
  3106. }
  3107. return data;
  3108. }
  3109. jQuery.extend({
  3110. queue: function( elem, type, data ) {
  3111. var queue;
  3112. if ( elem ) {
  3113. type = ( type || "fx" ) + "queue";
  3114. queue = data_priv.get( elem, type );
  3115. // Speed up dequeue by getting out quickly if this is just a lookup
  3116. if ( data ) {
  3117. if ( !queue || jQuery.isArray( data ) ) {
  3118. queue = data_priv.access( elem, type, jQuery.makeArray(data) );
  3119. } else {
  3120. queue.push( data );
  3121. }
  3122. }
  3123. return queue || [];
  3124. }
  3125. },
  3126. dequeue: function( elem, type ) {
  3127. type = type || "fx";
  3128. var queue = jQuery.queue( elem, type ),
  3129. startLength = queue.length,
  3130. fn = queue.shift(),
  3131. hooks = jQuery._queueHooks( elem, type ),
  3132. next = function() {
  3133. jQuery.dequeue( elem, type );
  3134. };
  3135. // If the fx queue is dequeued, always remove the progress sentinel
  3136. if ( fn === "inprogress" ) {
  3137. fn = queue.shift();
  3138. startLength--;
  3139. }
  3140. if ( fn ) {
  3141. // Add a progress sentinel to prevent the fx queue from being
  3142. // automatically dequeued
  3143. if ( type === "fx" ) {
  3144. queue.unshift( "inprogress" );
  3145. }
  3146. // clear up the last queue stop function
  3147. delete hooks.stop;
  3148. fn.call( elem, next, hooks );
  3149. }
  3150. if ( !startLength && hooks ) {
  3151. hooks.empty.fire();
  3152. }
  3153. },
  3154. // not intended for public consumption - generates a queueHooks object, or returns the current one
  3155. _queueHooks: function( elem, type ) {
  3156. var key = type + "queueHooks";
  3157. return data_priv.get( elem, key ) || data_priv.access( elem, key, {
  3158. empty: jQuery.Callbacks("once memory").add(function() {
  3159. data_priv.remove( elem, [ type + "queue", key ] );
  3160. })
  3161. });
  3162. }
  3163. });
  3164. jQuery.fn.extend({
  3165. queue: function( type, data ) {
  3166. var setter = 2;
  3167. if ( typeof type !== "string" ) {
  3168. data = type;
  3169. type = "fx";
  3170. setter--;
  3171. }
  3172. if ( arguments.length < setter ) {
  3173. return jQuery.queue( this[0], type );
  3174. }
  3175. return data === undefined ?
  3176. this :
  3177. this.each(function() {
  3178. var queue = jQuery.queue( this, type, data );
  3179. // ensure a hooks for this queue
  3180. jQuery._queueHooks( this, type );
  3181. if ( type === "fx" && queue[0] !== "inprogress" ) {
  3182. jQuery.dequeue( this, type );
  3183. }
  3184. });
  3185. },
  3186. dequeue: function( type ) {
  3187. return this.each(function() {
  3188. jQuery.dequeue( this, type );
  3189. });
  3190. },
  3191. // Based off of the plugin by Clint Helfers, with permission.
  3192. // http://blindsignals.com/index.php/2009/07/jquery-delay/
  3193. delay: function( time, type ) {
  3194. time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
  3195. type = type || "fx";
  3196. return this.queue( type, function( next, hooks ) {
  3197. var timeout = setTimeout( next, time );
  3198. hooks.stop = function() {
  3199. clearTimeout( timeout );
  3200. };
  3201. });
  3202. },
  3203. clearQueue: function( type ) {
  3204. return this.queue( type || "fx", [] );
  3205. },
  3206. // Get a promise resolved when queues of a certain type
  3207. // are emptied (fx is the type by default)
  3208. promise: function( type, obj ) {
  3209. var tmp,
  3210. count = 1,
  3211. defer = jQuery.Deferred(),
  3212. elements = this,
  3213. i = this.length,
  3214. resolve = function() {
  3215. if ( !( --count ) ) {
  3216. defer.resolveWith( elements, [ elements ] );
  3217. }
  3218. };
  3219. if ( typeof type !== "string" ) {
  3220. obj = type;
  3221. type = undefined;
  3222. }
  3223. type = type || "fx";
  3224. while( i-- ) {
  3225. tmp = data_priv.get( elements[ i ], type + "queueHooks" );
  3226. if ( tmp && tmp.empty ) {
  3227. count++;
  3228. tmp.empty.add( resolve );
  3229. }
  3230. }
  3231. resolve();
  3232. return defer.promise( obj );
  3233. }
  3234. });
  3235. var nodeHook, boolHook,
  3236. rclass = /[\t\r\n\f]/g,
  3237. rreturn = /\r/g,
  3238. rfocusable = /^(?:input|select|textarea|button)$/i;
  3239. jQuery.fn.extend({
  3240. attr: function( name, value ) {
  3241. return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );
  3242. },
  3243. removeAttr: function( name ) {
  3244. return this.each(function() {
  3245. jQuery.removeAttr( this, name );
  3246. });
  3247. },
  3248. prop: function( name, value ) {
  3249. return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );
  3250. },
  3251. removeProp: function( name ) {
  3252. return this.each(function() {
  3253. delete this[ jQuery.propFix[ name ] || name ];
  3254. });
  3255. },
  3256. addClass: function( value ) {
  3257. var classes, elem, cur, clazz, j,
  3258. i = 0,
  3259. len = this.length,
  3260. proceed = typeof value === "string" && value;
  3261. if ( jQuery.isFunction( value ) ) {
  3262. return this.each(function( j ) {
  3263. jQuery( this ).addClass( value.call( this, j, this.className ) );
  3264. });
  3265. }
  3266. if ( proceed ) {
  3267. // The disjunction here is for better compressibility (see removeClass)
  3268. classes = ( value || "" ).match( core_rnotwhite ) || [];
  3269. for ( ; i < len; i++ ) {
  3270. elem = this[ i ];
  3271. cur = elem.nodeType === 1 && ( elem.className ?
  3272. ( " " + elem.className + " " ).replace( rclass, " " ) :
  3273. " "
  3274. );
  3275. if ( cur ) {
  3276. j = 0;
  3277. while ( (clazz = classes[j++]) ) {
  3278. if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
  3279. cur += clazz + " ";
  3280. }
  3281. }
  3282. elem.className = jQuery.trim( cur );
  3283. }
  3284. }
  3285. }
  3286. return this;
  3287. },
  3288. removeClass: function( value ) {
  3289. var classes, elem, cur, clazz, j,
  3290. i = 0,
  3291. len = this.length,
  3292. proceed = arguments.length === 0 || typeof value === "string" && value;
  3293. if ( jQuery.isFunction( value ) ) {
  3294. return this.each(function( j ) {
  3295. jQuery( this ).removeClass( value.call( this, j, this.className ) );
  3296. });
  3297. }
  3298. if ( proceed ) {
  3299. classes = ( value || "" ).match( core_rnotwhite ) || [];
  3300. for ( ; i < len; i++ ) {
  3301. elem = this[ i ];
  3302. // This expression is here for better compressibility (see addClass)
  3303. cur = elem.nodeType === 1 && ( elem.className ?
  3304. ( " " + elem.className + " " ).replace( rclass, " " ) :
  3305. ""
  3306. );
  3307. if ( cur ) {
  3308. j = 0;
  3309. while ( (clazz = classes[j++]) ) {
  3310. // Remove *all* instances
  3311. while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
  3312. cur = cur.replace( " " + clazz + " ", " " );
  3313. }
  3314. }
  3315. elem.className = value ? jQuery.trim( cur ) : "";
  3316. }
  3317. }
  3318. }
  3319. return this;
  3320. },
  3321. toggleClass: function( value, stateVal ) {
  3322. var type = typeof value;
  3323. if ( typeof stateVal === "boolean" && type === "string" ) {
  3324. return stateVal ? this.addClass( value ) : this.removeClass( value );
  3325. }
  3326. if ( jQuery.isFunction( value ) ) {
  3327. return this.each(function( i ) {
  3328. jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );
  3329. });
  3330. }
  3331. return this.each(function() {
  3332. if ( type === "string" ) {
  3333. // toggle individual class names
  3334. var className,
  3335. i = 0,
  3336. self = jQuery( this ),
  3337. classNames = value.match( core_rnotwhite ) || [];
  3338. while ( (className = classNames[ i++ ]) ) {
  3339. // check each className given, space separated list
  3340. if ( self.hasClass( className ) ) {
  3341. self.removeClass( className );
  3342. } else {
  3343. self.addClass( className );
  3344. }
  3345. }
  3346. // Toggle whole class name
  3347. } else if ( type === core_strundefined || type === "boolean" ) {
  3348. if ( this.className ) {
  3349. // store className if set
  3350. data_priv.set( this, "__className__", this.className );
  3351. }
  3352. // If the element has a class name or if we're passed "false",
  3353. // then remove the whole classname (if there was one, the above saved it).
  3354. // Otherwise bring back whatever was previously saved (if anything),
  3355. // falling back to the empty string if nothing was stored.
  3356. this.className = this.className || value === false ? "" : data_priv.get( this, "__className__" ) || "";
  3357. }
  3358. });
  3359. },
  3360. hasClass: function( selector ) {
  3361. var className = " " + selector + " ",
  3362. i = 0,
  3363. l = this.length;
  3364. for ( ; i < l; i++ ) {
  3365. if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) {
  3366. return true;
  3367. }
  3368. }
  3369. return false;
  3370. },
  3371. val: function( value ) {
  3372. var hooks, ret, isFunction,
  3373. elem = this[0];
  3374. if ( !arguments.length ) {
  3375. if ( elem ) {
  3376. hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];
  3377. if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) {
  3378. return ret;
  3379. }
  3380. ret = elem.value;
  3381. return typeof ret === "string" ?
  3382. // handle most common string cases
  3383. ret.replace(rreturn, "") :
  3384. // handle cases where value is null/undef or number
  3385. ret == null ? "" : ret;
  3386. }
  3387. return;
  3388. }
  3389. isFunction = jQuery.isFunction( value );
  3390. return this.each(function( i ) {
  3391. var val;
  3392. if ( this.nodeType !== 1 ) {
  3393. return;
  3394. }
  3395. if ( isFunction ) {
  3396. val = value.call( this, i, jQuery( this ).val() );
  3397. } else {
  3398. val = value;
  3399. }
  3400. // Treat null/undefined as ""; convert numbers to string
  3401. if ( val == null ) {
  3402. val = "";
  3403. } else if ( typeof val === "number" ) {
  3404. val += "";
  3405. } else if ( jQuery.isArray( val ) ) {
  3406. val = jQuery.map(val, function ( value ) {
  3407. return value == null ? "" : value + "";
  3408. });
  3409. }
  3410. hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];
  3411. // If set returns undefined, fall back to normal setting
  3412. if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) {
  3413. this.value = val;
  3414. }
  3415. });
  3416. }
  3417. });
  3418. jQuery.extend({
  3419. valHooks: {
  3420. option: {
  3421. get: function( elem ) {
  3422. // attributes.value is undefined in Blackberry 4.7 but
  3423. // uses .value. See #6932
  3424. var val = elem.attributes.value;
  3425. return !val || val.specified ? elem.value : elem.text;
  3426. }
  3427. },
  3428. select: {
  3429. get: function( elem ) {
  3430. var value, option,
  3431. options = elem.options,
  3432. index = elem.selectedIndex,
  3433. one = elem.type === "select-one" || index < 0,
  3434. values = one ? null : [],
  3435. max = one ? index + 1 : options.length,
  3436. i = index < 0 ?
  3437. max :
  3438. one ? index : 0;
  3439. // Loop through all the selected options
  3440. for ( ; i < max; i++ ) {
  3441. option = options[ i ];
  3442. // IE6-9 doesn't update selected after form reset (#2551)
  3443. if ( ( option.selected || i === index ) &&
  3444. // Don't return options that are disabled or in a disabled optgroup
  3445. ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) &&
  3446. ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) {
  3447. // Get the specific value for the option
  3448. value = jQuery( option ).val();
  3449. // We don't need an array for one selects
  3450. if ( one ) {
  3451. return value;
  3452. }
  3453. // Multi-Selects return an array
  3454. values.push( value );
  3455. }
  3456. }
  3457. return values;
  3458. },
  3459. set: function( elem, value ) {
  3460. var optionSet, option,
  3461. options = elem.options,
  3462. values = jQuery.makeArray( value ),
  3463. i = options.length;
  3464. while ( i-- ) {
  3465. option = options[ i ];
  3466. if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {
  3467. optionSet = true;
  3468. }
  3469. }
  3470. // force browsers to behave consistently when non-matching value is set
  3471. if ( !optionSet ) {
  3472. elem.selectedIndex = -1;
  3473. }
  3474. return values;
  3475. }
  3476. }
  3477. },
  3478. attr: function( elem, name, value ) {
  3479. var hooks, ret,
  3480. nType = elem.nodeType;
  3481. // don't get/set attributes on text, comment and attribute nodes
  3482. if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
  3483. return;
  3484. }
  3485. // Fallback to prop when attributes are not supported
  3486. if ( typeof elem.getAttribute === core_strundefined ) {
  3487. return jQuery.prop( elem, name, value );
  3488. }
  3489. // All attributes are lowercase
  3490. // Grab necessary hook if one is defined
  3491. if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
  3492. name = name.toLowerCase();
  3493. hooks = jQuery.attrHooks[ name ] ||
  3494. ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
  3495. }
  3496. if ( value !== undefined ) {
  3497. if ( value === null ) {
  3498. jQuery.removeAttr( elem, name );
  3499. } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
  3500. return ret;
  3501. } else {
  3502. elem.setAttribute( name, value + "" );
  3503. return value;
  3504. }
  3505. } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
  3506. return ret;
  3507. } else {
  3508. ret = jQuery.find.attr( elem, name );
  3509. // Non-existent attributes return null, we normalize to undefined
  3510. return ret == null ?
  3511. undefined :
  3512. ret;
  3513. }
  3514. },
  3515. removeAttr: function( elem, value ) {
  3516. var name, propName,
  3517. i = 0,
  3518. attrNames = value && value.match( core_rnotwhite );
  3519. if ( attrNames && elem.nodeType === 1 ) {
  3520. while ( (name = attrNames[i++]) ) {
  3521. propName = jQuery.propFix[ name ] || name;
  3522. // Boolean attributes get special treatment (#10870)
  3523. if ( jQuery.expr.match.bool.test( name ) ) {
  3524. // Set corresponding property to false
  3525. elem[ propName ] = false;
  3526. }
  3527. elem.removeAttribute( name );
  3528. }
  3529. }
  3530. },
  3531. attrHooks: {
  3532. type: {
  3533. set: function( elem, value ) {
  3534. if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
  3535. // Setting the type on a radio button after the value resets the value in IE6-9
  3536. // Reset value to default in case type is set after value during creation
  3537. var val = elem.value;
  3538. elem.setAttribute( "type", value );
  3539. if ( val ) {
  3540. elem.value = val;
  3541. }
  3542. return value;
  3543. }
  3544. }
  3545. }
  3546. },
  3547. propFix: {
  3548. "for": "htmlFor",
  3549. "class": "className"
  3550. },
  3551. prop: function( elem, name, value ) {
  3552. var ret, hooks, notxml,
  3553. nType = elem.nodeType;
  3554. // don't get/set properties on text, comment and attribute nodes
  3555. if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
  3556. return;
  3557. }
  3558. notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
  3559. if ( notxml ) {
  3560. // Fix name and attach hooks
  3561. name = jQuery.propFix[ name ] || name;
  3562. hooks = jQuery.propHooks[ name ];
  3563. }
  3564. if ( value !== undefined ) {
  3565. return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?
  3566. ret :
  3567. ( elem[ name ] = value );
  3568. } else {
  3569. return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
  3570. ret :
  3571. elem[ name ];
  3572. }
  3573. },
  3574. propHooks: {
  3575. tabIndex: {
  3576. get: function( elem ) {
  3577. return elem.hasAttribute( "tabindex" ) || rfocusable.test( elem.nodeName ) || elem.href ?
  3578. elem.tabIndex :
  3579. -1;
  3580. }
  3581. }
  3582. }
  3583. });
  3584. // Hooks for boolean attributes
  3585. boolHook = {
  3586. set: function( elem, value, name ) {
  3587. if ( value === false ) {
  3588. // Remove boolean attributes when set to false
  3589. jQuery.removeAttr( elem, name );
  3590. } else {
  3591. elem.setAttribute( name, name );
  3592. }
  3593. return name;
  3594. }
  3595. };
  3596. jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
  3597. var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
  3598. jQuery.expr.attrHandle[ name ] = function( elem, name, isXML ) {
  3599. var fn = jQuery.expr.attrHandle[ name ],
  3600. ret = isXML ?
  3601. undefined :
  3602. /* jshint eqeqeq: false */
  3603. // Temporarily disable this handler to check existence
  3604. (jQuery.expr.attrHandle[ name ] = undefined) !=
  3605. getter( elem, name, isXML ) ?
  3606. name.toLowerCase() :
  3607. null;
  3608. // Restore handler
  3609. jQuery.expr.attrHandle[ name ] = fn;
  3610. return ret;
  3611. };
  3612. });
  3613. // Support: IE9+
  3614. // Selectedness for an option in an optgroup can be inaccurate
  3615. if ( !jQuery.support.optSelected ) {
  3616. jQuery.propHooks.selected = {
  3617. get: function( elem ) {
  3618. var parent = elem.parentNode;
  3619. if ( parent && parent.parentNode ) {
  3620. parent.parentNode.selectedIndex;
  3621. }
  3622. return null;
  3623. }
  3624. };
  3625. }
  3626. jQuery.each([
  3627. "tabIndex",
  3628. "readOnly",
  3629. "maxLength",
  3630. "cellSpacing",
  3631. "cellPadding",
  3632. "rowSpan",
  3633. "colSpan",
  3634. "useMap",
  3635. "frameBorder",
  3636. "contentEditable"
  3637. ], function() {
  3638. jQuery.propFix[ this.toLowerCase() ] = this;
  3639. });
  3640. // Radios and checkboxes getter/setter
  3641. jQuery.each([ "radio", "checkbox" ], function() {
  3642. jQuery.valHooks[ this ] = {
  3643. set: function( elem, value ) {
  3644. if ( jQuery.isArray( value ) ) {
  3645. return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
  3646. }
  3647. }
  3648. };
  3649. if ( !jQuery.support.checkOn ) {
  3650. jQuery.valHooks[ this ].get = function( elem ) {
  3651. // Support: Webkit
  3652. // "" is returned instead of "on" if a value isn't specified
  3653. return elem.getAttribute("value") === null ? "on" : elem.value;
  3654. };
  3655. }
  3656. });
  3657. var rkeyEvent = /^key/,
  3658. rmouseEvent = /^(?:mouse|contextmenu)|click/,
  3659. rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
  3660. rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
  3661. function returnTrue() {
  3662. return true;
  3663. }
  3664. function returnFalse() {
  3665. return false;
  3666. }
  3667. function safeActiveElement() {
  3668. try {
  3669. return document.activeElement;
  3670. } catch ( err ) { }
  3671. }
  3672. /*
  3673. * Helper functions for managing events -- not part of the public interface.
  3674. * Props to Dean Edwards' addEvent library for many of the ideas.
  3675. */
  3676. jQuery.event = {
  3677. global: {},
  3678. add: function( elem, types, handler, data, selector ) {
  3679. var handleObjIn, eventHandle, tmp,
  3680. events, t, handleObj,
  3681. special, handlers, type, namespaces, origType,
  3682. elemData = data_priv.get( elem );
  3683. // Don't attach events to noData or text/comment nodes (but allow plain objects)
  3684. if ( !elemData ) {
  3685. return;
  3686. }
  3687. // Caller can pass in an object of custom data in lieu of the handler
  3688. if ( handler.handler ) {
  3689. handleObjIn = handler;
  3690. handler = handleObjIn.handler;
  3691. selector = handleObjIn.selector;
  3692. }
  3693. // Make sure that the handler has a unique ID, used to find/remove it later
  3694. if ( !handler.guid ) {
  3695. handler.guid = jQuery.guid++;
  3696. }
  3697. // Init the element's event structure and main handler, if this is the first
  3698. if ( !(events = elemData.events) ) {
  3699. events = elemData.events = {};
  3700. }
  3701. if ( !(eventHandle = elemData.handle) ) {
  3702. eventHandle = elemData.handle = function( e ) {
  3703. // Discard the second event of a jQuery.event.trigger() and
  3704. // when an event is called after a page has unloaded
  3705. return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?
  3706. jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
  3707. undefined;
  3708. };
  3709. // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
  3710. eventHandle.elem = elem;
  3711. }
  3712. // Handle multiple events separated by a space
  3713. types = ( types || "" ).match( core_rnotwhite ) || [""];
  3714. t = types.length;
  3715. while ( t-- ) {
  3716. tmp = rtypenamespace.exec( types[t] ) || [];
  3717. type = origType = tmp[1];
  3718. namespaces = ( tmp[2] || "" ).split( "." ).sort();
  3719. // There *must* be a type, no attaching namespace-only handlers
  3720. if ( !type ) {
  3721. continue;
  3722. }
  3723. // If event changes its type, use the special event handlers for the changed type
  3724. special = jQuery.event.special[ type ] || {};
  3725. // If selector defined, determine special event api type, otherwise given type
  3726. type = ( selector ? special.delegateType : special.bindType ) || type;
  3727. // Update special based on newly reset type
  3728. special = jQuery.event.special[ type ] || {};
  3729. // handleObj is passed to all event handlers
  3730. handleObj = jQuery.extend({
  3731. type: type,
  3732. origType: origType,
  3733. data: data,
  3734. handler: handler,
  3735. guid: handler.guid,
  3736. selector: selector,
  3737. needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
  3738. namespace: namespaces.join(".")
  3739. }, handleObjIn );
  3740. // Init the event handler queue if we're the first
  3741. if ( !(handlers = events[ type ]) ) {
  3742. handlers = events[ type ] = [];
  3743. handlers.delegateCount = 0;
  3744. // Only use addEventListener if the special events handler returns false
  3745. if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
  3746. if ( elem.addEventListener ) {
  3747. elem.addEventListener( type, eventHandle, false );
  3748. }
  3749. }
  3750. }
  3751. if ( special.add ) {
  3752. special.add.call( elem, handleObj );
  3753. if ( !handleObj.handler.guid ) {
  3754. handleObj.handler.guid = handler.guid;
  3755. }
  3756. }
  3757. // Add to the element's handler list, delegates in front
  3758. if ( selector ) {
  3759. handlers.splice( handlers.delegateCount++, 0, handleObj );
  3760. } else {
  3761. handlers.push( handleObj );
  3762. }
  3763. // Keep track of which events have ever been used, for event optimization
  3764. jQuery.event.global[ type ] = true;
  3765. }
  3766. // Nullify elem to prevent memory leaks in IE
  3767. elem = null;
  3768. },
  3769. // Detach an event or set of events from an element
  3770. remove: function( elem, types, handler, selector, mappedTypes ) {
  3771. var j, origCount, tmp,
  3772. events, t, handleObj,
  3773. special, handlers, type, namespaces, origType,
  3774. elemData = data_priv.hasData( elem ) && data_priv.get( elem );
  3775. if ( !elemData || !(events = elemData.events) ) {
  3776. return;
  3777. }
  3778. // Once for each type.namespace in types; type may be omitted
  3779. types = ( types || "" ).match( core_rnotwhite ) || [""];
  3780. t = types.length;
  3781. while ( t-- ) {
  3782. tmp = rtypenamespace.exec( types[t] ) || [];
  3783. type = origType = tmp[1];
  3784. namespaces = ( tmp[2] || "" ).split( "." ).sort();
  3785. // Unbind all events (on this namespace, if provided) for the element
  3786. if ( !type ) {
  3787. for ( type in events ) {
  3788. jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
  3789. }
  3790. continue;
  3791. }
  3792. special = jQuery.event.special[ type ] || {};
  3793. type = ( selector ? special.delegateType : special.bindType ) || type;
  3794. handlers = events[ type ] || [];
  3795. tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
  3796. // Remove matching events
  3797. origCount = j = handlers.length;
  3798. while ( j-- ) {
  3799. handleObj = handlers[ j ];
  3800. if ( ( mappedTypes || origType === handleObj.origType ) &&
  3801. ( !handler || handler.guid === handleObj.guid ) &&
  3802. ( !tmp || tmp.test( handleObj.namespace ) ) &&
  3803. ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
  3804. handlers.splice( j, 1 );
  3805. if ( handleObj.selector ) {
  3806. handlers.delegateCount--;
  3807. }
  3808. if ( special.remove ) {
  3809. special.remove.call( elem, handleObj );
  3810. }
  3811. }
  3812. }
  3813. // Remove generic event handler if we removed something and no more handlers exist
  3814. // (avoids potential for endless recursion during removal of special event handlers)
  3815. if ( origCount && !handlers.length ) {
  3816. if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
  3817. jQuery.removeEvent( elem, type, elemData.handle );
  3818. }
  3819. delete events[ type ];
  3820. }
  3821. }
  3822. // Remove the expando if it's no longer used
  3823. if ( jQuery.isEmptyObject( events ) ) {
  3824. delete elemData.handle;
  3825. data_priv.remove( elem, "events" );
  3826. }
  3827. },
  3828. trigger: function( event, data, elem, onlyHandlers ) {
  3829. var i, cur, tmp, bubbleType, ontype, handle, special,
  3830. eventPath = [ elem || document ],
  3831. type = core_hasOwn.call( event, "type" ) ? event.type : event,
  3832. namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
  3833. cur = tmp = elem = elem || document;
  3834. // Don't do events on text and comment nodes
  3835. if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
  3836. return;
  3837. }
  3838. // focus/blur morphs to focusin/out; ensure we're not firing them right now
  3839. if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
  3840. return;
  3841. }
  3842. if ( type.indexOf(".") >= 0 ) {
  3843. // Namespaced trigger; create a regexp to match event type in handle()
  3844. namespaces = type.split(".");
  3845. type = namespaces.shift();
  3846. namespaces.sort();
  3847. }
  3848. ontype = type.indexOf(":") < 0 && "on" + type;
  3849. // Caller can pass in a jQuery.Event object, Object, or just an event type string
  3850. event = event[ jQuery.expando ] ?
  3851. event :
  3852. new jQuery.Event( type, typeof event === "object" && event );
  3853. // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
  3854. event.isTrigger = onlyHandlers ? 2 : 3;
  3855. event.namespace = namespaces.join(".");
  3856. event.namespace_re = event.namespace ?
  3857. new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
  3858. null;
  3859. // Clean up the event in case it is being reused
  3860. event.result = undefined;
  3861. if ( !event.target ) {
  3862. event.target = elem;
  3863. }
  3864. // Clone any incoming data and prepend the event, creating the handler arg list
  3865. data = data == null ?
  3866. [ event ] :
  3867. jQuery.makeArray( data, [ event ] );
  3868. // Allow special events to draw outside the lines
  3869. special = jQuery.event.special[ type ] || {};
  3870. if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
  3871. return;
  3872. }
  3873. // Determine event propagation path in advance, per W3C events spec (#9951)
  3874. // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
  3875. if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
  3876. bubbleType = special.delegateType || type;
  3877. if ( !rfocusMorph.test( bubbleType + type ) ) {
  3878. cur = cur.parentNode;
  3879. }
  3880. for ( ; cur; cur = cur.parentNode ) {
  3881. eventPath.push( cur );
  3882. tmp = cur;
  3883. }
  3884. // Only add window if we got to document (e.g., not plain obj or detached DOM)
  3885. if ( tmp === (elem.ownerDocument || document) ) {
  3886. eventPath.push( tmp.defaultView || tmp.parentWindow || window );
  3887. }
  3888. }
  3889. // Fire handlers on the event path
  3890. i = 0;
  3891. while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
  3892. event.type = i > 1 ?
  3893. bubbleType :
  3894. special.bindType || type;
  3895. // jQuery handler
  3896. handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
  3897. if ( handle ) {
  3898. handle.apply( cur, data );
  3899. }
  3900. // Native handler
  3901. handle = ontype && cur[ ontype ];
  3902. if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
  3903. event.preventDefault();
  3904. }
  3905. }
  3906. event.type = type;
  3907. // If nobody prevented the default action, do it now
  3908. if ( !onlyHandlers && !event.isDefaultPrevented() ) {
  3909. if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
  3910. jQuery.acceptData( elem ) ) {
  3911. // Call a native DOM method on the target with the same name name as the event.
  3912. // Don't do default actions on window, that's where global variables be (#6170)
  3913. if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {
  3914. // Don't re-trigger an onFOO event when we call its FOO() method
  3915. tmp = elem[ ontype ];
  3916. if ( tmp ) {
  3917. elem[ ontype ] = null;
  3918. }
  3919. // Prevent re-triggering of the same event, since we already bubbled it above
  3920. jQuery.event.triggered = type;
  3921. elem[ type ]();
  3922. jQuery.event.triggered = undefined;
  3923. if ( tmp ) {
  3924. elem[ ontype ] = tmp;
  3925. }
  3926. }
  3927. }
  3928. }
  3929. return event.result;
  3930. },
  3931. dispatch: function( event ) {
  3932. // Make a writable jQuery.Event from the native event object
  3933. event = jQuery.event.fix( event );
  3934. var i, j, ret, matched, handleObj,
  3935. handlerQueue = [],
  3936. args = core_slice.call( arguments ),
  3937. handlers = ( data_priv.get( this, "events" ) || {} )[ event.type ] || [],
  3938. special = jQuery.event.special[ event.type ] || {};
  3939. // Use the fix-ed jQuery.Event rather than the (read-only) native event
  3940. args[0] = event;
  3941. event.delegateTarget = this;
  3942. // Call the preDispatch hook for the mapped type, and let it bail if desired
  3943. if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
  3944. return;
  3945. }
  3946. // Determine handlers
  3947. handlerQueue = jQuery.event.handlers.call( this, event, handlers );
  3948. // Run delegates first; they may want to stop propagation beneath us
  3949. i = 0;
  3950. while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
  3951. event.currentTarget = matched.elem;
  3952. j = 0;
  3953. while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
  3954. // Triggered event must either 1) have no namespace, or
  3955. // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
  3956. if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
  3957. event.handleObj = handleObj;
  3958. event.data = handleObj.data;
  3959. ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
  3960. .apply( matched.elem, args );
  3961. if ( ret !== undefined ) {
  3962. if ( (event.result = ret) === false ) {
  3963. event.preventDefault();
  3964. event.stopPropagation();
  3965. }
  3966. }
  3967. }
  3968. }
  3969. }
  3970. // Call the postDispatch hook for the mapped type
  3971. if ( special.postDispatch ) {
  3972. special.postDispatch.call( this, event );
  3973. }
  3974. return event.result;
  3975. },
  3976. handlers: function( event, handlers ) {
  3977. var i, matches, sel, handleObj,
  3978. handlerQueue = [],
  3979. delegateCount = handlers.delegateCount,
  3980. cur = event.target;
  3981. // Find delegate handlers
  3982. // Black-hole SVG <use> instance trees (#13180)
  3983. // Avoid non-left-click bubbling in Firefox (#3861)
  3984. if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
  3985. for ( ; cur !== this; cur = cur.parentNode || this ) {
  3986. // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
  3987. if ( cur.disabled !== true || event.type !== "click" ) {
  3988. matches = [];
  3989. for ( i = 0; i < delegateCount; i++ ) {
  3990. handleObj = handlers[ i ];
  3991. // Don't conflict with Object.prototype properties (#13203)
  3992. sel = handleObj.selector + " ";
  3993. if ( matches[ sel ] === undefined ) {
  3994. matches[ sel ] = handleObj.needsContext ?
  3995. jQuery( sel, this ).index( cur ) >= 0 :
  3996. jQuery.find( sel, this, null, [ cur ] ).length;
  3997. }
  3998. if ( matches[ sel ] ) {
  3999. matches.push( handleObj );
  4000. }
  4001. }
  4002. if ( matches.length ) {
  4003. handlerQueue.push({ elem: cur, handlers: matches });
  4004. }
  4005. }
  4006. }
  4007. }
  4008. // Add the remaining (directly-bound) handlers
  4009. if ( delegateCount < handlers.length ) {
  4010. handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
  4011. }
  4012. return handlerQueue;
  4013. },
  4014. // Includes some event props shared by KeyEvent and MouseEvent
  4015. props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
  4016. fixHooks: {},
  4017. keyHooks: {
  4018. props: "char charCode key keyCode".split(" "),
  4019. filter: function( event, original ) {
  4020. // Add which for key events
  4021. if ( event.which == null ) {
  4022. event.which = original.charCode != null ? original.charCode : original.keyCode;
  4023. }
  4024. return event;
  4025. }
  4026. },
  4027. mouseHooks: {
  4028. props: "button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),
  4029. filter: function( event, original ) {
  4030. var eventDoc, doc, body,
  4031. button = original.button;
  4032. // Calculate pageX/Y if missing and clientX/Y available
  4033. if ( event.pageX == null && original.clientX != null ) {
  4034. eventDoc = event.target.ownerDocument || document;
  4035. doc = eventDoc.documentElement;
  4036. body = eventDoc.body;
  4037. event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );
  4038. event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );
  4039. }
  4040. // Add which for click: 1 === left; 2 === middle; 3 === right
  4041. // Note: button is not normalized, so don't use it
  4042. if ( !event.which && button !== undefined ) {
  4043. event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
  4044. }
  4045. return event;
  4046. }
  4047. },
  4048. fix: function( event ) {
  4049. if ( event[ jQuery.expando ] ) {
  4050. return event;
  4051. }
  4052. // Create a writable copy of the event object and normalize some properties
  4053. var i, prop, copy,
  4054. type = event.type,
  4055. originalEvent = event,
  4056. fixHook = this.fixHooks[ type ];
  4057. if ( !fixHook ) {
  4058. this.fixHooks[ type ] = fixHook =
  4059. rmouseEvent.test( type ) ? this.mouseHooks :
  4060. rkeyEvent.test( type ) ? this.keyHooks :
  4061. {};
  4062. }
  4063. copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
  4064. event = new jQuery.Event( originalEvent );
  4065. i = copy.length;
  4066. while ( i-- ) {
  4067. prop = copy[ i ];
  4068. event[ prop ] = originalEvent[ prop ];
  4069. }
  4070. // Support: Cordova 2.5 (WebKit) (#13255)
  4071. // All events should have a target; Cordova deviceready doesn't
  4072. if ( !event.target ) {
  4073. event.target = document;
  4074. }
  4075. // Support: Safari 6.0+, Chrome < 28
  4076. // Target should not be a text node (#504, #13143)
  4077. if ( event.target.nodeType === 3 ) {
  4078. event.target = event.target.parentNode;
  4079. }
  4080. return fixHook.filter? fixHook.filter( event, originalEvent ) : event;
  4081. },
  4082. special: {
  4083. load: {
  4084. // Prevent triggered image.load events from bubbling to window.load
  4085. noBubble: true
  4086. },
  4087. focus: {
  4088. // Fire native event if possible so blur/focus sequence is correct
  4089. trigger: function() {
  4090. if ( this !== safeActiveElement() && this.focus ) {
  4091. this.focus();
  4092. return false;
  4093. }
  4094. },
  4095. delegateType: "focusin"
  4096. },
  4097. blur: {
  4098. trigger: function() {
  4099. if ( this === safeActiveElement() && this.blur ) {
  4100. this.blur();
  4101. return false;
  4102. }
  4103. },
  4104. delegateType: "focusout"
  4105. },
  4106. click: {
  4107. // For checkbox, fire native event so checked state will be right
  4108. trigger: function() {
  4109. if ( this.type === "checkbox" && this.click && jQuery.nodeName( this, "input" ) ) {
  4110. this.click();
  4111. return false;
  4112. }
  4113. },
  4114. // For cross-browser consistency, don't fire native .click() on links
  4115. _default: function( event ) {
  4116. return jQuery.nodeName( event.target, "a" );
  4117. }
  4118. },
  4119. beforeunload: {
  4120. postDispatch: function( event ) {
  4121. // Support: Firefox 20+
  4122. // Firefox doesn't alert if the returnValue field is not set.
  4123. if ( event.result !== undefined ) {
  4124. event.originalEvent.returnValue = event.result;
  4125. }
  4126. }
  4127. }
  4128. },
  4129. simulate: function( type, elem, event, bubble ) {
  4130. // Piggyback on a donor event to simulate a different one.
  4131. // Fake originalEvent to avoid donor's stopPropagation, but if the
  4132. // simulated event prevents default then we do the same on the donor.
  4133. var e = jQuery.extend(
  4134. new jQuery.Event(),
  4135. event,
  4136. {
  4137. type: type,
  4138. isSimulated: true,
  4139. originalEvent: {}
  4140. }
  4141. );
  4142. if ( bubble ) {
  4143. jQuery.event.trigger( e, null, elem );
  4144. } else {
  4145. jQuery.event.dispatch.call( elem, e );
  4146. }
  4147. if ( e.isDefaultPrevented() ) {
  4148. event.preventDefault();
  4149. }
  4150. }
  4151. };
  4152. jQuery.removeEvent = function( elem, type, handle ) {
  4153. if ( elem.removeEventListener ) {
  4154. elem.removeEventListener( type, handle, false );
  4155. }
  4156. };
  4157. jQuery.Event = function( src, props ) {
  4158. // Allow instantiation without the 'new' keyword
  4159. if ( !(this instanceof jQuery.Event) ) {
  4160. return new jQuery.Event( src, props );
  4161. }
  4162. // Event object
  4163. if ( src && src.type ) {
  4164. this.originalEvent = src;
  4165. this.type = src.type;
  4166. // Events bubbling up the document may have been marked as prevented
  4167. // by a handler lower down the tree; reflect the correct value.
  4168. this.isDefaultPrevented = ( src.defaultPrevented ||
  4169. src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;
  4170. // Event type
  4171. } else {
  4172. this.type = src;
  4173. }
  4174. // Put explicitly provided properties onto the event object
  4175. if ( props ) {
  4176. jQuery.extend( this, props );
  4177. }
  4178. // Create a timestamp if incoming event doesn't have one
  4179. this.timeStamp = src && src.timeStamp || jQuery.now();
  4180. // Mark it as fixed
  4181. this[ jQuery.expando ] = true;
  4182. };
  4183. // jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
  4184. // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  4185. jQuery.Event.prototype = {
  4186. isDefaultPrevented: returnFalse,
  4187. isPropagationStopped: returnFalse,
  4188. isImmediatePropagationStopped: returnFalse,
  4189. preventDefault: function() {
  4190. var e = this.originalEvent;
  4191. this.isDefaultPrevented = returnTrue;
  4192. if ( e && e.preventDefault ) {
  4193. e.preventDefault();
  4194. }
  4195. },
  4196. stopPropagation: function() {
  4197. var e = this.originalEvent;
  4198. this.isPropagationStopped = returnTrue;
  4199. if ( e && e.stopPropagation ) {
  4200. e.stopPropagation();
  4201. }
  4202. },
  4203. stopImmediatePropagation: function() {
  4204. this.isImmediatePropagationStopped = returnTrue;
  4205. this.stopPropagation();
  4206. }
  4207. };
  4208. // Create mouseenter/leave events using mouseover/out and event-time checks
  4209. // Support: Chrome 15+
  4210. jQuery.each({
  4211. mouseenter: "mouseover",
  4212. mouseleave: "mouseout"
  4213. }, function( orig, fix ) {
  4214. jQuery.event.special[ orig ] = {
  4215. delegateType: fix,
  4216. bindType: fix,
  4217. handle: function( event ) {
  4218. var ret,
  4219. target = this,
  4220. related = event.relatedTarget,
  4221. handleObj = event.handleObj;
  4222. // For mousenter/leave call the handler if related is outside the target.
  4223. // NB: No relatedTarget if the mouse left/entered the browser window
  4224. if ( !related || (related !== target && !jQuery.contains( target, related )) ) {
  4225. event.type = handleObj.origType;
  4226. ret = handleObj.handler.apply( this, arguments );
  4227. event.type = fix;
  4228. }
  4229. return ret;
  4230. }
  4231. };
  4232. });
  4233. // Create "bubbling" focus and blur events
  4234. // Support: Firefox, Chrome, Safari
  4235. if ( !jQuery.support.focusinBubbles ) {
  4236. jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
  4237. // Attach a single capturing handler while someone wants focusin/focusout
  4238. var attaches = 0,
  4239. handler = function( event ) {
  4240. jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );
  4241. };
  4242. jQuery.event.special[ fix ] = {
  4243. setup: function() {
  4244. if ( attaches++ === 0 ) {
  4245. document.addEventListener( orig, handler, true );
  4246. }
  4247. },
  4248. teardown: function() {
  4249. if ( --attaches === 0 ) {
  4250. document.removeEventListener( orig, handler, true );
  4251. }
  4252. }
  4253. };
  4254. });
  4255. }
  4256. jQuery.fn.extend({
  4257. on: function( types, selector, data, fn, /*INTERNAL*/ one ) {
  4258. var origFn, type;
  4259. // Types can be a map of types/handlers
  4260. if ( typeof types === "object" ) {
  4261. // ( types-Object, selector, data )
  4262. if ( typeof selector !== "string" ) {
  4263. // ( types-Object, data )
  4264. data = data || selector;
  4265. selector = undefined;
  4266. }
  4267. for ( type in types ) {
  4268. this.on( type, selector, data, types[ type ], one );
  4269. }
  4270. return this;
  4271. }
  4272. if ( data == null && fn == null ) {
  4273. // ( types, fn )
  4274. fn = selector;
  4275. data = selector = undefined;
  4276. } else if ( fn == null ) {
  4277. if ( typeof selector === "string" ) {
  4278. // ( types, selector, fn )
  4279. fn = data;
  4280. data = undefined;
  4281. } else {
  4282. // ( types, data, fn )
  4283. fn = data;
  4284. data = selector;
  4285. selector = undefined;
  4286. }
  4287. }
  4288. if ( fn === false ) {
  4289. fn = returnFalse;
  4290. } else if ( !fn ) {
  4291. return this;
  4292. }
  4293. if ( one === 1 ) {
  4294. origFn = fn;
  4295. fn = function( event ) {
  4296. // Can use an empty set, since event contains the info
  4297. jQuery().off( event );
  4298. return origFn.apply( this, arguments );
  4299. };
  4300. // Use same guid so caller can remove using origFn
  4301. fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
  4302. }
  4303. return this.each( function() {
  4304. jQuery.event.add( this, types, fn, data, selector );
  4305. });
  4306. },
  4307. one: function( types, selector, data, fn ) {
  4308. return this.on( types, selector, data, fn, 1 );
  4309. },
  4310. off: function( types, selector, fn ) {
  4311. var handleObj, type;
  4312. if ( types && types.preventDefault && types.handleObj ) {
  4313. // ( event ) dispatched jQuery.Event
  4314. handleObj = types.handleObj;
  4315. jQuery( types.delegateTarget ).off(
  4316. handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType,
  4317. handleObj.selector,
  4318. handleObj.handler
  4319. );
  4320. return this;
  4321. }
  4322. if ( typeof types === "object" ) {
  4323. // ( types-object [, selector] )
  4324. for ( type in types ) {
  4325. this.off( type, selector, types[ type ] );
  4326. }
  4327. return this;
  4328. }
  4329. if ( selector === false || typeof selector === "function" ) {
  4330. // ( types [, fn] )
  4331. fn = selector;
  4332. selector = undefined;
  4333. }
  4334. if ( fn === false ) {
  4335. fn = returnFalse;
  4336. }
  4337. return this.each(function() {
  4338. jQuery.event.remove( this, types, fn, selector );
  4339. });
  4340. },
  4341. trigger: function( type, data ) {
  4342. return this.each(function() {
  4343. jQuery.event.trigger( type, data, this );
  4344. });
  4345. },
  4346. triggerHandler: function( type, data ) {
  4347. var elem = this[0];
  4348. if ( elem ) {
  4349. return jQuery.event.trigger( type, data, elem, true );
  4350. }
  4351. }
  4352. });
  4353. var isSimple = /^.[^:#\[\.,]*$/,
  4354. rparentsprev = /^(?:parents|prev(?:Until|All))/,
  4355. rneedsContext = jQuery.expr.match.needsContext,
  4356. // methods guaranteed to produce a unique set when starting from a unique set
  4357. guaranteedUnique = {
  4358. children: true,
  4359. contents: true,
  4360. next: true,
  4361. prev: true
  4362. };
  4363. jQuery.fn.extend({
  4364. find: function( selector ) {
  4365. var i,
  4366. ret = [],
  4367. self = this,
  4368. len = self.length;
  4369. if ( typeof selector !== "string" ) {
  4370. return this.pushStack( jQuery( selector ).filter(function() {
  4371. for ( i = 0; i < len; i++ ) {
  4372. if ( jQuery.contains( self[ i ], this ) ) {
  4373. return true;
  4374. }
  4375. }
  4376. }) );
  4377. }
  4378. for ( i = 0; i < len; i++ ) {
  4379. jQuery.find( selector, self[ i ], ret );
  4380. }
  4381. // Needed because $( selector, context ) becomes $( context ).find( selector )
  4382. ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
  4383. ret.selector = this.selector ? this.selector + " " + selector : selector;
  4384. return ret;
  4385. },
  4386. has: function( target ) {
  4387. var targets = jQuery( target, this ),
  4388. l = targets.length;
  4389. return this.filter(function() {
  4390. var i = 0;
  4391. for ( ; i < l; i++ ) {
  4392. if ( jQuery.contains( this, targets[i] ) ) {
  4393. return true;
  4394. }
  4395. }
  4396. });
  4397. },
  4398. not: function( selector ) {
  4399. return this.pushStack( winnow(this, selector || [], true) );
  4400. },
  4401. filter: function( selector ) {
  4402. return this.pushStack( winnow(this, selector || [], false) );
  4403. },
  4404. is: function( selector ) {
  4405. return !!winnow(
  4406. this,
  4407. // If this is a positional/relative selector, check membership in the returned set
  4408. // so $("p:first").is("p:last") won't return true for a doc with two "p".
  4409. typeof selector === "string" && rneedsContext.test( selector ) ?
  4410. jQuery( selector ) :
  4411. selector || [],
  4412. false
  4413. ).length;
  4414. },
  4415. closest: function( selectors, context ) {
  4416. var cur,
  4417. i = 0,
  4418. l = this.length,
  4419. matched = [],
  4420. pos = ( rneedsContext.test( selectors ) || typeof selectors !== "string" ) ?
  4421. jQuery( selectors, context || this.context ) :
  4422. 0;
  4423. for ( ; i < l; i++ ) {
  4424. for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
  4425. // Always skip document fragments
  4426. if ( cur.nodeType < 11 && (pos ?
  4427. pos.index(cur) > -1 :
  4428. // Don't pass non-elements to Sizzle
  4429. cur.nodeType === 1 &&
  4430. jQuery.find.matchesSelector(cur, selectors)) ) {
  4431. cur = matched.push( cur );
  4432. break;
  4433. }
  4434. }
  4435. }
  4436. return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
  4437. },
  4438. // Determine the position of an element within
  4439. // the matched set of elements
  4440. index: function( elem ) {
  4441. // No argument, return index in parent
  4442. if ( !elem ) {
  4443. return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
  4444. }
  4445. // index in selector
  4446. if ( typeof elem === "string" ) {
  4447. return core_indexOf.call( jQuery( elem ), this[ 0 ] );
  4448. }
  4449. // Locate the position of the desired element
  4450. return core_indexOf.call( this,
  4451. // If it receives a jQuery object, the first element is used
  4452. elem.jquery ? elem[ 0 ] : elem
  4453. );
  4454. },
  4455. add: function( selector, context ) {
  4456. var set = typeof selector === "string" ?
  4457. jQuery( selector, context ) :
  4458. jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
  4459. all = jQuery.merge( this.get(), set );
  4460. return this.pushStack( jQuery.unique(all) );
  4461. },
  4462. addBack: function( selector ) {
  4463. return this.add( selector == null ?
  4464. this.prevObject : this.prevObject.filter(selector)
  4465. );
  4466. }
  4467. });
  4468. function sibling( cur, dir ) {
  4469. while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
  4470. return cur;
  4471. }
  4472. jQuery.each({
  4473. parent: function( elem ) {
  4474. var parent = elem.parentNode;
  4475. return parent && parent.nodeType !== 11 ? parent : null;
  4476. },
  4477. parents: function( elem ) {
  4478. return jQuery.dir( elem, "parentNode" );
  4479. },
  4480. parentsUntil: function( elem, i, until ) {
  4481. return jQuery.dir( elem, "parentNode", until );
  4482. },
  4483. next: function( elem ) {
  4484. return sibling( elem, "nextSibling" );
  4485. },
  4486. prev: function( elem ) {
  4487. return sibling( elem, "previousSibling" );
  4488. },
  4489. nextAll: function( elem ) {
  4490. return jQuery.dir( elem, "nextSibling" );
  4491. },
  4492. prevAll: function( elem ) {
  4493. return jQuery.dir( elem, "previousSibling" );
  4494. },
  4495. nextUntil: function( elem, i, until ) {
  4496. return jQuery.dir( elem, "nextSibling", until );
  4497. },
  4498. prevUntil: function( elem, i, until ) {
  4499. return jQuery.dir( elem, "previousSibling", until );
  4500. },
  4501. siblings: function( elem ) {
  4502. return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
  4503. },
  4504. children: function( elem ) {
  4505. return jQuery.sibling( elem.firstChild );
  4506. },
  4507. contents: function( elem ) {
  4508. return elem.contentDocument || jQuery.merge( [], elem.childNodes );
  4509. }
  4510. }, function( name, fn ) {
  4511. jQuery.fn[ name ] = function( until, selector ) {
  4512. var matched = jQuery.map( this, fn, until );
  4513. if ( name.slice( -5 ) !== "Until" ) {
  4514. selector = until;
  4515. }
  4516. if ( selector && typeof selector === "string" ) {
  4517. matched = jQuery.filter( selector, matched );
  4518. }
  4519. if ( this.length > 1 ) {
  4520. // Remove duplicates
  4521. if ( !guaranteedUnique[ name ] ) {
  4522. jQuery.unique( matched );
  4523. }
  4524. // Reverse order for parents* and prev-derivatives
  4525. if ( rparentsprev.test( name ) ) {
  4526. matched.reverse();
  4527. }
  4528. }
  4529. return this.pushStack( matched );
  4530. };
  4531. });
  4532. jQuery.extend({
  4533. filter: function( expr, elems, not ) {
  4534. var elem = elems[ 0 ];
  4535. if ( not ) {
  4536. expr = ":not(" + expr + ")";
  4537. }
  4538. return elems.length === 1 && elem.nodeType === 1 ?
  4539. jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
  4540. jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
  4541. return elem.nodeType === 1;
  4542. }));
  4543. },
  4544. dir: function( elem, dir, until ) {
  4545. var matched = [],
  4546. truncate = until !== undefined;
  4547. while ( (elem = elem[ dir ]) && elem.nodeType !== 9 ) {
  4548. if ( elem.nodeType === 1 ) {
  4549. if ( truncate && jQuery( elem ).is( until ) ) {
  4550. break;
  4551. }
  4552. matched.push( elem );
  4553. }
  4554. }
  4555. return matched;
  4556. },
  4557. sibling: function( n, elem ) {
  4558. var matched = [];
  4559. for ( ; n; n = n.nextSibling ) {
  4560. if ( n.nodeType === 1 && n !== elem ) {
  4561. matched.push( n );
  4562. }
  4563. }
  4564. return matched;
  4565. }
  4566. });
  4567. // Implement the identical functionality for filter and not
  4568. function winnow( elements, qualifier, not ) {
  4569. if ( jQuery.isFunction( qualifier ) ) {
  4570. return jQuery.grep( elements, function( elem, i ) {
  4571. /* jshint -W018 */
  4572. return !!qualifier.call( elem, i, elem ) !== not;
  4573. });
  4574. }
  4575. if ( qualifier.nodeType ) {
  4576. return jQuery.grep( elements, function( elem ) {
  4577. return ( elem === qualifier ) !== not;
  4578. });
  4579. }
  4580. if ( typeof qualifier === "string" ) {
  4581. if ( isSimple.test( qualifier ) ) {
  4582. return jQuery.filter( qualifier, elements, not );
  4583. }
  4584. qualifier = jQuery.filter( qualifier, elements );
  4585. }
  4586. return jQuery.grep( elements, function( elem ) {
  4587. return ( core_indexOf.call( qualifier, elem ) >= 0 ) !== not;
  4588. });
  4589. }
  4590. var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
  4591. rtagName = /<([\w:]+)/,
  4592. rhtml = /<|&#?\w+;/,
  4593. rnoInnerhtml = /<(?:script|style|link)/i,
  4594. manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
  4595. // checked="checked" or checked
  4596. rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
  4597. rscriptType = /^$|\/(?:java|ecma)script/i,
  4598. rscriptTypeMasked = /^true\/(.*)/,
  4599. rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
  4600. // We have to close these tags to support XHTML (#13200)
  4601. wrapMap = {
  4602. // Support: IE 9
  4603. option: [ 1, "<select multiple='multiple'>", "</select>" ],
  4604. thead: [ 1, "<table>", "</table>" ],
  4605. col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
  4606. tr: [ 2, "<table><tbody>", "</tbody></table>" ],
  4607. td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
  4608. _default: [ 0, "", "" ]
  4609. };
  4610. // Support: IE 9
  4611. wrapMap.optgroup = wrapMap.option;
  4612. wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
  4613. wrapMap.th = wrapMap.td;
  4614. jQuery.fn.extend({
  4615. text: function( value ) {
  4616. return jQuery.access( this, function( value ) {
  4617. return value === undefined ?
  4618. jQuery.text( this ) :
  4619. this.empty().append( ( this[ 0 ] && this[ 0 ].ownerDocument || document ).createTextNode( value ) );
  4620. }, null, value, arguments.length );
  4621. },
  4622. append: function() {
  4623. return this.domManip( arguments, function( elem ) {
  4624. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4625. var target = manipulationTarget( this, elem );
  4626. target.appendChild( elem );
  4627. }
  4628. });
  4629. },
  4630. prepend: function() {
  4631. return this.domManip( arguments, function( elem ) {
  4632. if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
  4633. var target = manipulationTarget( this, elem );
  4634. target.insertBefore( elem, target.firstChild );
  4635. }
  4636. });
  4637. },
  4638. before: function() {
  4639. return this.domManip( arguments, function( elem ) {
  4640. if ( this.parentNode ) {
  4641. this.parentNode.insertBefore( elem, this );
  4642. }
  4643. });
  4644. },
  4645. after: function() {
  4646. return this.domManip( arguments, function( elem ) {
  4647. if ( this.parentNode ) {
  4648. this.parentNode.insertBefore( elem, this.nextSibling );
  4649. }
  4650. });
  4651. },
  4652. // keepData is for internal use only--do not document
  4653. remove: function( selector, keepData ) {
  4654. var elem,
  4655. elems = selector ? jQuery.filter( selector, this ) : this,
  4656. i = 0;
  4657. for ( ; (elem = elems[i]) != null; i++ ) {
  4658. if ( !keepData && elem.nodeType === 1 ) {
  4659. jQuery.cleanData( getAll( elem ) );
  4660. }
  4661. if ( elem.parentNode ) {
  4662. if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
  4663. setGlobalEval( getAll( elem, "script" ) );
  4664. }
  4665. elem.parentNode.removeChild( elem );
  4666. }
  4667. }
  4668. return this;
  4669. },
  4670. empty: function() {
  4671. var elem,
  4672. i = 0;
  4673. for ( ; (elem = this[i]) != null; i++ ) {
  4674. if ( elem.nodeType === 1 ) {
  4675. // Prevent memory leaks
  4676. jQuery.cleanData( getAll( elem, false ) );
  4677. // Remove any remaining nodes
  4678. elem.textContent = "";
  4679. }
  4680. }
  4681. return this;
  4682. },
  4683. clone: function( dataAndEvents, deepDataAndEvents ) {
  4684. dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
  4685. deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
  4686. return this.map( function () {
  4687. return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
  4688. });
  4689. },
  4690. html: function( value ) {
  4691. return jQuery.access( this, function( value ) {
  4692. var elem = this[ 0 ] || {},
  4693. i = 0,
  4694. l = this.length;
  4695. if ( value === undefined && elem.nodeType === 1 ) {
  4696. return elem.innerHTML;
  4697. }
  4698. // See if we can take a shortcut and just use innerHTML
  4699. if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
  4700. !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
  4701. value = value.replace( rxhtmlTag, "<$1></$2>" );
  4702. try {
  4703. for ( ; i < l; i++ ) {
  4704. elem = this[ i ] || {};
  4705. // Remove element nodes and prevent memory leaks
  4706. if ( elem.nodeType === 1 ) {
  4707. jQuery.cleanData( getAll( elem, false ) );
  4708. elem.innerHTML = value;
  4709. }
  4710. }
  4711. elem = 0;
  4712. // If using innerHTML throws an exception, use the fallback method
  4713. } catch( e ) {}
  4714. }
  4715. if ( elem ) {
  4716. this.empty().append( value );
  4717. }
  4718. }, null, value, arguments.length );
  4719. },
  4720. replaceWith: function() {
  4721. var
  4722. // Snapshot the DOM in case .domManip sweeps something relevant into its fragment
  4723. args = jQuery.map( this, function( elem ) {
  4724. return [ elem.nextSibling, elem.parentNode ];
  4725. }),
  4726. i = 0;
  4727. // Make the changes, replacing each context element with the new content
  4728. this.domManip( arguments, function( elem ) {
  4729. var next = args[ i++ ],
  4730. parent = args[ i++ ];
  4731. if ( parent ) {
  4732. // Don't use the snapshot next if it has moved (#13810)
  4733. if ( next && next.parentNode !== parent ) {
  4734. next = this.nextSibling;
  4735. }
  4736. jQuery( this ).remove();
  4737. parent.insertBefore( elem, next );
  4738. }
  4739. // Allow new content to include elements from the context set
  4740. }, true );
  4741. // Force removal if there was no new content (e.g., from empty arguments)
  4742. return i ? this : this.remove();
  4743. },
  4744. detach: function( selector ) {
  4745. return this.remove( selector, true );
  4746. },
  4747. domManip: function( args, callback, allowIntersection ) {
  4748. // Flatten any nested arrays
  4749. args = core_concat.apply( [], args );
  4750. var fragment, first, scripts, hasScripts, node, doc,
  4751. i = 0,
  4752. l = this.length,
  4753. set = this,
  4754. iNoClone = l - 1,
  4755. value = args[ 0 ],
  4756. isFunction = jQuery.isFunction( value );
  4757. // We can't cloneNode fragments that contain checked, in WebKit
  4758. if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
  4759. return this.each(function( index ) {
  4760. var self = set.eq( index );
  4761. if ( isFunction ) {
  4762. args[ 0 ] = value.call( this, index, self.html() );
  4763. }
  4764. self.domManip( args, callback, allowIntersection );
  4765. });
  4766. }
  4767. if ( l ) {
  4768. fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );
  4769. first = fragment.firstChild;
  4770. if ( fragment.childNodes.length === 1 ) {
  4771. fragment = first;
  4772. }
  4773. if ( first ) {
  4774. scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
  4775. hasScripts = scripts.length;
  4776. // Use the original fragment for the last item instead of the first because it can end up
  4777. // being emptied incorrectly in certain situations (#8070).
  4778. for ( ; i < l; i++ ) {
  4779. node = fragment;
  4780. if ( i !== iNoClone ) {
  4781. node = jQuery.clone( node, true, true );
  4782. // Keep references to cloned scripts for later restoration
  4783. if ( hasScripts ) {
  4784. // Support: QtWebKit
  4785. // jQuery.merge because core_push.apply(_, arraylike) throws
  4786. jQuery.merge( scripts, getAll( node, "script" ) );
  4787. }
  4788. }
  4789. callback.call( this[ i ], node, i );
  4790. }
  4791. if ( hasScripts ) {
  4792. doc = scripts[ scripts.length - 1 ].ownerDocument;
  4793. // Reenable scripts
  4794. jQuery.map( scripts, restoreScript );
  4795. // Evaluate executable scripts on first document insertion
  4796. for ( i = 0; i < hasScripts; i++ ) {
  4797. node = scripts[ i ];
  4798. if ( rscriptType.test( node.type || "" ) &&
  4799. !data_priv.access( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
  4800. if ( node.src ) {
  4801. // Hope ajax is available...
  4802. jQuery._evalUrl( node.src );
  4803. } else {
  4804. jQuery.globalEval( node.textContent.replace( rcleanScript, "" ) );
  4805. }
  4806. }
  4807. }
  4808. }
  4809. }
  4810. }
  4811. return this;
  4812. }
  4813. });
  4814. jQuery.each({
  4815. appendTo: "append",
  4816. prependTo: "prepend",
  4817. insertBefore: "before",
  4818. insertAfter: "after",
  4819. replaceAll: "replaceWith"
  4820. }, function( name, original ) {
  4821. jQuery.fn[ name ] = function( selector ) {
  4822. var elems,
  4823. ret = [],
  4824. insert = jQuery( selector ),
  4825. last = insert.length - 1,
  4826. i = 0;
  4827. for ( ; i <= last; i++ ) {
  4828. elems = i === last ? this : this.clone( true );
  4829. jQuery( insert[ i ] )[ original ]( elems );
  4830. // Support: QtWebKit
  4831. // .get() because core_push.apply(_, arraylike) throws
  4832. core_push.apply( ret, elems.get() );
  4833. }
  4834. return this.pushStack( ret );
  4835. };
  4836. });
  4837. jQuery.extend({
  4838. clone: function( elem, dataAndEvents, deepDataAndEvents ) {
  4839. var i, l, srcElements, destElements,
  4840. clone = elem.cloneNode( true ),
  4841. inPage = jQuery.contains( elem.ownerDocument, elem );
  4842. // Support: IE >= 9
  4843. // Fix Cloning issues
  4844. if ( !jQuery.support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && !jQuery.isXMLDoc( elem ) ) {
  4845. // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
  4846. destElements = getAll( clone );
  4847. srcElements = getAll( elem );
  4848. for ( i = 0, l = srcElements.length; i < l; i++ ) {
  4849. fixInput( srcElements[ i ], destElements[ i ] );
  4850. }
  4851. }
  4852. // Copy the events from the original to the clone
  4853. if ( dataAndEvents ) {
  4854. if ( deepDataAndEvents ) {
  4855. srcElements = srcElements || getAll( elem );
  4856. destElements = destElements || getAll( clone );
  4857. for ( i = 0, l = srcElements.length; i < l; i++ ) {
  4858. cloneCopyEvent( srcElements[ i ], destElements[ i ] );
  4859. }
  4860. } else {
  4861. cloneCopyEvent( elem, clone );
  4862. }
  4863. }
  4864. // Preserve script evaluation history
  4865. destElements = getAll( clone, "script" );
  4866. if ( destElements.length > 0 ) {
  4867. setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
  4868. }
  4869. // Return the cloned set
  4870. return clone;
  4871. },
  4872. buildFragment: function( elems, context, scripts, selection ) {
  4873. var elem, tmp, tag, wrap, contains, j,
  4874. i = 0,
  4875. l = elems.length,
  4876. fragment = context.createDocumentFragment(),
  4877. nodes = [];
  4878. for ( ; i < l; i++ ) {
  4879. elem = elems[ i ];
  4880. if ( elem || elem === 0 ) {
  4881. // Add nodes directly
  4882. if ( jQuery.type( elem ) === "object" ) {
  4883. // Support: QtWebKit
  4884. // jQuery.merge because core_push.apply(_, arraylike) throws
  4885. jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
  4886. // Convert non-html into a text node
  4887. } else if ( !rhtml.test( elem ) ) {
  4888. nodes.push( context.createTextNode( elem ) );
  4889. // Convert html into DOM nodes
  4890. } else {
  4891. tmp = tmp || fragment.appendChild( context.createElement("div") );
  4892. // Deserialize a standard representation
  4893. tag = ( rtagName.exec( elem ) || ["", ""] )[ 1 ].toLowerCase();
  4894. wrap = wrapMap[ tag ] || wrapMap._default;
  4895. tmp.innerHTML = wrap[ 1 ] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[ 2 ];
  4896. // Descend through wrappers to the right content
  4897. j = wrap[ 0 ];
  4898. while ( j-- ) {
  4899. tmp = tmp.lastChild;
  4900. }
  4901. // Support: QtWebKit
  4902. // jQuery.merge because core_push.apply(_, arraylike) throws
  4903. jQuery.merge( nodes, tmp.childNodes );
  4904. // Remember the top-level container
  4905. tmp = fragment.firstChild;
  4906. // Fixes #12346
  4907. // Support: Webkit, IE
  4908. tmp.textContent = "";
  4909. }
  4910. }
  4911. }
  4912. // Remove wrapper from fragment
  4913. fragment.textContent = "";
  4914. i = 0;
  4915. while ( (elem = nodes[ i++ ]) ) {
  4916. // #4087 - If origin and destination elements are the same, and this is
  4917. // that element, do not do anything
  4918. if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
  4919. continue;
  4920. }
  4921. contains = jQuery.contains( elem.ownerDocument, elem );
  4922. // Append to fragment
  4923. tmp = getAll( fragment.appendChild( elem ), "script" );
  4924. // Preserve script evaluation history
  4925. if ( contains ) {
  4926. setGlobalEval( tmp );
  4927. }
  4928. // Capture executables
  4929. if ( scripts ) {
  4930. j = 0;
  4931. while ( (elem = tmp[ j++ ]) ) {
  4932. if ( rscriptType.test( elem.type || "" ) ) {
  4933. scripts.push( elem );
  4934. }
  4935. }
  4936. }
  4937. }
  4938. return fragment;
  4939. },
  4940. cleanData: function( elems ) {
  4941. var data, elem, events, type, key, j,
  4942. special = jQuery.event.special,
  4943. i = 0;
  4944. for ( ; (elem = elems[ i ]) !== undefined; i++ ) {
  4945. if ( Data.accepts( elem ) ) {
  4946. key = elem[ data_priv.expando ];
  4947. if ( key && (data = data_priv.cache[ key ]) ) {
  4948. events = Object.keys( data.events || {} );
  4949. if ( events.length ) {
  4950. for ( j = 0; (type = events[j]) !== undefined; j++ ) {
  4951. if ( special[ type ] ) {
  4952. jQuery.event.remove( elem, type );
  4953. // This is a shortcut to avoid jQuery.event.remove's overhead
  4954. } else {
  4955. jQuery.removeEvent( elem, type, data.handle );
  4956. }
  4957. }
  4958. }
  4959. if ( data_priv.cache[ key ] ) {
  4960. // Discard any remaining `private` data
  4961. delete data_priv.cache[ key ];
  4962. }
  4963. }
  4964. }
  4965. // Discard any remaining `user` data
  4966. delete data_user.cache[ elem[ data_user.expando ] ];
  4967. }
  4968. },
  4969. _evalUrl: function( url ) {
  4970. return jQuery.ajax({
  4971. url: url,
  4972. type: "GET",
  4973. dataType: "script",
  4974. async: false,
  4975. global: false,
  4976. "throws": true
  4977. });
  4978. }
  4979. });
  4980. // Support: 1.x compatibility
  4981. // Manipulating tables requires a tbody
  4982. function manipulationTarget( elem, content ) {
  4983. return jQuery.nodeName( elem, "table" ) &&
  4984. jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ?
  4985. elem.getElementsByTagName("tbody")[0] ||
  4986. elem.appendChild( elem.ownerDocument.createElement("tbody") ) :
  4987. elem;
  4988. }
  4989. // Replace/restore the type attribute of script elements for safe DOM manipulation
  4990. function disableScript( elem ) {
  4991. elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
  4992. return elem;
  4993. }
  4994. function restoreScript( elem ) {
  4995. var match = rscriptTypeMasked.exec( elem.type );
  4996. if ( match ) {
  4997. elem.type = match[ 1 ];
  4998. } else {
  4999. elem.removeAttribute("type");
  5000. }
  5001. return elem;
  5002. }
  5003. // Mark scripts as having already been evaluated
  5004. function setGlobalEval( elems, refElements ) {
  5005. var l = elems.length,
  5006. i = 0;
  5007. for ( ; i < l; i++ ) {
  5008. data_priv.set(
  5009. elems[ i ], "globalEval", !refElements || data_priv.get( refElements[ i ], "globalEval" )
  5010. );
  5011. }
  5012. }
  5013. function cloneCopyEvent( src, dest ) {
  5014. var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
  5015. if ( dest.nodeType !== 1 ) {
  5016. return;
  5017. }
  5018. // 1. Copy private data: events, handlers, etc.
  5019. if ( data_priv.hasData( src ) ) {
  5020. pdataOld = data_priv.access( src );
  5021. pdataCur = data_priv.set( dest, pdataOld );
  5022. events = pdataOld.events;
  5023. if ( events ) {
  5024. delete pdataCur.handle;
  5025. pdataCur.events = {};
  5026. for ( type in events ) {
  5027. for ( i = 0, l = events[ type ].length; i < l; i++ ) {
  5028. jQuery.event.add( dest, type, events[ type ][ i ] );
  5029. }
  5030. }
  5031. }
  5032. }
  5033. // 2. Copy user data
  5034. if ( data_user.hasData( src ) ) {
  5035. udataOld = data_user.access( src );
  5036. udataCur = jQuery.extend( {}, udataOld );
  5037. data_user.set( dest, udataCur );
  5038. }
  5039. }
  5040. function getAll( context, tag ) {
  5041. var ret = context.getElementsByTagName ? context.getElementsByTagName( tag || "*" ) :
  5042. context.querySelectorAll ? context.querySelectorAll( tag || "*" ) :
  5043. [];
  5044. return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
  5045. jQuery.merge( [ context ], ret ) :
  5046. ret;
  5047. }
  5048. // Support: IE >= 9
  5049. function fixInput( src, dest ) {
  5050. var nodeName = dest.nodeName.toLowerCase();
  5051. // Fails to persist the checked state of a cloned checkbox or radio button.
  5052. if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) {
  5053. dest.checked = src.checked;
  5054. // Fails to return the selected option to the default selected state when cloning options
  5055. } else if ( nodeName === "input" || nodeName === "textarea" ) {
  5056. dest.defaultValue = src.defaultValue;
  5057. }
  5058. }
  5059. jQuery.fn.extend({
  5060. wrapAll: function( html ) {
  5061. var wrap;
  5062. if ( jQuery.isFunction( html ) ) {
  5063. return this.each(function( i ) {
  5064. jQuery( this ).wrapAll( html.call(this, i) );
  5065. });
  5066. }
  5067. if ( this[ 0 ] ) {
  5068. // The elements to wrap the target around
  5069. wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
  5070. if ( this[ 0 ].parentNode ) {
  5071. wrap.insertBefore( this[ 0 ] );
  5072. }
  5073. wrap.map(function() {
  5074. var elem = this;
  5075. while ( elem.firstElementChild ) {
  5076. elem = elem.firstElementChild;
  5077. }
  5078. return elem;
  5079. }).append( this );
  5080. }
  5081. return this;
  5082. },
  5083. wrapInner: function( html ) {
  5084. if ( jQuery.isFunction( html ) ) {
  5085. return this.each(function( i ) {
  5086. jQuery( this ).wrapInner( html.call(this, i) );
  5087. });
  5088. }
  5089. return this.each(function() {
  5090. var self = jQuery( this ),
  5091. contents = self.contents();
  5092. if ( contents.length ) {
  5093. contents.wrapAll( html );
  5094. } else {
  5095. self.append( html );
  5096. }
  5097. });
  5098. },
  5099. wrap: function( html ) {
  5100. var isFunction = jQuery.isFunction( html );
  5101. return this.each(function( i ) {
  5102. jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );
  5103. });
  5104. },
  5105. unwrap: function() {
  5106. return this.parent().each(function() {
  5107. if ( !jQuery.nodeName( this, "body" ) ) {
  5108. jQuery( this ).replaceWith( this.childNodes );
  5109. }
  5110. }).end();
  5111. }
  5112. });
  5113. var curCSS, iframe,
  5114. // swappable if display is none or starts with table except "table", "table-cell", or "table-caption"
  5115. // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
  5116. rdisplayswap = /^(none|table(?!-c[ea]).+)/,
  5117. rmargin = /^margin/,
  5118. rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ),
  5119. rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ),
  5120. rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ),
  5121. elemdisplay = { BODY: "block" },
  5122. cssShow = { position: "absolute", visibility: "hidden", display: "block" },
  5123. cssNormalTransform = {
  5124. letterSpacing: 0,
  5125. fontWeight: 400
  5126. },
  5127. cssExpand = [ "Top", "Right", "Bottom", "Left" ],
  5128. cssPrefixes = [ "Webkit", "O", "Moz", "ms" ];
  5129. // return a css property mapped to a potentially vendor prefixed property
  5130. function vendorPropName( style, name ) {
  5131. // shortcut for names that are not vendor prefixed
  5132. if ( name in style ) {
  5133. return name;
  5134. }
  5135. // check for vendor prefixed names
  5136. var capName = name.charAt(0).toUpperCase() + name.slice(1),
  5137. origName = name,
  5138. i = cssPrefixes.length;
  5139. while ( i-- ) {
  5140. name = cssPrefixes[ i ] + capName;
  5141. if ( name in style ) {
  5142. return name;
  5143. }
  5144. }
  5145. return origName;
  5146. }
  5147. function isHidden( elem, el ) {
  5148. // isHidden might be called from jQuery#filter function;
  5149. // in that case, element will be second argument
  5150. elem = el || elem;
  5151. return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
  5152. }
  5153. // NOTE: we've included the "window" in window.getComputedStyle
  5154. // because jsdom on node.js will break without it.
  5155. function getStyles( elem ) {
  5156. return window.getComputedStyle( elem, null );
  5157. }
  5158. function showHide( elements, show ) {
  5159. var display, elem, hidden,
  5160. values = [],
  5161. index = 0,
  5162. length = elements.length;
  5163. for ( ; index < length; index++ ) {
  5164. elem = elements[ index ];
  5165. if ( !elem.style ) {
  5166. continue;
  5167. }
  5168. values[ index ] = data_priv.get( elem, "olddisplay" );
  5169. display = elem.style.display;
  5170. if ( show ) {
  5171. // Reset the inline display of this element to learn if it is
  5172. // being hidden by cascaded rules or not
  5173. if ( !values[ index ] && display === "none" ) {
  5174. elem.style.display = "";
  5175. }
  5176. // Set elements which have been overridden with display: none
  5177. // in a stylesheet to whatever the default browser style is
  5178. // for such an element
  5179. if ( elem.style.display === "" && isHidden( elem ) ) {
  5180. values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
  5181. }
  5182. } else {
  5183. if ( !values[ index ] ) {
  5184. hidden = isHidden( elem );
  5185. if ( display && display !== "none" || !hidden ) {
  5186. data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css(elem, "display") );
  5187. }
  5188. }
  5189. }
  5190. }
  5191. // Set the display of most of the elements in a second loop
  5192. // to avoid the constant reflow
  5193. for ( index = 0; index < length; index++ ) {
  5194. elem = elements[ index ];
  5195. if ( !elem.style ) {
  5196. continue;
  5197. }
  5198. if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
  5199. elem.style.display = show ? values[ index ] || "" : "none";
  5200. }
  5201. }
  5202. return elements;
  5203. }
  5204. jQuery.fn.extend({
  5205. css: function( name, value ) {
  5206. return jQuery.access( this, function( elem, name, value ) {
  5207. var styles, len,
  5208. map = {},
  5209. i = 0;
  5210. if ( jQuery.isArray( name ) ) {
  5211. styles = getStyles( elem );
  5212. len = name.length;
  5213. for ( ; i < len; i++ ) {
  5214. map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
  5215. }
  5216. return map;
  5217. }
  5218. return value !== undefined ?
  5219. jQuery.style( elem, name, value ) :
  5220. jQuery.css( elem, name );
  5221. }, name, value, arguments.length > 1 );
  5222. },
  5223. show: function() {
  5224. return showHide( this, true );
  5225. },
  5226. hide: function() {
  5227. return showHide( this );
  5228. },
  5229. toggle: function( state ) {
  5230. if ( typeof state === "boolean" ) {
  5231. return state ? this.show() : this.hide();
  5232. }
  5233. return this.each(function() {
  5234. if ( isHidden( this ) ) {
  5235. jQuery( this ).show();
  5236. } else {
  5237. jQuery( this ).hide();
  5238. }
  5239. });
  5240. }
  5241. });
  5242. jQuery.extend({
  5243. // Add in style property hooks for overriding the default
  5244. // behavior of getting and setting a style property
  5245. cssHooks: {
  5246. opacity: {
  5247. get: function( elem, computed ) {
  5248. if ( computed ) {
  5249. // We should always get a number back from opacity
  5250. var ret = curCSS( elem, "opacity" );
  5251. return ret === "" ? "1" : ret;
  5252. }
  5253. }
  5254. }
  5255. },
  5256. // Don't automatically add "px" to these possibly-unitless properties
  5257. cssNumber: {
  5258. "columnCount": true,
  5259. "fillOpacity": true,
  5260. "fontWeight": true,
  5261. "lineHeight": true,
  5262. "opacity": true,
  5263. "order": true,
  5264. "orphans": true,
  5265. "widows": true,
  5266. "zIndex": true,
  5267. "zoom": true
  5268. },
  5269. // Add in properties whose names you wish to fix before
  5270. // setting or getting the value
  5271. cssProps: {
  5272. // normalize float css property
  5273. "float": "cssFloat"
  5274. },
  5275. // Get and set the style property on a DOM Node
  5276. style: function( elem, name, value, extra ) {
  5277. // Don't set styles on text and comment nodes
  5278. if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
  5279. return;
  5280. }
  5281. // Make sure that we're working with the right name
  5282. var ret, type, hooks,
  5283. origName = jQuery.camelCase( name ),
  5284. style = elem.style;
  5285. name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );
  5286. // gets hook for the prefixed version
  5287. // followed by the unprefixed version
  5288. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  5289. // Check if we're setting a value
  5290. if ( value !== undefined ) {
  5291. type = typeof value;
  5292. // convert relative number strings (+= or -=) to relative numbers. #7345
  5293. if ( type === "string" && (ret = rrelNum.exec( value )) ) {
  5294. value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );
  5295. // Fixes bug #9237
  5296. type = "number";
  5297. }
  5298. // Make sure that NaN and null values aren't set. See: #7116
  5299. if ( value == null || type === "number" && isNaN( value ) ) {
  5300. return;
  5301. }
  5302. // If a number was passed in, add 'px' to the (except for certain CSS properties)
  5303. if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
  5304. value += "px";
  5305. }
  5306. // Fixes #8908, it can be done more correctly by specifying setters in cssHooks,
  5307. // but it would mean to define eight (for every problematic property) identical functions
  5308. if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
  5309. style[ name ] = "inherit";
  5310. }
  5311. // If a hook was provided, use that value, otherwise just set the specified value
  5312. if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {
  5313. style[ name ] = value;
  5314. }
  5315. } else {
  5316. // If a hook was provided get the non-computed value from there
  5317. if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
  5318. return ret;
  5319. }
  5320. // Otherwise just get the value from the style object
  5321. return style[ name ];
  5322. }
  5323. },
  5324. css: function( elem, name, extra, styles ) {
  5325. var val, num, hooks,
  5326. origName = jQuery.camelCase( name );
  5327. // Make sure that we're working with the right name
  5328. name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
  5329. // gets hook for the prefixed version
  5330. // followed by the unprefixed version
  5331. hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
  5332. // If a hook was provided get the computed value from there
  5333. if ( hooks && "get" in hooks ) {
  5334. val = hooks.get( elem, true, extra );
  5335. }
  5336. // Otherwise, if a way to get the computed value exists, use that
  5337. if ( val === undefined ) {
  5338. val = curCSS( elem, name, styles );
  5339. }
  5340. //convert "normal" to computed value
  5341. if ( val === "normal" && name in cssNormalTransform ) {
  5342. val = cssNormalTransform[ name ];
  5343. }
  5344. // Return, converting to number if forced or a qualifier was provided and val looks numeric
  5345. if ( extra === "" || extra ) {
  5346. num = parseFloat( val );
  5347. return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
  5348. }
  5349. return val;
  5350. }
  5351. });
  5352. curCSS = function( elem, name, _computed ) {
  5353. var width, minWidth, maxWidth,
  5354. computed = _computed || getStyles( elem ),
  5355. // Support: IE9
  5356. // getPropertyValue is only needed for .css('filter') in IE9, see #12537
  5357. ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
  5358. style = elem.style;
  5359. if ( computed ) {
  5360. if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
  5361. ret = jQuery.style( elem, name );
  5362. }
  5363. // Support: Safari 5.1
  5364. // A tribute to the "awesome hack by Dean Edwards"
  5365. // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels
  5366. // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
  5367. if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {
  5368. // Remember the original values
  5369. width = style.width;
  5370. minWidth = style.minWidth;
  5371. maxWidth = style.maxWidth;
  5372. // Put in the new values to get a computed value out
  5373. style.minWidth = style.maxWidth = style.width = ret;
  5374. ret = computed.width;
  5375. // Revert the changed values
  5376. style.width = width;
  5377. style.minWidth = minWidth;
  5378. style.maxWidth = maxWidth;
  5379. }
  5380. }
  5381. return ret;
  5382. };
  5383. function setPositiveNumber( elem, value, subtract ) {
  5384. var matches = rnumsplit.exec( value );
  5385. return matches ?
  5386. // Guard against undefined "subtract", e.g., when used as in cssHooks
  5387. Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
  5388. value;
  5389. }
  5390. function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  5391. var i = extra === ( isBorderBox ? "border" : "content" ) ?
  5392. // If we already have the right measurement, avoid augmentation
  5393. 4 :
  5394. // Otherwise initialize for horizontal or vertical properties
  5395. name === "width" ? 1 : 0,
  5396. val = 0;
  5397. for ( ; i < 4; i += 2 ) {
  5398. // both box models exclude margin, so add it if we want it
  5399. if ( extra === "margin" ) {
  5400. val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
  5401. }
  5402. if ( isBorderBox ) {
  5403. // border-box includes padding, so remove it if we want content
  5404. if ( extra === "content" ) {
  5405. val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  5406. }
  5407. // at this point, extra isn't border nor margin, so remove border
  5408. if ( extra !== "margin" ) {
  5409. val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  5410. }
  5411. } else {
  5412. // at this point, extra isn't content, so add padding
  5413. val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
  5414. // at this point, extra isn't content nor padding, so add border
  5415. if ( extra !== "padding" ) {
  5416. val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
  5417. }
  5418. }
  5419. }
  5420. return val;
  5421. }
  5422. function getWidthOrHeight( elem, name, extra ) {
  5423. // Start with offset property, which is equivalent to the border-box value
  5424. var valueIsBorderBox = true,
  5425. val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
  5426. styles = getStyles( elem ),
  5427. isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
  5428. // some non-html elements return undefined for offsetWidth, so check for null/undefined
  5429. // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
  5430. // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
  5431. if ( val <= 0 || val == null ) {
  5432. // Fall back to computed then uncomputed css if necessary
  5433. val = curCSS( elem, name, styles );
  5434. if ( val < 0 || val == null ) {
  5435. val = elem.style[ name ];
  5436. }
  5437. // Computed unit is not pixels. Stop here and return.
  5438. if ( rnumnonpx.test(val) ) {
  5439. return val;
  5440. }
  5441. // we need the check for style in case a browser which returns unreliable values
  5442. // for getComputedStyle silently falls back to the reliable elem.style
  5443. valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );
  5444. // Normalize "", auto, and prepare for extra
  5445. val = parseFloat( val ) || 0;
  5446. }
  5447. // use the active box-sizing model to add/subtract irrelevant styles
  5448. return ( val +
  5449. augmentWidthOrHeight(
  5450. elem,
  5451. name,
  5452. extra || ( isBorderBox ? "border" : "content" ),
  5453. valueIsBorderBox,
  5454. styles
  5455. )
  5456. ) + "px";
  5457. }
  5458. // Try to determine the default display value of an element
  5459. function css_defaultDisplay( nodeName ) {
  5460. var doc = document,
  5461. display = elemdisplay[ nodeName ];
  5462. if ( !display ) {
  5463. display = actualDisplay( nodeName, doc );
  5464. // If the simple way fails, read from inside an iframe
  5465. if ( display === "none" || !display ) {
  5466. // Use the already-created iframe if possible
  5467. iframe = ( iframe ||
  5468. jQuery("<iframe frameborder='0' width='0' height='0'/>")
  5469. .css( "cssText", "display:block !important" )
  5470. ).appendTo( doc.documentElement );
  5471. // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
  5472. doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
  5473. doc.write("<!doctype html><html><body>");
  5474. doc.close();
  5475. display = actualDisplay( nodeName, doc );
  5476. iframe.detach();
  5477. }
  5478. // Store the correct default display
  5479. elemdisplay[ nodeName ] = display;
  5480. }
  5481. return display;
  5482. }
  5483. // Called ONLY from within css_defaultDisplay
  5484. function actualDisplay( name, doc ) {
  5485. var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
  5486. display = jQuery.css( elem[0], "display" );
  5487. elem.remove();
  5488. return display;
  5489. }
  5490. jQuery.each([ "height", "width" ], function( i, name ) {
  5491. jQuery.cssHooks[ name ] = {
  5492. get: function( elem, computed, extra ) {
  5493. if ( computed ) {
  5494. // certain elements can have dimension info if we invisibly show them
  5495. // however, it must have a current display style that would benefit from this
  5496. return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
  5497. jQuery.swap( elem, cssShow, function() {
  5498. return getWidthOrHeight( elem, name, extra );
  5499. }) :
  5500. getWidthOrHeight( elem, name, extra );
  5501. }
  5502. },
  5503. set: function( elem, value, extra ) {
  5504. var styles = extra && getStyles( elem );
  5505. return setPositiveNumber( elem, value, extra ?
  5506. augmentWidthOrHeight(
  5507. elem,
  5508. name,
  5509. extra,
  5510. jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
  5511. styles
  5512. ) : 0
  5513. );
  5514. }
  5515. };
  5516. });
  5517. // These hooks cannot be added until DOM ready because the support test
  5518. // for it is not run until after DOM ready
  5519. jQuery(function() {
  5520. // Support: Android 2.3
  5521. if ( !jQuery.support.reliableMarginRight ) {
  5522. jQuery.cssHooks.marginRight = {
  5523. get: function( elem, computed ) {
  5524. if ( computed ) {
  5525. // Support: Android 2.3
  5526. // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
  5527. // Work around by temporarily setting element display to inline-block
  5528. return jQuery.swap( elem, { "display": "inline-block" },
  5529. curCSS, [ elem, "marginRight" ] );
  5530. }
  5531. }
  5532. };
  5533. }
  5534. // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
  5535. // getComputedStyle returns percent when specified for top/left/bottom/right
  5536. // rather than make the css module depend on the offset module, we just check for it here
  5537. if ( !jQuery.support.pixelPosition && jQuery.fn.position ) {
  5538. jQuery.each( [ "top", "left" ], function( i, prop ) {
  5539. jQuery.cssHooks[ prop ] = {
  5540. get: function( elem, computed ) {
  5541. if ( computed ) {
  5542. computed = curCSS( elem, prop );
  5543. // if curCSS returns percentage, fallback to offset
  5544. return rnumnonpx.test( computed ) ?
  5545. jQuery( elem ).position()[ prop ] + "px" :
  5546. computed;
  5547. }
  5548. }
  5549. };
  5550. });
  5551. }
  5552. });
  5553. if ( jQuery.expr && jQuery.expr.filters ) {
  5554. jQuery.expr.filters.hidden = function( elem ) {
  5555. // Support: Opera <= 12.12
  5556. // Opera reports offsetWidths and offsetHeights less than zero on some elements
  5557. return elem.offsetWidth <= 0 && elem.offsetHeight <= 0;
  5558. };
  5559. jQuery.expr.filters.visible = function( elem ) {
  5560. return !jQuery.expr.filters.hidden( elem );
  5561. };
  5562. }
  5563. // These hooks are used by animate to expand properties
  5564. jQuery.each({
  5565. margin: "",
  5566. padding: "",
  5567. border: "Width"
  5568. }, function( prefix, suffix ) {
  5569. jQuery.cssHooks[ prefix + suffix ] = {
  5570. expand: function( value ) {
  5571. var i = 0,
  5572. expanded = {},
  5573. // assumes a single number if not a string
  5574. parts = typeof value === "string" ? value.split(" ") : [ value ];
  5575. for ( ; i < 4; i++ ) {
  5576. expanded[ prefix + cssExpand[ i ] + suffix ] =
  5577. parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
  5578. }
  5579. return expanded;
  5580. }
  5581. };
  5582. if ( !rmargin.test( prefix ) ) {
  5583. jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
  5584. }
  5585. });
  5586. var r20 = /%20/g,
  5587. rbracket = /\[\]$/,
  5588. rCRLF = /\r?\n/g,
  5589. rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
  5590. rsubmittable = /^(?:input|select|textarea|keygen)/i;
  5591. jQuery.fn.extend({
  5592. serialize: function() {
  5593. return jQuery.param( this.serializeArray() );
  5594. },
  5595. serializeArray: function() {
  5596. return this.map(function(){
  5597. // Can add propHook for "elements" to filter or add form elements
  5598. var elements = jQuery.prop( this, "elements" );
  5599. return elements ? jQuery.makeArray( elements ) : this;
  5600. })
  5601. .filter(function(){
  5602. var type = this.type;
  5603. // Use .is(":disabled") so that fieldset[disabled] works
  5604. return this.name && !jQuery( this ).is( ":disabled" ) &&
  5605. rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
  5606. ( this.checked || !manipulation_rcheckableType.test( type ) );
  5607. })
  5608. .map(function( i, elem ){
  5609. var val = jQuery( this ).val();
  5610. return val == null ?
  5611. null :
  5612. jQuery.isArray( val ) ?
  5613. jQuery.map( val, function( val ){
  5614. return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  5615. }) :
  5616. { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
  5617. }).get();
  5618. }
  5619. });
  5620. //Serialize an array of form elements or a set of
  5621. //key/values into a query string
  5622. jQuery.param = function( a, traditional ) {
  5623. var prefix,
  5624. s = [],
  5625. add = function( key, value ) {
  5626. // If value is a function, invoke it and return its value
  5627. value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value );
  5628. s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value );
  5629. };
  5630. // Set traditional to true for jQuery <= 1.3.2 behavior.
  5631. if ( traditional === undefined ) {
  5632. traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
  5633. }
  5634. // If an array was passed in, assume that it is an array of form elements.
  5635. if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
  5636. // Serialize the form elements
  5637. jQuery.each( a, function() {
  5638. add( this.name, this.value );
  5639. });
  5640. } else {
  5641. // If traditional, encode the "old" way (the way 1.3.2 or older
  5642. // did it), otherwise encode params recursively.
  5643. for ( prefix in a ) {
  5644. buildParams( prefix, a[ prefix ], traditional, add );
  5645. }
  5646. }
  5647. // Return the resulting serialization
  5648. return s.join( "&" ).replace( r20, "+" );
  5649. };
  5650. function buildParams( prefix, obj, traditional, add ) {
  5651. var name;
  5652. if ( jQuery.isArray( obj ) ) {
  5653. // Serialize array item.
  5654. jQuery.each( obj, function( i, v ) {
  5655. if ( traditional || rbracket.test( prefix ) ) {
  5656. // Treat each array item as a scalar.
  5657. add( prefix, v );
  5658. } else {
  5659. // Item is non-scalar (array or object), encode its numeric index.
  5660. buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add );
  5661. }
  5662. });
  5663. } else if ( !traditional && jQuery.type( obj ) === "object" ) {
  5664. // Serialize object item.
  5665. for ( name in obj ) {
  5666. buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
  5667. }
  5668. } else {
  5669. // Serialize scalar item.
  5670. add( prefix, obj );
  5671. }
  5672. }
  5673. jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
  5674. "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
  5675. "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {
  5676. // Handle event binding
  5677. jQuery.fn[ name ] = function( data, fn ) {
  5678. return arguments.length > 0 ?
  5679. this.on( name, null, data, fn ) :
  5680. this.trigger( name );
  5681. };
  5682. });
  5683. jQuery.fn.extend({
  5684. hover: function( fnOver, fnOut ) {
  5685. return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
  5686. },
  5687. bind: function( types, data, fn ) {
  5688. return this.on( types, null, data, fn );
  5689. },
  5690. unbind: function( types, fn ) {
  5691. return this.off( types, null, fn );
  5692. },
  5693. delegate: function( selector, types, data, fn ) {
  5694. return this.on( types, selector, data, fn );
  5695. },
  5696. undelegate: function( selector, types, fn ) {
  5697. // ( namespace ) or ( selector, types [, fn] )
  5698. return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn );
  5699. }
  5700. });
  5701. var
  5702. // Document location
  5703. ajaxLocParts,
  5704. ajaxLocation,
  5705. ajax_nonce = jQuery.now(),
  5706. ajax_rquery = /\?/,
  5707. rhash = /#.*$/,
  5708. rts = /([?&])_=[^&]*/,
  5709. rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
  5710. // #7653, #8125, #8152: local protocol detection
  5711. rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
  5712. rnoContent = /^(?:GET|HEAD)$/,
  5713. rprotocol = /^\/\//,
  5714. rurl = /^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,
  5715. // Keep a copy of the old load method
  5716. _load = jQuery.fn.load,
  5717. /* Prefilters
  5718. * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  5719. * 2) These are called:
  5720. * - BEFORE asking for a transport
  5721. * - AFTER param serialization (s.data is a string if s.processData is true)
  5722. * 3) key is the dataType
  5723. * 4) the catchall symbol "*" can be used
  5724. * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  5725. */
  5726. prefilters = {},
  5727. /* Transports bindings
  5728. * 1) key is the dataType
  5729. * 2) the catchall symbol "*" can be used
  5730. * 3) selection will start with transport dataType and THEN go to "*" if needed
  5731. */
  5732. transports = {},
  5733. // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
  5734. allTypes = "*/".concat("*");
  5735. // #8138, IE may throw an exception when accessing
  5736. // a field from window.location if document.domain has been set
  5737. try {
  5738. ajaxLocation = location.href;
  5739. } catch( e ) {
  5740. // Use the href attribute of an A element
  5741. // since IE will modify it given document.location
  5742. ajaxLocation = document.createElement( "a" );
  5743. ajaxLocation.href = "";
  5744. ajaxLocation = ajaxLocation.href;
  5745. }
  5746. // Segment location into parts
  5747. ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];
  5748. // Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
  5749. function addToPrefiltersOrTransports( structure ) {
  5750. // dataTypeExpression is optional and defaults to "*"
  5751. return function( dataTypeExpression, func ) {
  5752. if ( typeof dataTypeExpression !== "string" ) {
  5753. func = dataTypeExpression;
  5754. dataTypeExpression = "*";
  5755. }
  5756. var dataType,
  5757. i = 0,
  5758. dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
  5759. if ( jQuery.isFunction( func ) ) {
  5760. // For each dataType in the dataTypeExpression
  5761. while ( (dataType = dataTypes[i++]) ) {
  5762. // Prepend if requested
  5763. if ( dataType[0] === "+" ) {
  5764. dataType = dataType.slice( 1 ) || "*";
  5765. (structure[ dataType ] = structure[ dataType ] || []).unshift( func );
  5766. // Otherwise append
  5767. } else {
  5768. (structure[ dataType ] = structure[ dataType ] || []).push( func );
  5769. }
  5770. }
  5771. }
  5772. };
  5773. }
  5774. // Base inspection function for prefilters and transports
  5775. function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
  5776. var inspected = {},
  5777. seekingTransport = ( structure === transports );
  5778. function inspect( dataType ) {
  5779. var selected;
  5780. inspected[ dataType ] = true;
  5781. jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
  5782. var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
  5783. if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
  5784. options.dataTypes.unshift( dataTypeOrTransport );
  5785. inspect( dataTypeOrTransport );
  5786. return false;
  5787. } else if ( seekingTransport ) {
  5788. return !( selected = dataTypeOrTransport );
  5789. }
  5790. });
  5791. return selected;
  5792. }
  5793. return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
  5794. }
  5795. // A special extend for ajax options
  5796. // that takes "flat" options (not to be deep extended)
  5797. // Fixes #9887
  5798. function ajaxExtend( target, src ) {
  5799. var key, deep,
  5800. flatOptions = jQuery.ajaxSettings.flatOptions || {};
  5801. for ( key in src ) {
  5802. if ( src[ key ] !== undefined ) {
  5803. ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];
  5804. }
  5805. }
  5806. if ( deep ) {
  5807. jQuery.extend( true, target, deep );
  5808. }
  5809. return target;
  5810. }
  5811. jQuery.fn.load = function( url, params, callback ) {
  5812. if ( typeof url !== "string" && _load ) {
  5813. return _load.apply( this, arguments );
  5814. }
  5815. var selector, type, response,
  5816. self = this,
  5817. off = url.indexOf(" ");
  5818. if ( off >= 0 ) {
  5819. selector = url.slice( off );
  5820. url = url.slice( 0, off );
  5821. }
  5822. // If it's a function
  5823. if ( jQuery.isFunction( params ) ) {
  5824. // We assume that it's the callback
  5825. callback = params;
  5826. params = undefined;
  5827. // Otherwise, build a param string
  5828. } else if ( params && typeof params === "object" ) {
  5829. type = "POST";
  5830. }
  5831. // If we have elements to modify, make the request
  5832. if ( self.length > 0 ) {
  5833. jQuery.ajax({
  5834. url: url,
  5835. // if "type" variable is undefined, then "GET" method will be used
  5836. type: type,
  5837. dataType: "html",
  5838. data: params
  5839. }).done(function( responseText ) {
  5840. // Save response for use in complete callback
  5841. response = arguments;
  5842. self.html( selector ?
  5843. // If a selector was specified, locate the right elements in a dummy div
  5844. // Exclude scripts to avoid IE 'Permission Denied' errors
  5845. jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
  5846. // Otherwise use the full result
  5847. responseText );
  5848. }).complete( callback && function( jqXHR, status ) {
  5849. self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
  5850. });
  5851. }
  5852. return this;
  5853. };
  5854. // Attach a bunch of functions for handling common AJAX events
  5855. jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
  5856. jQuery.fn[ type ] = function( fn ){
  5857. return this.on( type, fn );
  5858. };
  5859. });
  5860. jQuery.extend({
  5861. // Counter for holding the number of active queries
  5862. active: 0,
  5863. // Last-Modified header cache for next request
  5864. lastModified: {},
  5865. etag: {},
  5866. ajaxSettings: {
  5867. url: ajaxLocation,
  5868. type: "GET",
  5869. isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
  5870. global: true,
  5871. processData: true,
  5872. async: true,
  5873. contentType: "application/x-www-form-urlencoded; charset=UTF-8",
  5874. /*
  5875. timeout: 0,
  5876. data: null,
  5877. dataType: null,
  5878. username: null,
  5879. password: null,
  5880. cache: null,
  5881. throws: false,
  5882. traditional: false,
  5883. headers: {},
  5884. */
  5885. accepts: {
  5886. "*": allTypes,
  5887. text: "text/plain",
  5888. html: "text/html",
  5889. xml: "application/xml, text/xml",
  5890. json: "application/json, text/javascript"
  5891. },
  5892. contents: {
  5893. xml: /xml/,
  5894. html: /html/,
  5895. json: /json/
  5896. },
  5897. responseFields: {
  5898. xml: "responseXML",
  5899. text: "responseText",
  5900. json: "responseJSON"
  5901. },
  5902. // Data converters
  5903. // Keys separate source (or catchall "*") and destination types with a single space
  5904. converters: {
  5905. // Convert anything to text
  5906. "* text": String,
  5907. // Text to html (true = no transformation)
  5908. "text html": true,
  5909. // Evaluate text as a json expression
  5910. "text json": jQuery.parseJSON,
  5911. // Parse text as xml
  5912. "text xml": jQuery.parseXML
  5913. },
  5914. // For options that shouldn't be deep extended:
  5915. // you can add your own custom options here if
  5916. // and when you create one that shouldn't be
  5917. // deep extended (see ajaxExtend)
  5918. flatOptions: {
  5919. url: true,
  5920. context: true
  5921. }
  5922. },
  5923. // Creates a full fledged settings object into target
  5924. // with both ajaxSettings and settings fields.
  5925. // If target is omitted, writes into ajaxSettings.
  5926. ajaxSetup: function( target, settings ) {
  5927. return settings ?
  5928. // Building a settings object
  5929. ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
  5930. // Extending ajaxSettings
  5931. ajaxExtend( jQuery.ajaxSettings, target );
  5932. },
  5933. ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
  5934. ajaxTransport: addToPrefiltersOrTransports( transports ),
  5935. // Main method
  5936. ajax: function( url, options ) {
  5937. // If url is an object, simulate pre-1.5 signature
  5938. if ( typeof url === "object" ) {
  5939. options = url;
  5940. url = undefined;
  5941. }
  5942. // Force options to be an object
  5943. options = options || {};
  5944. var transport,
  5945. // URL without anti-cache param
  5946. cacheURL,
  5947. // Response headers
  5948. responseHeadersString,
  5949. responseHeaders,
  5950. // timeout handle
  5951. timeoutTimer,
  5952. // Cross-domain detection vars
  5953. parts,
  5954. // To know if global events are to be dispatched
  5955. fireGlobals,
  5956. // Loop variable
  5957. i,
  5958. // Create the final options object
  5959. s = jQuery.ajaxSetup( {}, options ),
  5960. // Callbacks context
  5961. callbackContext = s.context || s,
  5962. // Context for global events is callbackContext if it is a DOM node or jQuery collection
  5963. globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?
  5964. jQuery( callbackContext ) :
  5965. jQuery.event,
  5966. // Deferreds
  5967. deferred = jQuery.Deferred(),
  5968. completeDeferred = jQuery.Callbacks("once memory"),
  5969. // Status-dependent callbacks
  5970. statusCode = s.statusCode || {},
  5971. // Headers (they are sent all at once)
  5972. requestHeaders = {},
  5973. requestHeadersNames = {},
  5974. // The jqXHR state
  5975. state = 0,
  5976. // Default abort message
  5977. strAbort = "canceled",
  5978. // Fake xhr
  5979. jqXHR = {
  5980. readyState: 0,
  5981. // Builds headers hashtable if needed
  5982. getResponseHeader: function( key ) {
  5983. var match;
  5984. if ( state === 2 ) {
  5985. if ( !responseHeaders ) {
  5986. responseHeaders = {};
  5987. while ( (match = rheaders.exec( responseHeadersString )) ) {
  5988. responseHeaders[ match[1].toLowerCase() ] = match[ 2 ];
  5989. }
  5990. }
  5991. match = responseHeaders[ key.toLowerCase() ];
  5992. }
  5993. return match == null ? null : match;
  5994. },
  5995. // Raw string
  5996. getAllResponseHeaders: function() {
  5997. return state === 2 ? responseHeadersString : null;
  5998. },
  5999. // Caches the header
  6000. setRequestHeader: function( name, value ) {
  6001. var lname = name.toLowerCase();
  6002. if ( !state ) {
  6003. name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
  6004. requestHeaders[ name ] = value;
  6005. }
  6006. return this;
  6007. },
  6008. // Overrides response content-type header
  6009. overrideMimeType: function( type ) {
  6010. if ( !state ) {
  6011. s.mimeType = type;
  6012. }
  6013. return this;
  6014. },
  6015. // Status-dependent callbacks
  6016. statusCode: function( map ) {
  6017. var code;
  6018. if ( map ) {
  6019. if ( state < 2 ) {
  6020. for ( code in map ) {
  6021. // Lazy-add the new callback in a way that preserves old ones
  6022. statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
  6023. }
  6024. } else {
  6025. // Execute the appropriate callbacks
  6026. jqXHR.always( map[ jqXHR.status ] );
  6027. }
  6028. }
  6029. return this;
  6030. },
  6031. // Cancel the request
  6032. abort: function( statusText ) {
  6033. var finalText = statusText || strAbort;
  6034. if ( transport ) {
  6035. transport.abort( finalText );
  6036. }
  6037. done( 0, finalText );
  6038. return this;
  6039. }
  6040. };
  6041. // Attach deferreds
  6042. deferred.promise( jqXHR ).complete = completeDeferred.add;
  6043. jqXHR.success = jqXHR.done;
  6044. jqXHR.error = jqXHR.fail;
  6045. // Remove hash character (#7531: and string promotion)
  6046. // Add protocol if not provided (prefilters might expect it)
  6047. // Handle falsy url in the settings object (#10093: consistency with old signature)
  6048. // We also use the url parameter if available
  6049. s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" )
  6050. .replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
  6051. // Alias method option to type as per ticket #12004
  6052. s.type = options.method || options.type || s.method || s.type;
  6053. // Extract dataTypes list
  6054. s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
  6055. // A cross-domain request is in order when we have a protocol:host:port mismatch
  6056. if ( s.crossDomain == null ) {
  6057. parts = rurl.exec( s.url.toLowerCase() );
  6058. s.crossDomain = !!( parts &&
  6059. ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||
  6060. ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !==
  6061. ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) )
  6062. );
  6063. }
  6064. // Convert data if not already a string
  6065. if ( s.data && s.processData && typeof s.data !== "string" ) {
  6066. s.data = jQuery.param( s.data, s.traditional );
  6067. }
  6068. // Apply prefilters
  6069. inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
  6070. // If request was aborted inside a prefilter, stop there
  6071. if ( state === 2 ) {
  6072. return jqXHR;
  6073. }
  6074. // We can fire global events as of now if asked to
  6075. fireGlobals = s.global;
  6076. // Watch for a new set of requests
  6077. if ( fireGlobals && jQuery.active++ === 0 ) {
  6078. jQuery.event.trigger("ajaxStart");
  6079. }
  6080. // Uppercase the type
  6081. s.type = s.type.toUpperCase();
  6082. // Determine if request has content
  6083. s.hasContent = !rnoContent.test( s.type );
  6084. // Save the URL in case we're toying with the If-Modified-Since
  6085. // and/or If-None-Match header later on
  6086. cacheURL = s.url;
  6087. // More options handling for requests with no content
  6088. if ( !s.hasContent ) {
  6089. // If data is available, append data to url
  6090. if ( s.data ) {
  6091. cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
  6092. // #9682: remove data so that it's not used in an eventual retry
  6093. delete s.data;
  6094. }
  6095. // Add anti-cache in url if needed
  6096. if ( s.cache === false ) {
  6097. s.url = rts.test( cacheURL ) ?
  6098. // If there is already a '_' parameter, set its value
  6099. cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
  6100. // Otherwise add one to the end
  6101. cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
  6102. }
  6103. }
  6104. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  6105. if ( s.ifModified ) {
  6106. if ( jQuery.lastModified[ cacheURL ] ) {
  6107. jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
  6108. }
  6109. if ( jQuery.etag[ cacheURL ] ) {
  6110. jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
  6111. }
  6112. }
  6113. // Set the correct header, if data is being sent
  6114. if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
  6115. jqXHR.setRequestHeader( "Content-Type", s.contentType );
  6116. }
  6117. // Set the Accepts header for the server, depending on the dataType
  6118. jqXHR.setRequestHeader(
  6119. "Accept",
  6120. s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?
  6121. s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
  6122. s.accepts[ "*" ]
  6123. );
  6124. // Check for headers option
  6125. for ( i in s.headers ) {
  6126. jqXHR.setRequestHeader( i, s.headers[ i ] );
  6127. }
  6128. // Allow custom headers/mimetypes and early abort
  6129. if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {
  6130. // Abort if not done already and return
  6131. return jqXHR.abort();
  6132. }
  6133. // aborting is no longer a cancellation
  6134. strAbort = "abort";
  6135. // Install callbacks on deferreds
  6136. for ( i in { success: 1, error: 1, complete: 1 } ) {
  6137. jqXHR[ i ]( s[ i ] );
  6138. }
  6139. // Get transport
  6140. transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
  6141. // If no transport, we auto-abort
  6142. if ( !transport ) {
  6143. done( -1, "No Transport" );
  6144. } else {
  6145. jqXHR.readyState = 1;
  6146. // Send global event
  6147. if ( fireGlobals ) {
  6148. globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
  6149. }
  6150. // Timeout
  6151. if ( s.async && s.timeout > 0 ) {
  6152. timeoutTimer = setTimeout(function() {
  6153. jqXHR.abort("timeout");
  6154. }, s.timeout );
  6155. }
  6156. try {
  6157. state = 1;
  6158. transport.send( requestHeaders, done );
  6159. } catch ( e ) {
  6160. // Propagate exception as error if not done
  6161. if ( state < 2 ) {
  6162. done( -1, e );
  6163. // Simply rethrow otherwise
  6164. } else {
  6165. throw e;
  6166. }
  6167. }
  6168. }
  6169. // Callback for when everything is done
  6170. function done( status, nativeStatusText, responses, headers ) {
  6171. var isSuccess, success, error, response, modified,
  6172. statusText = nativeStatusText;
  6173. // Called once
  6174. if ( state === 2 ) {
  6175. return;
  6176. }
  6177. // State is "done" now
  6178. state = 2;
  6179. // Clear timeout if it exists
  6180. if ( timeoutTimer ) {
  6181. clearTimeout( timeoutTimer );
  6182. }
  6183. // Dereference transport for early garbage collection
  6184. // (no matter how long the jqXHR object will be used)
  6185. transport = undefined;
  6186. // Cache response headers
  6187. responseHeadersString = headers || "";
  6188. // Set readyState
  6189. jqXHR.readyState = status > 0 ? 4 : 0;
  6190. // Determine if successful
  6191. isSuccess = status >= 200 && status < 300 || status === 304;
  6192. // Get response data
  6193. if ( responses ) {
  6194. response = ajaxHandleResponses( s, jqXHR, responses );
  6195. }
  6196. // Convert no matter what (that way responseXXX fields are always set)
  6197. response = ajaxConvert( s, response, jqXHR, isSuccess );
  6198. // If successful, handle type chaining
  6199. if ( isSuccess ) {
  6200. // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
  6201. if ( s.ifModified ) {
  6202. modified = jqXHR.getResponseHeader("Last-Modified");
  6203. if ( modified ) {
  6204. jQuery.lastModified[ cacheURL ] = modified;
  6205. }
  6206. modified = jqXHR.getResponseHeader("etag");
  6207. if ( modified ) {
  6208. jQuery.etag[ cacheURL ] = modified;
  6209. }
  6210. }
  6211. // if no content
  6212. if ( status === 204 || s.type === "HEAD" ) {
  6213. statusText = "nocontent";
  6214. // if not modified
  6215. } else if ( status === 304 ) {
  6216. statusText = "notmodified";
  6217. // If we have data, let's convert it
  6218. } else {
  6219. statusText = response.state;
  6220. success = response.data;
  6221. error = response.error;
  6222. isSuccess = !error;
  6223. }
  6224. } else {
  6225. // We extract error from statusText
  6226. // then normalize statusText and status for non-aborts
  6227. error = statusText;
  6228. if ( status || !statusText ) {
  6229. statusText = "error";
  6230. if ( status < 0 ) {
  6231. status = 0;
  6232. }
  6233. }
  6234. }
  6235. // Set data for the fake xhr object
  6236. jqXHR.status = status;
  6237. jqXHR.statusText = ( nativeStatusText || statusText ) + "";
  6238. // Success/Error
  6239. if ( isSuccess ) {
  6240. deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
  6241. } else {
  6242. deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
  6243. }
  6244. // Status-dependent callbacks
  6245. jqXHR.statusCode( statusCode );
  6246. statusCode = undefined;
  6247. if ( fireGlobals ) {
  6248. globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
  6249. [ jqXHR, s, isSuccess ? success : error ] );
  6250. }
  6251. // Complete
  6252. completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
  6253. if ( fireGlobals ) {
  6254. globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
  6255. // Handle the global AJAX counter
  6256. if ( !( --jQuery.active ) ) {
  6257. jQuery.event.trigger("ajaxStop");
  6258. }
  6259. }
  6260. }
  6261. return jqXHR;
  6262. },
  6263. getJSON: function( url, data, callback ) {
  6264. return jQuery.get( url, data, callback, "json" );
  6265. },
  6266. getScript: function( url, callback ) {
  6267. return jQuery.get( url, undefined, callback, "script" );
  6268. }
  6269. });
  6270. jQuery.each( [ "get", "post" ], function( i, method ) {
  6271. jQuery[ method ] = function( url, data, callback, type ) {
  6272. // shift arguments if data argument was omitted
  6273. if ( jQuery.isFunction( data ) ) {
  6274. type = type || callback;
  6275. callback = data;
  6276. data = undefined;
  6277. }
  6278. return jQuery.ajax({
  6279. url: url,
  6280. type: method,
  6281. dataType: type,
  6282. data: data,
  6283. success: callback
  6284. });
  6285. };
  6286. });
  6287. /* Handles responses to an ajax request:
  6288. * - finds the right dataType (mediates between content-type and expected dataType)
  6289. * - returns the corresponding response
  6290. */
  6291. function ajaxHandleResponses( s, jqXHR, responses ) {
  6292. var ct, type, finalDataType, firstDataType,
  6293. contents = s.contents,
  6294. dataTypes = s.dataTypes;
  6295. // Remove auto dataType and get content-type in the process
  6296. while( dataTypes[ 0 ] === "*" ) {
  6297. dataTypes.shift();
  6298. if ( ct === undefined ) {
  6299. ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
  6300. }
  6301. }
  6302. // Check if we're dealing with a known content-type
  6303. if ( ct ) {
  6304. for ( type in contents ) {
  6305. if ( contents[ type ] && contents[ type ].test( ct ) ) {
  6306. dataTypes.unshift( type );
  6307. break;
  6308. }
  6309. }
  6310. }
  6311. // Check to see if we have a response for the expected dataType
  6312. if ( dataTypes[ 0 ] in responses ) {
  6313. finalDataType = dataTypes[ 0 ];
  6314. } else {
  6315. // Try convertible dataTypes
  6316. for ( type in responses ) {
  6317. if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) {
  6318. finalDataType = type;
  6319. break;
  6320. }
  6321. if ( !firstDataType ) {
  6322. firstDataType = type;
  6323. }
  6324. }
  6325. // Or just use first one
  6326. finalDataType = finalDataType || firstDataType;
  6327. }
  6328. // If we found a dataType
  6329. // We add the dataType to the list if needed
  6330. // and return the corresponding response
  6331. if ( finalDataType ) {
  6332. if ( finalDataType !== dataTypes[ 0 ] ) {
  6333. dataTypes.unshift( finalDataType );
  6334. }
  6335. return responses[ finalDataType ];
  6336. }
  6337. }
  6338. /* Chain conversions given the request and the original response
  6339. * Also sets the responseXXX fields on the jqXHR instance
  6340. */
  6341. function ajaxConvert( s, response, jqXHR, isSuccess ) {
  6342. var conv2, current, conv, tmp, prev,
  6343. converters = {},
  6344. // Work with a copy of dataTypes in case we need to modify it for conversion
  6345. dataTypes = s.dataTypes.slice();
  6346. // Create converters map with lowercased keys
  6347. if ( dataTypes[ 1 ] ) {
  6348. for ( conv in s.converters ) {
  6349. converters[ conv.toLowerCase() ] = s.converters[ conv ];
  6350. }
  6351. }
  6352. current = dataTypes.shift();
  6353. // Convert to each sequential dataType
  6354. while ( current ) {
  6355. if ( s.responseFields[ current ] ) {
  6356. jqXHR[ s.responseFields[ current ] ] = response;
  6357. }
  6358. // Apply the dataFilter if provided
  6359. if ( !prev && isSuccess && s.dataFilter ) {
  6360. response = s.dataFilter( response, s.dataType );
  6361. }
  6362. prev = current;
  6363. current = dataTypes.shift();
  6364. if ( current ) {
  6365. // There's only work to do if current dataType is non-auto
  6366. if ( current === "*" ) {
  6367. current = prev;
  6368. // Convert response if prev dataType is non-auto and differs from current
  6369. } else if ( prev !== "*" && prev !== current ) {
  6370. // Seek a direct converter
  6371. conv = converters[ prev + " " + current ] || converters[ "* " + current ];
  6372. // If none found, seek a pair
  6373. if ( !conv ) {
  6374. for ( conv2 in converters ) {
  6375. // If conv2 outputs current
  6376. tmp = conv2.split( " " );
  6377. if ( tmp[ 1 ] === current ) {
  6378. // If prev can be converted to accepted input
  6379. conv = converters[ prev + " " + tmp[ 0 ] ] ||
  6380. converters[ "* " + tmp[ 0 ] ];
  6381. if ( conv ) {
  6382. // Condense equivalence converters
  6383. if ( conv === true ) {
  6384. conv = converters[ conv2 ];
  6385. // Otherwise, insert the intermediate dataType
  6386. } else if ( converters[ conv2 ] !== true ) {
  6387. current = tmp[ 0 ];
  6388. dataTypes.unshift( tmp[ 1 ] );
  6389. }
  6390. break;
  6391. }
  6392. }
  6393. }
  6394. }
  6395. // Apply converter (if not an equivalence)
  6396. if ( conv !== true ) {
  6397. // Unless errors are allowed to bubble, catch and return them
  6398. if ( conv && s[ "throws" ] ) {
  6399. response = conv( response );
  6400. } else {
  6401. try {
  6402. response = conv( response );
  6403. } catch ( e ) {
  6404. return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current };
  6405. }
  6406. }
  6407. }
  6408. }
  6409. }
  6410. }
  6411. return { state: "success", data: response };
  6412. }
  6413. // Install script dataType
  6414. jQuery.ajaxSetup({
  6415. accepts: {
  6416. script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
  6417. },
  6418. contents: {
  6419. script: /(?:java|ecma)script/
  6420. },
  6421. converters: {
  6422. "text script": function( text ) {
  6423. jQuery.globalEval( text );
  6424. return text;
  6425. }
  6426. }
  6427. });
  6428. // Handle cache's special case and crossDomain
  6429. jQuery.ajaxPrefilter( "script", function( s ) {
  6430. if ( s.cache === undefined ) {
  6431. s.cache = false;
  6432. }
  6433. if ( s.crossDomain ) {
  6434. s.type = "GET";
  6435. }
  6436. });
  6437. // Bind script tag hack transport
  6438. jQuery.ajaxTransport( "script", function( s ) {
  6439. // This transport only deals with cross domain requests
  6440. if ( s.crossDomain ) {
  6441. var script, callback;
  6442. return {
  6443. send: function( _, complete ) {
  6444. script = jQuery("<script>").prop({
  6445. async: true,
  6446. charset: s.scriptCharset,
  6447. src: s.url
  6448. }).on(
  6449. "load error",
  6450. callback = function( evt ) {
  6451. script.remove();
  6452. callback = null;
  6453. if ( evt ) {
  6454. complete( evt.type === "error" ? 404 : 200, evt.type );
  6455. }
  6456. }
  6457. );
  6458. document.head.appendChild( script[ 0 ] );
  6459. },
  6460. abort: function() {
  6461. if ( callback ) {
  6462. callback();
  6463. }
  6464. }
  6465. };
  6466. }
  6467. });
  6468. var oldCallbacks = [],
  6469. rjsonp = /(=)\?(?=&|$)|\?\?/;
  6470. // Default jsonp settings
  6471. jQuery.ajaxSetup({
  6472. jsonp: "callback",
  6473. jsonpCallback: function() {
  6474. var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_nonce++ ) );
  6475. this[ callback ] = true;
  6476. return callback;
  6477. }
  6478. });
  6479. // Detect, normalize options and install callbacks for jsonp requests
  6480. jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
  6481. var callbackName, overwritten, responseContainer,
  6482. jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
  6483. "url" :
  6484. typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
  6485. );
  6486. // Handle iff the expected data type is "jsonp" or we have a parameter to set
  6487. if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
  6488. // Get callback name, remembering preexisting value associated with it
  6489. callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
  6490. s.jsonpCallback() :
  6491. s.jsonpCallback;
  6492. // Insert callback into url or form data
  6493. if ( jsonProp ) {
  6494. s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
  6495. } else if ( s.jsonp !== false ) {
  6496. s.url += ( ajax_rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
  6497. }
  6498. // Use data converter to retrieve json after script execution
  6499. s.converters["script json"] = function() {
  6500. if ( !responseContainer ) {
  6501. jQuery.error( callbackName + " was not called" );
  6502. }
  6503. return responseContainer[ 0 ];
  6504. };
  6505. // force json dataType
  6506. s.dataTypes[ 0 ] = "json";
  6507. // Install callback
  6508. overwritten = window[ callbackName ];
  6509. window[ callbackName ] = function() {
  6510. responseContainer = arguments;
  6511. };
  6512. // Clean-up function (fires after converters)
  6513. jqXHR.always(function() {
  6514. // Restore preexisting value
  6515. window[ callbackName ] = overwritten;
  6516. // Save back as free
  6517. if ( s[ callbackName ] ) {
  6518. // make sure that re-using the options doesn't screw things around
  6519. s.jsonpCallback = originalSettings.jsonpCallback;
  6520. // save the callback name for future use
  6521. oldCallbacks.push( callbackName );
  6522. }
  6523. // Call if it was a function and we have a response
  6524. if ( responseContainer && jQuery.isFunction( overwritten ) ) {
  6525. overwritten( responseContainer[ 0 ] );
  6526. }
  6527. responseContainer = overwritten = undefined;
  6528. });
  6529. // Delegate to script
  6530. return "script";
  6531. }
  6532. });
  6533. jQuery.ajaxSettings.xhr = function() {
  6534. try {
  6535. return new XMLHttpRequest();
  6536. } catch( e ) {}
  6537. };
  6538. var xhrSupported = jQuery.ajaxSettings.xhr(),
  6539. xhrSuccessStatus = {
  6540. // file protocol always yields status code 0, assume 200
  6541. 0: 200,
  6542. // Support: IE9
  6543. // #1450: sometimes IE returns 1223 when it should be 204
  6544. 1223: 204
  6545. },
  6546. // Support: IE9
  6547. // We need to keep track of outbound xhr and abort them manually
  6548. // because IE is not smart enough to do it all by itself
  6549. xhrId = 0,
  6550. xhrCallbacks = {};
  6551. if ( window.ActiveXObject ) {
  6552. jQuery( window ).on( "unload", function() {
  6553. for( var key in xhrCallbacks ) {
  6554. xhrCallbacks[ key ]();
  6555. }
  6556. xhrCallbacks = undefined;
  6557. });
  6558. }
  6559. jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
  6560. jQuery.support.ajax = xhrSupported = !!xhrSupported;
  6561. jQuery.ajaxTransport(function( options ) {
  6562. var callback;
  6563. // Cross domain only allowed if supported through XMLHttpRequest
  6564. if ( jQuery.support.cors || xhrSupported && !options.crossDomain ) {
  6565. return {
  6566. send: function( headers, complete ) {
  6567. var i, id,
  6568. xhr = options.xhr();
  6569. xhr.open( options.type, options.url, options.async, options.username, options.password );
  6570. // Apply custom fields if provided
  6571. if ( options.xhrFields ) {
  6572. for ( i in options.xhrFields ) {
  6573. xhr[ i ] = options.xhrFields[ i ];
  6574. }
  6575. }
  6576. // Override mime type if needed
  6577. if ( options.mimeType && xhr.overrideMimeType ) {
  6578. xhr.overrideMimeType( options.mimeType );
  6579. }
  6580. // X-Requested-With header
  6581. // For cross-domain requests, seeing as conditions for a preflight are
  6582. // akin to a jigsaw puzzle, we simply never set it to be sure.
  6583. // (it can always be set on a per-request basis or even using ajaxSetup)
  6584. // For same-domain requests, won't change header if already provided.
  6585. if ( !options.crossDomain && !headers["X-Requested-With"] ) {
  6586. headers["X-Requested-With"] = "XMLHttpRequest";
  6587. }
  6588. // Set headers
  6589. for ( i in headers ) {
  6590. xhr.setRequestHeader( i, headers[ i ] );
  6591. }
  6592. // Callback
  6593. callback = function( type ) {
  6594. return function() {
  6595. if ( callback ) {
  6596. delete xhrCallbacks[ id ];
  6597. callback = xhr.onload = xhr.onerror = null;
  6598. if ( type === "abort" ) {
  6599. xhr.abort();
  6600. } else if ( type === "error" ) {
  6601. complete(
  6602. // file protocol always yields status 0, assume 404
  6603. xhr.status || 404,
  6604. xhr.statusText
  6605. );
  6606. } else {
  6607. complete(
  6608. xhrSuccessStatus[ xhr.status ] || xhr.status,
  6609. xhr.statusText,
  6610. // Support: IE9
  6611. // #11426: When requesting binary data, IE9 will throw an exception
  6612. // on any attempt to access responseText
  6613. typeof xhr.responseText === "string" ? {
  6614. text: xhr.responseText
  6615. } : undefined,
  6616. xhr.getAllResponseHeaders()
  6617. );
  6618. }
  6619. }
  6620. };
  6621. };
  6622. // Listen to events
  6623. xhr.onload = callback();
  6624. xhr.onerror = callback("error");
  6625. // Create the abort callback
  6626. callback = xhrCallbacks[( id = xhrId++ )] = callback("abort");
  6627. // Do send the request
  6628. // This may raise an exception which is actually
  6629. // handled in jQuery.ajax (so no try/catch here)
  6630. xhr.send( options.hasContent && options.data || null );
  6631. },
  6632. abort: function() {
  6633. if ( callback ) {
  6634. callback();
  6635. }
  6636. }
  6637. };
  6638. }
  6639. });
  6640. var fxNow, timerId,
  6641. rfxtypes = /^(?:toggle|show|hide)$/,
  6642. rfxnum = new RegExp( "^(?:([+-])=|)(" + core_pnum + ")([a-z%]*)$", "i" ),
  6643. rrun = /queueHooks$/,
  6644. animationPrefilters = [ defaultPrefilter ],
  6645. tweeners = {
  6646. "*": [function( prop, value ) {
  6647. var tween = this.createTween( prop, value ),
  6648. target = tween.cur(),
  6649. parts = rfxnum.exec( value ),
  6650. unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
  6651. // Starting value computation is required for potential unit mismatches
  6652. start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) &&
  6653. rfxnum.exec( jQuery.css( tween.elem, prop ) ),
  6654. scale = 1,
  6655. maxIterations = 20;
  6656. if ( start && start[ 3 ] !== unit ) {
  6657. // Trust units reported by jQuery.css
  6658. unit = unit || start[ 3 ];
  6659. // Make sure we update the tween properties later on
  6660. parts = parts || [];
  6661. // Iteratively approximate from a nonzero starting point
  6662. start = +target || 1;
  6663. do {
  6664. // If previous iteration zeroed out, double until we get *something*
  6665. // Use a string for doubling factor so we don't accidentally see scale as unchanged below
  6666. scale = scale || ".5";
  6667. // Adjust and apply
  6668. start = start / scale;
  6669. jQuery.style( tween.elem, prop, start + unit );
  6670. // Update scale, tolerating zero or NaN from tween.cur()
  6671. // And breaking the loop if scale is unchanged or perfect, or if we've just had enough
  6672. } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );
  6673. }
  6674. // Update tween properties
  6675. if ( parts ) {
  6676. start = tween.start = +start || +target || 0;
  6677. tween.unit = unit;
  6678. // If a +=/-= token was provided, we're doing a relative animation
  6679. tween.end = parts[ 1 ] ?
  6680. start + ( parts[ 1 ] + 1 ) * parts[ 2 ] :
  6681. +parts[ 2 ];
  6682. }
  6683. return tween;
  6684. }]
  6685. };
  6686. // Animations created synchronously will run synchronously
  6687. function createFxNow() {
  6688. setTimeout(function() {
  6689. fxNow = undefined;
  6690. });
  6691. return ( fxNow = jQuery.now() );
  6692. }
  6693. function createTween( value, prop, animation ) {
  6694. var tween,
  6695. collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ),
  6696. index = 0,
  6697. length = collection.length;
  6698. for ( ; index < length; index++ ) {
  6699. if ( (tween = collection[ index ].call( animation, prop, value )) ) {
  6700. // we're done with this property
  6701. return tween;
  6702. }
  6703. }
  6704. }
  6705. function Animation( elem, properties, options ) {
  6706. var result,
  6707. stopped,
  6708. index = 0,
  6709. length = animationPrefilters.length,
  6710. deferred = jQuery.Deferred().always( function() {
  6711. // don't match elem in the :animated selector
  6712. delete tick.elem;
  6713. }),
  6714. tick = function() {
  6715. if ( stopped ) {
  6716. return false;
  6717. }
  6718. var currentTime = fxNow || createFxNow(),
  6719. remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
  6720. // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)
  6721. temp = remaining / animation.duration || 0,
  6722. percent = 1 - temp,
  6723. index = 0,
  6724. length = animation.tweens.length;
  6725. for ( ; index < length ; index++ ) {
  6726. animation.tweens[ index ].run( percent );
  6727. }
  6728. deferred.notifyWith( elem, [ animation, percent, remaining ]);
  6729. if ( percent < 1 && length ) {
  6730. return remaining;
  6731. } else {
  6732. deferred.resolveWith( elem, [ animation ] );
  6733. return false;
  6734. }
  6735. },
  6736. animation = deferred.promise({
  6737. elem: elem,
  6738. props: jQuery.extend( {}, properties ),
  6739. opts: jQuery.extend( true, { specialEasing: {} }, options ),
  6740. originalProperties: properties,
  6741. originalOptions: options,
  6742. startTime: fxNow || createFxNow(),
  6743. duration: options.duration,
  6744. tweens: [],
  6745. createTween: function( prop, end ) {
  6746. var tween = jQuery.Tween( elem, animation.opts, prop, end,
  6747. animation.opts.specialEasing[ prop ] || animation.opts.easing );
  6748. animation.tweens.push( tween );
  6749. return tween;
  6750. },
  6751. stop: function( gotoEnd ) {
  6752. var index = 0,
  6753. // if we are going to the end, we want to run all the tweens
  6754. // otherwise we skip this part
  6755. length = gotoEnd ? animation.tweens.length : 0;
  6756. if ( stopped ) {
  6757. return this;
  6758. }
  6759. stopped = true;
  6760. for ( ; index < length ; index++ ) {
  6761. animation.tweens[ index ].run( 1 );
  6762. }
  6763. // resolve when we played the last frame
  6764. // otherwise, reject
  6765. if ( gotoEnd ) {
  6766. deferred.resolveWith( elem, [ animation, gotoEnd ] );
  6767. } else {
  6768. deferred.rejectWith( elem, [ animation, gotoEnd ] );
  6769. }
  6770. return this;
  6771. }
  6772. }),
  6773. props = animation.props;
  6774. propFilter( props, animation.opts.specialEasing );
  6775. for ( ; index < length ; index++ ) {
  6776. result = animationPrefilters[ index ].call( animation, elem, props, animation.opts );
  6777. if ( result ) {
  6778. return result;
  6779. }
  6780. }
  6781. jQuery.map( props, createTween, animation );
  6782. if ( jQuery.isFunction( animation.opts.start ) ) {
  6783. animation.opts.start.call( elem, animation );
  6784. }
  6785. jQuery.fx.timer(
  6786. jQuery.extend( tick, {
  6787. elem: elem,
  6788. anim: animation,
  6789. queue: animation.opts.queue
  6790. })
  6791. );
  6792. // attach callbacks from options
  6793. return animation.progress( animation.opts.progress )
  6794. .done( animation.opts.done, animation.opts.complete )
  6795. .fail( animation.opts.fail )
  6796. .always( animation.opts.always );
  6797. }
  6798. function propFilter( props, specialEasing ) {
  6799. var index, name, easing, value, hooks;
  6800. // camelCase, specialEasing and expand cssHook pass
  6801. for ( index in props ) {
  6802. name = jQuery.camelCase( index );
  6803. easing = specialEasing[ name ];
  6804. value = props[ index ];
  6805. if ( jQuery.isArray( value ) ) {
  6806. easing = value[ 1 ];
  6807. value = props[ index ] = value[ 0 ];
  6808. }
  6809. if ( index !== name ) {
  6810. props[ name ] = value;
  6811. delete props[ index ];
  6812. }
  6813. hooks = jQuery.cssHooks[ name ];
  6814. if ( hooks && "expand" in hooks ) {
  6815. value = hooks.expand( value );
  6816. delete props[ name ];
  6817. // not quite $.extend, this wont overwrite keys already present.
  6818. // also - reusing 'index' from above because we have the correct "name"
  6819. for ( index in value ) {
  6820. if ( !( index in props ) ) {
  6821. props[ index ] = value[ index ];
  6822. specialEasing[ index ] = easing;
  6823. }
  6824. }
  6825. } else {
  6826. specialEasing[ name ] = easing;
  6827. }
  6828. }
  6829. }
  6830. jQuery.Animation = jQuery.extend( Animation, {
  6831. tweener: function( props, callback ) {
  6832. if ( jQuery.isFunction( props ) ) {
  6833. callback = props;
  6834. props = [ "*" ];
  6835. } else {
  6836. props = props.split(" ");
  6837. }
  6838. var prop,
  6839. index = 0,
  6840. length = props.length;
  6841. for ( ; index < length ; index++ ) {
  6842. prop = props[ index ];
  6843. tweeners[ prop ] = tweeners[ prop ] || [];
  6844. tweeners[ prop ].unshift( callback );
  6845. }
  6846. },
  6847. prefilter: function( callback, prepend ) {
  6848. if ( prepend ) {
  6849. animationPrefilters.unshift( callback );
  6850. } else {
  6851. animationPrefilters.push( callback );
  6852. }
  6853. }
  6854. });
  6855. function defaultPrefilter( elem, props, opts ) {
  6856. /* jshint validthis: true */
  6857. var prop, value, toggle, tween, hooks, oldfire,
  6858. anim = this,
  6859. orig = {},
  6860. style = elem.style,
  6861. hidden = elem.nodeType && isHidden( elem ),
  6862. dataShow = data_priv.get( elem, "fxshow" );
  6863. // handle queue: false promises
  6864. if ( !opts.queue ) {
  6865. hooks = jQuery._queueHooks( elem, "fx" );
  6866. if ( hooks.unqueued == null ) {
  6867. hooks.unqueued = 0;
  6868. oldfire = hooks.empty.fire;
  6869. hooks.empty.fire = function() {
  6870. if ( !hooks.unqueued ) {
  6871. oldfire();
  6872. }
  6873. };
  6874. }
  6875. hooks.unqueued++;
  6876. anim.always(function() {
  6877. // doing this makes sure that the complete handler will be called
  6878. // before this completes
  6879. anim.always(function() {
  6880. hooks.unqueued--;
  6881. if ( !jQuery.queue( elem, "fx" ).length ) {
  6882. hooks.empty.fire();
  6883. }
  6884. });
  6885. });
  6886. }
  6887. // height/width overflow pass
  6888. if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) {
  6889. // Make sure that nothing sneaks out
  6890. // Record all 3 overflow attributes because IE9-10 do not
  6891. // change the overflow attribute when overflowX and
  6892. // overflowY are set to the same value
  6893. opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
  6894. // Set display property to inline-block for height/width
  6895. // animations on inline elements that are having width/height animated
  6896. if ( jQuery.css( elem, "display" ) === "inline" &&
  6897. jQuery.css( elem, "float" ) === "none" ) {
  6898. style.display = "inline-block";
  6899. }
  6900. }
  6901. if ( opts.overflow ) {
  6902. style.overflow = "hidden";
  6903. anim.always(function() {
  6904. style.overflow = opts.overflow[ 0 ];
  6905. style.overflowX = opts.overflow[ 1 ];
  6906. style.overflowY = opts.overflow[ 2 ];
  6907. });
  6908. }
  6909. // show/hide pass
  6910. for ( prop in props ) {
  6911. value = props[ prop ];
  6912. if ( rfxtypes.exec( value ) ) {
  6913. delete props[ prop ];
  6914. toggle = toggle || value === "toggle";
  6915. if ( value === ( hidden ? "hide" : "show" ) ) {
  6916. // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden
  6917. if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
  6918. hidden = true;
  6919. } else {
  6920. continue;
  6921. }
  6922. }
  6923. orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
  6924. }
  6925. }
  6926. if ( !jQuery.isEmptyObject( orig ) ) {
  6927. if ( dataShow ) {
  6928. if ( "hidden" in dataShow ) {
  6929. hidden = dataShow.hidden;
  6930. }
  6931. } else {
  6932. dataShow = data_priv.access( elem, "fxshow", {} );
  6933. }
  6934. // store state if its toggle - enables .stop().toggle() to "reverse"
  6935. if ( toggle ) {
  6936. dataShow.hidden = !hidden;
  6937. }
  6938. if ( hidden ) {
  6939. jQuery( elem ).show();
  6940. } else {
  6941. anim.done(function() {
  6942. jQuery( elem ).hide();
  6943. });
  6944. }
  6945. anim.done(function() {
  6946. var prop;
  6947. data_priv.remove( elem, "fxshow" );
  6948. for ( prop in orig ) {
  6949. jQuery.style( elem, prop, orig[ prop ] );
  6950. }
  6951. });
  6952. for ( prop in orig ) {
  6953. tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
  6954. if ( !( prop in dataShow ) ) {
  6955. dataShow[ prop ] = tween.start;
  6956. if ( hidden ) {
  6957. tween.end = tween.start;
  6958. tween.start = prop === "width" || prop === "height" ? 1 : 0;
  6959. }
  6960. }
  6961. }
  6962. }
  6963. }
  6964. function Tween( elem, options, prop, end, easing ) {
  6965. return new Tween.prototype.init( elem, options, prop, end, easing );
  6966. }
  6967. jQuery.Tween = Tween;
  6968. Tween.prototype = {
  6969. constructor: Tween,
  6970. init: function( elem, options, prop, end, easing, unit ) {
  6971. this.elem = elem;
  6972. this.prop = prop;
  6973. this.easing = easing || "swing";
  6974. this.options = options;
  6975. this.start = this.now = this.cur();
  6976. this.end = end;
  6977. this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
  6978. },
  6979. cur: function() {
  6980. var hooks = Tween.propHooks[ this.prop ];
  6981. return hooks && hooks.get ?
  6982. hooks.get( this ) :
  6983. Tween.propHooks._default.get( this );
  6984. },
  6985. run: function( percent ) {
  6986. var eased,
  6987. hooks = Tween.propHooks[ this.prop ];
  6988. if ( this.options.duration ) {
  6989. this.pos = eased = jQuery.easing[ this.easing ](
  6990. percent, this.options.duration * percent, 0, 1, this.options.duration
  6991. );
  6992. } else {
  6993. this.pos = eased = percent;
  6994. }
  6995. this.now = ( this.end - this.start ) * eased + this.start;
  6996. if ( this.options.step ) {
  6997. this.options.step.call( this.elem, this.now, this );
  6998. }
  6999. if ( hooks && hooks.set ) {
  7000. hooks.set( this );
  7001. } else {
  7002. Tween.propHooks._default.set( this );
  7003. }
  7004. return this;
  7005. }
  7006. };
  7007. Tween.prototype.init.prototype = Tween.prototype;
  7008. Tween.propHooks = {
  7009. _default: {
  7010. get: function( tween ) {
  7011. var result;
  7012. if ( tween.elem[ tween.prop ] != null &&
  7013. (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {
  7014. return tween.elem[ tween.prop ];
  7015. }
  7016. // passing an empty string as a 3rd parameter to .css will automatically
  7017. // attempt a parseFloat and fallback to a string if the parse fails
  7018. // so, simple values such as "10px" are parsed to Float.
  7019. // complex values such as "rotate(1rad)" are returned as is.
  7020. result = jQuery.css( tween.elem, tween.prop, "" );
  7021. // Empty strings, null, undefined and "auto" are converted to 0.
  7022. return !result || result === "auto" ? 0 : result;
  7023. },
  7024. set: function( tween ) {
  7025. // use step hook for back compat - use cssHook if its there - use .style if its
  7026. // available and use plain properties where available
  7027. if ( jQuery.fx.step[ tween.prop ] ) {
  7028. jQuery.fx.step[ tween.prop ]( tween );
  7029. } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {
  7030. jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
  7031. } else {
  7032. tween.elem[ tween.prop ] = tween.now;
  7033. }
  7034. }
  7035. }
  7036. };
  7037. // Support: IE9
  7038. // Panic based approach to setting things on disconnected nodes
  7039. Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
  7040. set: function( tween ) {
  7041. if ( tween.elem.nodeType && tween.elem.parentNode ) {
  7042. tween.elem[ tween.prop ] = tween.now;
  7043. }
  7044. }
  7045. };
  7046. jQuery.each([ "toggle", "show", "hide" ], function( i, name ) {
  7047. var cssFn = jQuery.fn[ name ];
  7048. jQuery.fn[ name ] = function( speed, easing, callback ) {
  7049. return speed == null || typeof speed === "boolean" ?
  7050. cssFn.apply( this, arguments ) :
  7051. this.animate( genFx( name, true ), speed, easing, callback );
  7052. };
  7053. });
  7054. jQuery.fn.extend({
  7055. fadeTo: function( speed, to, easing, callback ) {
  7056. // show any hidden elements after setting opacity to 0
  7057. return this.filter( isHidden ).css( "opacity", 0 ).show()
  7058. // animate to the value specified
  7059. .end().animate({ opacity: to }, speed, easing, callback );
  7060. },
  7061. animate: function( prop, speed, easing, callback ) {
  7062. var empty = jQuery.isEmptyObject( prop ),
  7063. optall = jQuery.speed( speed, easing, callback ),
  7064. doAnimation = function() {
  7065. // Operate on a copy of prop so per-property easing won't be lost
  7066. var anim = Animation( this, jQuery.extend( {}, prop ), optall );
  7067. // Empty animations, or finishing resolves immediately
  7068. if ( empty || data_priv.get( this, "finish" ) ) {
  7069. anim.stop( true );
  7070. }
  7071. };
  7072. doAnimation.finish = doAnimation;
  7073. return empty || optall.queue === false ?
  7074. this.each( doAnimation ) :
  7075. this.queue( optall.queue, doAnimation );
  7076. },
  7077. stop: function( type, clearQueue, gotoEnd ) {
  7078. var stopQueue = function( hooks ) {
  7079. var stop = hooks.stop;
  7080. delete hooks.stop;
  7081. stop( gotoEnd );
  7082. };
  7083. if ( typeof type !== "string" ) {
  7084. gotoEnd = clearQueue;
  7085. clearQueue = type;
  7086. type = undefined;
  7087. }
  7088. if ( clearQueue && type !== false ) {
  7089. this.queue( type || "fx", [] );
  7090. }
  7091. return this.each(function() {
  7092. var dequeue = true,
  7093. index = type != null && type + "queueHooks",
  7094. timers = jQuery.timers,
  7095. data = data_priv.get( this );
  7096. if ( index ) {
  7097. if ( data[ index ] && data[ index ].stop ) {
  7098. stopQueue( data[ index ] );
  7099. }
  7100. } else {
  7101. for ( index in data ) {
  7102. if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
  7103. stopQueue( data[ index ] );
  7104. }
  7105. }
  7106. }
  7107. for ( index = timers.length; index--; ) {
  7108. if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {
  7109. timers[ index ].anim.stop( gotoEnd );
  7110. dequeue = false;
  7111. timers.splice( index, 1 );
  7112. }
  7113. }
  7114. // start the next in the queue if the last step wasn't forced
  7115. // timers currently will call their complete callbacks, which will dequeue
  7116. // but only if they were gotoEnd
  7117. if ( dequeue || !gotoEnd ) {
  7118. jQuery.dequeue( this, type );
  7119. }
  7120. });
  7121. },
  7122. finish: function( type ) {
  7123. if ( type !== false ) {
  7124. type = type || "fx";
  7125. }
  7126. return this.each(function() {
  7127. var index,
  7128. data = data_priv.get( this ),
  7129. queue = data[ type + "queue" ],
  7130. hooks = data[ type + "queueHooks" ],
  7131. timers = jQuery.timers,
  7132. length = queue ? queue.length : 0;
  7133. // enable finishing flag on private data
  7134. data.finish = true;
  7135. // empty the queue first
  7136. jQuery.queue( this, type, [] );
  7137. if ( hooks && hooks.stop ) {
  7138. hooks.stop.call( this, true );
  7139. }
  7140. // look for any active animations, and finish them
  7141. for ( index = timers.length; index--; ) {
  7142. if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
  7143. timers[ index ].anim.stop( true );
  7144. timers.splice( index, 1 );
  7145. }
  7146. }
  7147. // look for any animations in the old queue and finish them
  7148. for ( index = 0; index < length; index++ ) {
  7149. if ( queue[ index ] && queue[ index ].finish ) {
  7150. queue[ index ].finish.call( this );
  7151. }
  7152. }
  7153. // turn off finishing flag
  7154. delete data.finish;
  7155. });
  7156. }
  7157. });
  7158. // Generate parameters to create a standard animation
  7159. function genFx( type, includeWidth ) {
  7160. var which,
  7161. attrs = { height: type },
  7162. i = 0;
  7163. // if we include width, step value is 1 to do all cssExpand values,
  7164. // if we don't include width, step value is 2 to skip over Left and Right
  7165. includeWidth = includeWidth? 1 : 0;
  7166. for( ; i < 4 ; i += 2 - includeWidth ) {
  7167. which = cssExpand[ i ];
  7168. attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
  7169. }
  7170. if ( includeWidth ) {
  7171. attrs.opacity = attrs.width = type;
  7172. }
  7173. return attrs;
  7174. }
  7175. // Generate shortcuts for custom animations
  7176. jQuery.each({
  7177. slideDown: genFx("show"),
  7178. slideUp: genFx("hide"),
  7179. slideToggle: genFx("toggle"),
  7180. fadeIn: { opacity: "show" },
  7181. fadeOut: { opacity: "hide" },
  7182. fadeToggle: { opacity: "toggle" }
  7183. }, function( name, props ) {
  7184. jQuery.fn[ name ] = function( speed, easing, callback ) {
  7185. return this.animate( props, speed, easing, callback );
  7186. };
  7187. });
  7188. jQuery.speed = function( speed, easing, fn ) {
  7189. var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
  7190. complete: fn || !fn && easing ||
  7191. jQuery.isFunction( speed ) && speed,
  7192. duration: speed,
  7193. easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
  7194. };
  7195. opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :
  7196. opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;
  7197. // normalize opt.queue - true/undefined/null -> "fx"
  7198. if ( opt.queue == null || opt.queue === true ) {
  7199. opt.queue = "fx";
  7200. }
  7201. // Queueing
  7202. opt.old = opt.complete;
  7203. opt.complete = function() {
  7204. if ( jQuery.isFunction( opt.old ) ) {
  7205. opt.old.call( this );
  7206. }
  7207. if ( opt.queue ) {
  7208. jQuery.dequeue( this, opt.queue );
  7209. }
  7210. };
  7211. return opt;
  7212. };
  7213. jQuery.easing = {
  7214. linear: function( p ) {
  7215. return p;
  7216. },
  7217. swing: function( p ) {
  7218. return 0.5 - Math.cos( p*Math.PI ) / 2;
  7219. }
  7220. };
  7221. jQuery.timers = [];
  7222. jQuery.fx = Tween.prototype.init;
  7223. jQuery.fx.tick = function() {
  7224. var timer,
  7225. timers = jQuery.timers,
  7226. i = 0;
  7227. fxNow = jQuery.now();
  7228. for ( ; i < timers.length; i++ ) {
  7229. timer = timers[ i ];
  7230. // Checks the timer has not already been removed
  7231. if ( !timer() && timers[ i ] === timer ) {
  7232. timers.splice( i--, 1 );
  7233. }
  7234. }
  7235. if ( !timers.length ) {
  7236. jQuery.fx.stop();
  7237. }
  7238. fxNow = undefined;
  7239. };
  7240. jQuery.fx.timer = function( timer ) {
  7241. if ( timer() && jQuery.timers.push( timer ) ) {
  7242. jQuery.fx.start();
  7243. }
  7244. };
  7245. jQuery.fx.interval = 13;
  7246. jQuery.fx.start = function() {
  7247. if ( !timerId ) {
  7248. timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
  7249. }
  7250. };
  7251. jQuery.fx.stop = function() {
  7252. clearInterval( timerId );
  7253. timerId = null;
  7254. };
  7255. jQuery.fx.speeds = {
  7256. slow: 600,
  7257. fast: 200,
  7258. // Default speed
  7259. _default: 400
  7260. };
  7261. // Back Compat <1.8 extension point
  7262. jQuery.fx.step = {};
  7263. if ( jQuery.expr && jQuery.expr.filters ) {
  7264. jQuery.expr.filters.animated = function( elem ) {
  7265. return jQuery.grep(jQuery.timers, function( fn ) {
  7266. return elem === fn.elem;
  7267. }).length;
  7268. };
  7269. }
  7270. jQuery.fn.offset = function( options ) {
  7271. if ( arguments.length ) {
  7272. return options === undefined ?
  7273. this :
  7274. this.each(function( i ) {
  7275. jQuery.offset.setOffset( this, options, i );
  7276. });
  7277. }
  7278. var docElem, win,
  7279. elem = this[ 0 ],
  7280. box = { top: 0, left: 0 },
  7281. doc = elem && elem.ownerDocument;
  7282. if ( !doc ) {
  7283. return;
  7284. }
  7285. docElem = doc.documentElement;
  7286. // Make sure it's not a disconnected DOM node
  7287. if ( !jQuery.contains( docElem, elem ) ) {
  7288. return box;
  7289. }
  7290. // If we don't have gBCR, just use 0,0 rather than error
  7291. // BlackBerry 5, iOS 3 (original iPhone)
  7292. if ( typeof elem.getBoundingClientRect !== core_strundefined ) {
  7293. box = elem.getBoundingClientRect();
  7294. }
  7295. win = getWindow( doc );
  7296. return {
  7297. top: box.top + win.pageYOffset - docElem.clientTop,
  7298. left: box.left + win.pageXOffset - docElem.clientLeft
  7299. };
  7300. };
  7301. jQuery.offset = {
  7302. setOffset: function( elem, options, i ) {
  7303. var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
  7304. position = jQuery.css( elem, "position" ),
  7305. curElem = jQuery( elem ),
  7306. props = {};
  7307. // Set position first, in-case top/left are set even on static elem
  7308. if ( position === "static" ) {
  7309. elem.style.position = "relative";
  7310. }
  7311. curOffset = curElem.offset();
  7312. curCSSTop = jQuery.css( elem, "top" );
  7313. curCSSLeft = jQuery.css( elem, "left" );
  7314. calculatePosition = ( position === "absolute" || position === "fixed" ) && ( curCSSTop + curCSSLeft ).indexOf("auto") > -1;
  7315. // Need to be able to calculate position if either top or left is auto and position is either absolute or fixed
  7316. if ( calculatePosition ) {
  7317. curPosition = curElem.position();
  7318. curTop = curPosition.top;
  7319. curLeft = curPosition.left;
  7320. } else {
  7321. curTop = parseFloat( curCSSTop ) || 0;
  7322. curLeft = parseFloat( curCSSLeft ) || 0;
  7323. }
  7324. if ( jQuery.isFunction( options ) ) {
  7325. options = options.call( elem, i, curOffset );
  7326. }
  7327. if ( options.top != null ) {
  7328. props.top = ( options.top - curOffset.top ) + curTop;
  7329. }
  7330. if ( options.left != null ) {
  7331. props.left = ( options.left - curOffset.left ) + curLeft;
  7332. }
  7333. if ( "using" in options ) {
  7334. options.using.call( elem, props );
  7335. } else {
  7336. curElem.css( props );
  7337. }
  7338. }
  7339. };
  7340. jQuery.fn.extend({
  7341. position: function() {
  7342. if ( !this[ 0 ] ) {
  7343. return;
  7344. }
  7345. var offsetParent, offset,
  7346. elem = this[ 0 ],
  7347. parentOffset = { top: 0, left: 0 };
  7348. // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
  7349. if ( jQuery.css( elem, "position" ) === "fixed" ) {
  7350. // We assume that getBoundingClientRect is available when computed position is fixed
  7351. offset = elem.getBoundingClientRect();
  7352. } else {
  7353. // Get *real* offsetParent
  7354. offsetParent = this.offsetParent();
  7355. // Get correct offsets
  7356. offset = this.offset();
  7357. if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
  7358. parentOffset = offsetParent.offset();
  7359. }
  7360. // Add offsetParent borders
  7361. parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
  7362. parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
  7363. }
  7364. // Subtract parent offsets and element margins
  7365. return {
  7366. top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
  7367. left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
  7368. };
  7369. },
  7370. offsetParent: function() {
  7371. return this.map(function() {
  7372. var offsetParent = this.offsetParent || docElem;
  7373. while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
  7374. offsetParent = offsetParent.offsetParent;
  7375. }
  7376. return offsetParent || docElem;
  7377. });
  7378. }
  7379. });
  7380. // Create scrollLeft and scrollTop methods
  7381. jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) {
  7382. var top = "pageYOffset" === prop;
  7383. jQuery.fn[ method ] = function( val ) {
  7384. return jQuery.access( this, function( elem, method, val ) {
  7385. var win = getWindow( elem );
  7386. if ( val === undefined ) {
  7387. return win ? win[ prop ] : elem[ method ];
  7388. }
  7389. if ( win ) {
  7390. win.scrollTo(
  7391. !top ? val : window.pageXOffset,
  7392. top ? val : window.pageYOffset
  7393. );
  7394. } else {
  7395. elem[ method ] = val;
  7396. }
  7397. }, method, val, arguments.length, null );
  7398. };
  7399. });
  7400. function getWindow( elem ) {
  7401. return jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
  7402. }
  7403. // Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
  7404. jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
  7405. jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) {
  7406. // margin is only for outerHeight, outerWidth
  7407. jQuery.fn[ funcName ] = function( margin, value ) {
  7408. var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
  7409. extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" );
  7410. return jQuery.access( this, function( elem, type, value ) {
  7411. var doc;
  7412. if ( jQuery.isWindow( elem ) ) {
  7413. // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
  7414. // isn't a whole lot we can do. See pull request at this URL for discussion:
  7415. // https://github.com/jquery/jquery/pull/764
  7416. return elem.document.documentElement[ "client" + name ];
  7417. }
  7418. // Get document width or height
  7419. if ( elem.nodeType === 9 ) {
  7420. doc = elem.documentElement;
  7421. // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
  7422. // whichever is greatest
  7423. return Math.max(
  7424. elem.body[ "scroll" + name ], doc[ "scroll" + name ],
  7425. elem.body[ "offset" + name ], doc[ "offset" + name ],
  7426. doc[ "client" + name ]
  7427. );
  7428. }
  7429. return value === undefined ?
  7430. // Get width or height on the element, requesting but not forcing parseFloat
  7431. jQuery.css( elem, type, extra ) :
  7432. // Set width or height on the element
  7433. jQuery.style( elem, type, value, extra );
  7434. }, type, chainable ? margin : undefined, chainable, null );
  7435. };
  7436. });
  7437. });
  7438. // Limit scope pollution from any deprecated API
  7439. // (function() {
  7440. // The number of elements contained in the matched element set
  7441. jQuery.fn.size = function() {
  7442. return this.length;
  7443. };
  7444. jQuery.fn.andSelf = jQuery.fn.addBack;
  7445. // })();
  7446. if ( typeof module === "object" && module && typeof module.exports === "object" ) {
  7447. // Expose jQuery as module.exports in loaders that implement the Node
  7448. // module pattern (including browserify). Do not create the global, since
  7449. // the user will be storing it themselves locally, and globals are frowned
  7450. // upon in the Node module world.
  7451. module.exports = jQuery;
  7452. } else {
  7453. // Register as a named AMD module, since jQuery can be concatenated with other
  7454. // files that may use define, but not via a proper concatenation script that
  7455. // understands anonymous AMD modules. A named AMD is safest and most robust
  7456. // way to register. Lowercase jquery is used because AMD module names are
  7457. // derived from file names, and jQuery is normally delivered in a lowercase
  7458. // file name. Do this after creating the global so that if an AMD module wants
  7459. // to call noConflict to hide this version of jQuery, it will work.
  7460. if ( typeof define === "function" && define.amd ) {
  7461. define( "jquery", [], function () { return jQuery; } );
  7462. }
  7463. }
  7464. // If there is a window object, that at least has a document property,
  7465. // define jQuery and $ identifiers
  7466. if ( typeof window === "object" && typeof window.document === "object" ) {
  7467. window.jQuery = window.$ = jQuery;
  7468. }
  7469. })( window );
  7470. /**
  7471. * @license
  7472. * Lo-Dash 2.2.1 (Custom Build) <http://lodash.com/>
  7473. * Build: `lodash modern -o ./dist/lodash.js`
  7474. * Copyright 2012-2013 The Dojo Foundation <http://dojofoundation.org/>
  7475. * Based on Underscore.js 1.5.2 <http://underscorejs.org/LICENSE>
  7476. * Copyright 2009-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
  7477. * Available under MIT license <http://lodash.com/license>
  7478. */
  7479. ;(function() {
  7480. /** Used as a safe reference for `undefined` in pre ES5 environments */
  7481. var undefined;
  7482. /** Used to pool arrays and objects used internally */
  7483. var arrayPool = [],
  7484. objectPool = [];
  7485. /** Used to generate unique IDs */
  7486. var idCounter = 0;
  7487. /** Used to prefix keys to avoid issues with `__proto__` and properties on `Object.prototype` */
  7488. var keyPrefix = +new Date + '';
  7489. /** Used as the size when optimizations are enabled for large arrays */
  7490. var largeArraySize = 75;
  7491. /** Used as the max size of the `arrayPool` and `objectPool` */
  7492. var maxPoolSize = 40;
  7493. /** Used to detect and test whitespace */
  7494. var whitespace = (
  7495. // whitespace
  7496. ' \t\x0B\f\xA0\ufeff' +
  7497. // line terminators
  7498. '\n\r\u2028\u2029' +
  7499. // unicode category "Zs" space separators
  7500. '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000'
  7501. );
  7502. /** Used to match empty string literals in compiled template source */
  7503. var reEmptyStringLeading = /\b__p \+= '';/g,
  7504. reEmptyStringMiddle = /\b(__p \+=) '' \+/g,
  7505. reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g;
  7506. /**
  7507. * Used to match ES6 template delimiters
  7508. * http://people.mozilla.org/~jorendorff/es6-draft.html#sec-7.8.6
  7509. */
  7510. var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g;
  7511. /** Used to match regexp flags from their coerced string values */
  7512. var reFlags = /\w*$/;
  7513. /** Used to detected named functions */
  7514. var reFuncName = /^function[ \n\r\t]+\w/;
  7515. /** Used to match "interpolate" template delimiters */
  7516. var reInterpolate = /<%=([\s\S]+?)%>/g;
  7517. /** Used to match leading whitespace and zeros to be removed */
  7518. var reLeadingSpacesAndZeros = RegExp('^[' + whitespace + ']*0+(?=.$)');
  7519. /** Used to ensure capturing order of template delimiters */
  7520. var reNoMatch = /($^)/;
  7521. /** Used to detect functions containing a `this` reference */
  7522. var reThis = /\bthis\b/;
  7523. /** Used to match unescaped characters in compiled string literals */
  7524. var reUnescapedString = /['\n\r\t\u2028\u2029\\]/g;
  7525. /** Used to assign default `context` object properties */
  7526. var contextProps = [
  7527. 'Array', 'Boolean', 'Date', 'Function', 'Math', 'Number', 'Object',
  7528. 'RegExp', 'String', '_', 'attachEvent', 'clearTimeout', 'isFinite', 'isNaN',
  7529. 'parseInt', 'setImmediate', 'setTimeout'
  7530. ];
  7531. /** Used to make template sourceURLs easier to identify */
  7532. var templateCounter = 0;
  7533. /** `Object#toString` result shortcuts */
  7534. var argsClass = '[object Arguments]',
  7535. arrayClass = '[object Array]',
  7536. boolClass = '[object Boolean]',
  7537. dateClass = '[object Date]',
  7538. funcClass = '[object Function]',
  7539. numberClass = '[object Number]',
  7540. objectClass = '[object Object]',
  7541. regexpClass = '[object RegExp]',
  7542. stringClass = '[object String]';
  7543. /** Used to identify object classifications that `_.clone` supports */
  7544. var cloneableClasses = {};
  7545. cloneableClasses[funcClass] = false;
  7546. cloneableClasses[argsClass] = cloneableClasses[arrayClass] =
  7547. cloneableClasses[boolClass] = cloneableClasses[dateClass] =
  7548. cloneableClasses[numberClass] = cloneableClasses[objectClass] =
  7549. cloneableClasses[regexpClass] = cloneableClasses[stringClass] = true;
  7550. /** Used as an internal `_.debounce` options object */
  7551. var debounceOptions = {
  7552. 'leading': false,
  7553. 'maxWait': 0,
  7554. 'trailing': false
  7555. };
  7556. /** Used as the property descriptor for `__bindData__` */
  7557. var descriptor = {
  7558. 'configurable': false,
  7559. 'enumerable': false,
  7560. 'value': null,
  7561. 'writable': false
  7562. };
  7563. /** Used to determine if values are of the language type Object */
  7564. var objectTypes = {
  7565. 'boolean': false,
  7566. 'function': true,
  7567. 'object': true,
  7568. 'number': false,
  7569. 'string': false,
  7570. 'undefined': false
  7571. };
  7572. /** Used to escape characters for inclusion in compiled string literals */
  7573. var stringEscapes = {
  7574. '\\': '\\',
  7575. "'": "'",
  7576. '\n': 'n',
  7577. '\r': 'r',
  7578. '\t': 't',
  7579. '\u2028': 'u2028',
  7580. '\u2029': 'u2029'
  7581. };
  7582. /** Used as a reference to the global object */
  7583. var root = (objectTypes[typeof window] && window) || this;
  7584. /** Detect free variable `exports` */
  7585. var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
  7586. /** Detect free variable `module` */
  7587. var freeModule = objectTypes[typeof module] && module && !module.nodeType && module;
  7588. /** Detect the popular CommonJS extension `module.exports` */
  7589. var moduleExports = freeModule && freeModule.exports === freeExports && freeExports;
  7590. /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */
  7591. var freeGlobal = objectTypes[typeof global] && global;
  7592. if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) {
  7593. root = freeGlobal;
  7594. }
  7595. /*--------------------------------------------------------------------------*/
  7596. /**
  7597. * The base implementation of `_.indexOf` without support for binary searches
  7598. * or `fromIndex` constraints.
  7599. *
  7600. * @private
  7601. * @param {Array} array The array to search.
  7602. * @param {*} value The value to search for.
  7603. * @param {number} [fromIndex=0] The index to search from.
  7604. * @returns {number} Returns the index of the matched value or `-1`.
  7605. */
  7606. function baseIndexOf(array, value, fromIndex) {
  7607. var index = (fromIndex || 0) - 1,
  7608. length = array ? array.length : 0;
  7609. while (++index < length) {
  7610. if (array[index] === value) {
  7611. return index;
  7612. }
  7613. }
  7614. return -1;
  7615. }
  7616. /**
  7617. * An implementation of `_.contains` for cache objects that mimics the return
  7618. * signature of `_.indexOf` by returning `0` if the value is found, else `-1`.
  7619. *
  7620. * @private
  7621. * @param {Object} cache The cache object to inspect.
  7622. * @param {*} value The value to search for.
  7623. * @returns {number} Returns `0` if `value` is found, else `-1`.
  7624. */
  7625. function cacheIndexOf(cache, value) {
  7626. var type = typeof value;
  7627. cache = cache.cache;
  7628. if (type == 'boolean' || value == null) {
  7629. return cache[value] ? 0 : -1;
  7630. }
  7631. if (type != 'number' && type != 'string') {
  7632. type = 'object';
  7633. }
  7634. var key = type == 'number' ? value : keyPrefix + value;
  7635. cache = (cache = cache[type]) && cache[key];
  7636. return type == 'object'
  7637. ? (cache && baseIndexOf(cache, value) > -1 ? 0 : -1)
  7638. : (cache ? 0 : -1);
  7639. }
  7640. /**
  7641. * Adds a given value to the corresponding cache object.
  7642. *
  7643. * @private
  7644. * @param {*} value The value to add to the cache.
  7645. */
  7646. function cachePush(value) {
  7647. var cache = this.cache,
  7648. type = typeof value;
  7649. if (type == 'boolean' || value == null) {
  7650. cache[value] = true;
  7651. } else {
  7652. if (type != 'number' && type != 'string') {
  7653. type = 'object';
  7654. }
  7655. var key = type == 'number' ? value : keyPrefix + value,
  7656. typeCache = cache[type] || (cache[type] = {});
  7657. if (type == 'object') {
  7658. (typeCache[key] || (typeCache[key] = [])).push(value);
  7659. } else {
  7660. typeCache[key] = true;
  7661. }
  7662. }
  7663. }
  7664. /**
  7665. * Used by `_.max` and `_.min` as the default callback when a given
  7666. * collection is a string value.
  7667. *
  7668. * @private
  7669. * @param {string} value The character to inspect.
  7670. * @returns {number} Returns the code unit of given character.
  7671. */
  7672. function charAtCallback(value) {
  7673. return value.charCodeAt(0);
  7674. }
  7675. /**
  7676. * Used by `sortBy` to compare transformed `collection` elements, stable sorting
  7677. * them in ascending order.
  7678. *
  7679. * @private
  7680. * @param {Object} a The object to compare to `b`.
  7681. * @param {Object} b The object to compare to `a`.
  7682. * @returns {number} Returns the sort order indicator of `1` or `-1`.
  7683. */
  7684. function compareAscending(a, b) {
  7685. var ac = a.criteria,
  7686. bc = b.criteria;
  7687. // ensure a stable sort in V8 and other engines
  7688. // http://code.google.com/p/v8/issues/detail?id=90
  7689. if (ac !== bc) {
  7690. if (ac > bc || typeof ac == 'undefined') {
  7691. return 1;
  7692. }
  7693. if (ac < bc || typeof bc == 'undefined') {
  7694. return -1;
  7695. }
  7696. }
  7697. // The JS engine embedded in Adobe applications like InDesign has a buggy
  7698. // `Array#sort` implementation that causes it, under certain circumstances,
  7699. // to return the same value for `a` and `b`.
  7700. // See https://github.com/jashkenas/underscore/pull/1247
  7701. return a.index - b.index;
  7702. }
  7703. /**
  7704. * Creates a cache object to optimize linear searches of large arrays.
  7705. *
  7706. * @private
  7707. * @param {Array} [array=[]] The array to search.
  7708. * @returns {null|Object} Returns the cache object or `null` if caching should not be used.
  7709. */
  7710. function createCache(array) {
  7711. var index = -1,
  7712. length = array.length,
  7713. first = array[0],
  7714. mid = array[(length / 2) | 0],
  7715. last = array[length - 1];
  7716. if (first && typeof first == 'object' &&
  7717. mid && typeof mid == 'object' && last && typeof last == 'object') {
  7718. return false;
  7719. }
  7720. var cache = getObject();
  7721. cache['false'] = cache['null'] = cache['true'] = cache['undefined'] = false;
  7722. var result = getObject();
  7723. result.array = array;
  7724. result.cache = cache;
  7725. result.push = cachePush;
  7726. while (++index < length) {
  7727. result.push(array[index]);
  7728. }
  7729. return result;
  7730. }
  7731. /**
  7732. * Used by `template` to escape characters for inclusion in compiled
  7733. * string literals.
  7734. *
  7735. * @private
  7736. * @param {string} match The matched character to escape.
  7737. * @returns {string} Returns the escaped character.
  7738. */
  7739. function escapeStringChar(match) {
  7740. return '\\' + stringEscapes[match];
  7741. }
  7742. /**
  7743. * Gets an array from the array pool or creates a new one if the pool is empty.
  7744. *
  7745. * @private
  7746. * @returns {Array} The array from the pool.
  7747. */
  7748. function getArray() {
  7749. return arrayPool.pop() || [];
  7750. }
  7751. /**
  7752. * Gets an object from the object pool or creates a new one if the pool is empty.
  7753. *
  7754. * @private
  7755. * @returns {Object} The object from the pool.
  7756. */
  7757. function getObject() {
  7758. return objectPool.pop() || {
  7759. 'array': null,
  7760. 'cache': null,
  7761. 'criteria': null,
  7762. 'false': false,
  7763. 'index': 0,
  7764. 'null': false,
  7765. 'number': null,
  7766. 'object': null,
  7767. 'push': null,
  7768. 'string': null,
  7769. 'true': false,
  7770. 'undefined': false,
  7771. 'value': null
  7772. };
  7773. }
  7774. /**
  7775. * A no-operation function.
  7776. *
  7777. * @private
  7778. */
  7779. function noop() {
  7780. // no operation performed
  7781. }
  7782. /**
  7783. * Releases the given array back to the array pool.
  7784. *
  7785. * @private
  7786. * @param {Array} [array] The array to release.
  7787. */
  7788. function releaseArray(array) {
  7789. array.length = 0;
  7790. if (arrayPool.length < maxPoolSize) {
  7791. arrayPool.push(array);
  7792. }
  7793. }
  7794. /**
  7795. * Releases the given object back to the object pool.
  7796. *
  7797. * @private
  7798. * @param {Object} [object] The object to release.
  7799. */
  7800. function releaseObject(object) {
  7801. var cache = object.cache;
  7802. if (cache) {
  7803. releaseObject(cache);
  7804. }
  7805. object.array = object.cache = object.criteria = object.object = object.number = object.string = object.value = null;
  7806. if (objectPool.length < maxPoolSize) {
  7807. objectPool.push(object);
  7808. }
  7809. }
  7810. /**
  7811. * Slices the `collection` from the `start` index up to, but not including,
  7812. * the `end` index.
  7813. *
  7814. * Note: This function is used instead of `Array#slice` to support node lists
  7815. * in IE < 9 and to ensure dense arrays are returned.
  7816. *
  7817. * @private
  7818. * @param {Array|Object|string} collection The collection to slice.
  7819. * @param {number} start The start index.
  7820. * @param {number} end The end index.
  7821. * @returns {Array} Returns the new array.
  7822. */
  7823. function slice(array, start, end) {
  7824. start || (start = 0);
  7825. if (typeof end == 'undefined') {
  7826. end = array ? array.length : 0;
  7827. }
  7828. var index = -1,
  7829. length = end - start || 0,
  7830. result = Array(length < 0 ? 0 : length);
  7831. while (++index < length) {
  7832. result[index] = array[start + index];
  7833. }
  7834. return result;
  7835. }
  7836. /*--------------------------------------------------------------------------*/
  7837. /**
  7838. * Create a new `lodash` function using the given context object.
  7839. *
  7840. * @static
  7841. * @memberOf _
  7842. * @category Utilities
  7843. * @param {Object} [context=root] The context object.
  7844. * @returns {Function} Returns the `lodash` function.
  7845. */
  7846. function runInContext(context) {
  7847. // Avoid issues with some ES3 environments that attempt to use values, named
  7848. // after built-in constructors like `Object`, for the creation of literals.
  7849. // ES5 clears this up by stating that literals must use built-in constructors.
  7850. // See http://es5.github.io/#x11.1.5.
  7851. context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root;
  7852. /** Native constructor references */
  7853. var Array = context.Array,
  7854. Boolean = context.Boolean,
  7855. Date = context.Date,
  7856. Function = context.Function,
  7857. Math = context.Math,
  7858. Number = context.Number,
  7859. Object = context.Object,
  7860. RegExp = context.RegExp,
  7861. String = context.String,
  7862. TypeError = context.TypeError;
  7863. /**
  7864. * Used for `Array` method references.
  7865. *
  7866. * Normally `Array.prototype` would suffice, however, using an array literal
  7867. * avoids issues in Narwhal.
  7868. */
  7869. var arrayRef = [];
  7870. /** Used for native method references */
  7871. var objectProto = Object.prototype;
  7872. /** Used to restore the original `_` reference in `noConflict` */
  7873. var oldDash = context._;
  7874. /** Used to detect if a method is native */
  7875. var reNative = RegExp('^' +
  7876. String(objectProto.valueOf)
  7877. .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  7878. .replace(/valueOf|for [^\]]+/g, '.+?') + '$'
  7879. );
  7880. /** Native method shortcuts */
  7881. var ceil = Math.ceil,
  7882. clearTimeout = context.clearTimeout,
  7883. floor = Math.floor,
  7884. fnToString = Function.prototype.toString,
  7885. getPrototypeOf = reNative.test(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf,
  7886. hasOwnProperty = objectProto.hasOwnProperty,
  7887. now = reNative.test(now = Date.now) && now || function() { return +new Date; },
  7888. push = arrayRef.push,
  7889. setImmediate = context.setImmediate,
  7890. setTimeout = context.setTimeout,
  7891. splice = arrayRef.splice,
  7892. toString = objectProto.toString,
  7893. unshift = arrayRef.unshift;
  7894. var defineProperty = (function() {
  7895. try {
  7896. var o = {},
  7897. func = reNative.test(func = Object.defineProperty) && func,
  7898. result = func(o, o, o) && func;
  7899. } catch(e) { }
  7900. return result;
  7901. }());
  7902. /* Native method shortcuts for methods with the same name as other `lodash` methods */
  7903. var nativeBind = reNative.test(nativeBind = toString.bind) && nativeBind,
  7904. nativeCreate = reNative.test(nativeCreate = Object.create) && nativeCreate,
  7905. nativeIsArray = reNative.test(nativeIsArray = Array.isArray) && nativeIsArray,
  7906. nativeIsFinite = context.isFinite,
  7907. nativeIsNaN = context.isNaN,
  7908. nativeKeys = reNative.test(nativeKeys = Object.keys) && nativeKeys,
  7909. nativeMax = Math.max,
  7910. nativeMin = Math.min,
  7911. nativeParseInt = context.parseInt,
  7912. nativeRandom = Math.random,
  7913. nativeSlice = arrayRef.slice;
  7914. /** Detect various environments */
  7915. var isIeOpera = reNative.test(context.attachEvent),
  7916. isV8 = nativeBind && !/\n|true/.test(nativeBind + isIeOpera);
  7917. /** Used to lookup a built-in constructor by [[Class]] */
  7918. var ctorByClass = {};
  7919. ctorByClass[arrayClass] = Array;
  7920. ctorByClass[boolClass] = Boolean;
  7921. ctorByClass[dateClass] = Date;
  7922. ctorByClass[funcClass] = Function;
  7923. ctorByClass[objectClass] = Object;
  7924. ctorByClass[numberClass] = Number;
  7925. ctorByClass[regexpClass] = RegExp;
  7926. ctorByClass[stringClass] = String;
  7927. /*--------------------------------------------------------------------------*/
  7928. /**
  7929. * Creates a `lodash` object which wraps the given value to enable intuitive
  7930. * method chaining.
  7931. *
  7932. * In addition to Lo-Dash methods, wrappers also have the following `Array` methods:
  7933. * `concat`, `join`, `pop`, `push`, `reverse`, `shift`, `slice`, `sort`, `splice`,
  7934. * and `unshift`
  7935. *
  7936. * Chaining is supported in custom builds as long as the `value` method is
  7937. * implicitly or explicitly included in the build.
  7938. *
  7939. * The chainable wrapper functions are:
  7940. * `after`, `assign`, `bind`, `bindAll`, `bindKey`, `chain`, `compact`,
  7941. * `compose`, `concat`, `countBy`, `createCallback`, `curry`, `debounce`,
  7942. * `defaults`, `defer`, `delay`, `difference`, `filter`, `flatten`, `forEach`,
  7943. * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`,
  7944. * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`,
  7945. * `map`, `max`, `memoize`, `merge`, `min`, `object`, `omit`, `once`, `pairs`,
  7946. * `partial`, `partialRight`, `pick`, `pluck`, `pull`, `push`, `range`, `reject`,
  7947. * `remove`, `rest`, `reverse`, `shuffle`, `slice`, `sort`, `sortBy`, `splice`,
  7948. * `tap`, `throttle`, `times`, `toArray`, `transform`, `union`, `uniq`, `unshift`,
  7949. * `unzip`, `values`, `where`, `without`, `wrap`, and `zip`
  7950. *
  7951. * The non-chainable wrapper functions are:
  7952. * `clone`, `cloneDeep`, `contains`, `escape`, `every`, `find`, `findIndex`,
  7953. * `findKey`, `findLast`, `findLastIndex`, `findLastKey`, `has`, `identity`,
  7954. * `indexOf`, `isArguments`, `isArray`, `isBoolean`, `isDate`, `isElement`,
  7955. * `isEmpty`, `isEqual`, `isFinite`, `isFunction`, `isNaN`, `isNull`, `isNumber`,
  7956. * `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `join`,
  7957. * `lastIndexOf`, `mixin`, `noConflict`, `parseInt`, `pop`, `random`, `reduce`,
  7958. * `reduceRight`, `result`, `shift`, `size`, `some`, `sortedIndex`, `runInContext`,
  7959. * `template`, `unescape`, `uniqueId`, and `value`
  7960. *
  7961. * The wrapper functions `first` and `last` return wrapped values when `n` is
  7962. * provided, otherwise they return unwrapped values.
  7963. *
  7964. * Explicit chaining can be enabled by using the `_.chain` method.
  7965. *
  7966. * @name _
  7967. * @constructor
  7968. * @category Chaining
  7969. * @param {*} value The value to wrap in a `lodash` instance.
  7970. * @returns {Object} Returns a `lodash` instance.
  7971. * @example
  7972. *
  7973. * var wrapped = _([1, 2, 3]);
  7974. *
  7975. * // returns an unwrapped value
  7976. * wrapped.reduce(function(sum, num) {
  7977. * return sum + num;
  7978. * });
  7979. * // => 6
  7980. *
  7981. * // returns a wrapped value
  7982. * var squares = wrapped.map(function(num) {
  7983. * return num * num;
  7984. * });
  7985. *
  7986. * _.isArray(squares);
  7987. * // => false
  7988. *
  7989. * _.isArray(squares.value());
  7990. * // => true
  7991. */
  7992. function lodash(value) {
  7993. // don't wrap if already wrapped, even if wrapped by a different `lodash` constructor
  7994. return (value && typeof value == 'object' && !isArray(value) && hasOwnProperty.call(value, '__wrapped__'))
  7995. ? value
  7996. : new lodashWrapper(value);
  7997. }
  7998. /**
  7999. * A fast path for creating `lodash` wrapper objects.
  8000. *
  8001. * @private
  8002. * @param {*} value The value to wrap in a `lodash` instance.
  8003. * @param {boolean} chainAll A flag to enable chaining for all methods
  8004. * @returns {Object} Returns a `lodash` instance.
  8005. */
  8006. function lodashWrapper(value, chainAll) {
  8007. this.__chain__ = !!chainAll;
  8008. this.__wrapped__ = value;
  8009. }
  8010. // ensure `new lodashWrapper` is an instance of `lodash`
  8011. lodashWrapper.prototype = lodash.prototype;
  8012. /**
  8013. * An object used to flag environments features.
  8014. *
  8015. * @static
  8016. * @memberOf _
  8017. * @type Object
  8018. */
  8019. var support = lodash.support = {};
  8020. /**
  8021. * Detect if `Function#bind` exists and is inferred to be fast (all but V8).
  8022. *
  8023. * @memberOf _.support
  8024. * @type boolean
  8025. */
  8026. support.fastBind = nativeBind && !isV8;
  8027. /**
  8028. * Detect if functions can be decompiled by `Function#toString`
  8029. * (all but PS3 and older Opera mobile browsers & avoided in Windows 8 apps).
  8030. *
  8031. * @memberOf _.support
  8032. * @type boolean
  8033. */
  8034. support.funcDecomp = !reNative.test(context.WinRTError) && reThis.test(runInContext);
  8035. /**
  8036. * Detect if `Function#name` is supported (all but IE).
  8037. *
  8038. * @memberOf _.support
  8039. * @type boolean
  8040. */
  8041. support.funcNames = typeof Function.name == 'string';
  8042. /**
  8043. * By default, the template delimiters used by Lo-Dash are similar to those in
  8044. * embedded Ruby (ERB). Change the following template settings to use alternative
  8045. * delimiters.
  8046. *
  8047. * @static
  8048. * @memberOf _
  8049. * @type Object
  8050. */
  8051. lodash.templateSettings = {
  8052. /**
  8053. * Used to detect `data` property values to be HTML-escaped.
  8054. *
  8055. * @memberOf _.templateSettings
  8056. * @type RegExp
  8057. */
  8058. 'escape': /<%-([\s\S]+?)%>/g,
  8059. /**
  8060. * Used to detect code to be evaluated.
  8061. *
  8062. * @memberOf _.templateSettings
  8063. * @type RegExp
  8064. */
  8065. 'evaluate': /<%([\s\S]+?)%>/g,
  8066. /**
  8067. * Used to detect `data` property values to inject.
  8068. *
  8069. * @memberOf _.templateSettings
  8070. * @type RegExp
  8071. */
  8072. 'interpolate': reInterpolate,
  8073. /**
  8074. * Used to reference the data object in the template text.
  8075. *
  8076. * @memberOf _.templateSettings
  8077. * @type string
  8078. */
  8079. 'variable': '',
  8080. /**
  8081. * Used to import variables into the compiled template.
  8082. *
  8083. * @memberOf _.templateSettings
  8084. * @type Object
  8085. */
  8086. 'imports': {
  8087. /**
  8088. * A reference to the `lodash` function.
  8089. *
  8090. * @memberOf _.templateSettings.imports
  8091. * @type Function
  8092. */
  8093. '_': lodash
  8094. }
  8095. };
  8096. /*--------------------------------------------------------------------------*/
  8097. /**
  8098. * The base implementation of `_.clone` without argument juggling or support
  8099. * for `thisArg` binding.
  8100. *
  8101. * @private
  8102. * @param {*} value The value to clone.
  8103. * @param {boolean} [deep=false] Specify a deep clone.
  8104. * @param {Function} [callback] The function to customize cloning values.
  8105. * @param {Array} [stackA=[]] Tracks traversed source objects.
  8106. * @param {Array} [stackB=[]] Associates clones with source counterparts.
  8107. * @returns {*} Returns the cloned value.
  8108. */
  8109. function baseClone(value, deep, callback, stackA, stackB) {
  8110. if (callback) {
  8111. var result = callback(value);
  8112. if (typeof result != 'undefined') {
  8113. return result;
  8114. }
  8115. }
  8116. // inspect [[Class]]
  8117. var isObj = isObject(value);
  8118. if (isObj) {
  8119. var className = toString.call(value);
  8120. if (!cloneableClasses[className]) {
  8121. return value;
  8122. }
  8123. var ctor = ctorByClass[className];
  8124. switch (className) {
  8125. case boolClass:
  8126. case dateClass:
  8127. return new ctor(+value);
  8128. case numberClass:
  8129. case stringClass:
  8130. return new ctor(value);
  8131. case regexpClass:
  8132. result = ctor(value.source, reFlags.exec(value));
  8133. result.lastIndex = value.lastIndex;
  8134. return result;
  8135. }
  8136. } else {
  8137. return value;
  8138. }
  8139. var isArr = isArray(value);
  8140. if (deep) {
  8141. // check for circular references and return corresponding clone
  8142. var initedStack = !stackA;
  8143. stackA || (stackA = getArray());
  8144. stackB || (stackB = getArray());
  8145. var length = stackA.length;
  8146. while (length--) {
  8147. if (stackA[length] == value) {
  8148. return stackB[length];
  8149. }
  8150. }
  8151. result = isArr ? ctor(value.length) : {};
  8152. }
  8153. else {
  8154. result = isArr ? slice(value) : assign({}, value);
  8155. }
  8156. // add array properties assigned by `RegExp#exec`
  8157. if (isArr) {
  8158. if (hasOwnProperty.call(value, 'index')) {
  8159. result.index = value.index;
  8160. }
  8161. if (hasOwnProperty.call(value, 'input')) {
  8162. result.input = value.input;
  8163. }
  8164. }
  8165. // exit for shallow clone
  8166. if (!deep) {
  8167. return result;
  8168. }
  8169. // add the source value to the stack of traversed objects
  8170. // and associate it with its clone
  8171. stackA.push(value);
  8172. stackB.push(result);
  8173. // recursively populate clone (susceptible to call stack limits)
  8174. (isArr ? forEach : forOwn)(value, function(objValue, key) {
  8175. result[key] = baseClone(objValue, deep, callback, stackA, stackB);
  8176. });
  8177. if (initedStack) {
  8178. releaseArray(stackA);
  8179. releaseArray(stackB);
  8180. }
  8181. return result;
  8182. }
  8183. /**
  8184. * The base implementation of `_.createCallback` without support for creating
  8185. * "_.pluck" or "_.where" style callbacks.
  8186. *
  8187. * @private
  8188. * @param {*} [func=identity] The value to convert to a callback.
  8189. * @param {*} [thisArg] The `this` binding of the created callback.
  8190. * @param {number} [argCount] The number of arguments the callback accepts.
  8191. * @returns {Function} Returns a callback function.
  8192. */
  8193. function baseCreateCallback(func, thisArg, argCount) {
  8194. if (typeof func != 'function') {
  8195. return identity;
  8196. }
  8197. // exit early if there is no `thisArg`
  8198. if (typeof thisArg == 'undefined') {
  8199. return func;
  8200. }
  8201. var bindData = func.__bindData__ || (support.funcNames && !func.name);
  8202. if (typeof bindData == 'undefined') {
  8203. var source = reThis && fnToString.call(func);
  8204. if (!support.funcNames && source && !reFuncName.test(source)) {
  8205. bindData = true;
  8206. }
  8207. if (support.funcNames || !bindData) {
  8208. // checks if `func` references the `this` keyword and stores the result
  8209. bindData = !support.funcDecomp || reThis.test(source);
  8210. setBindData(func, bindData);
  8211. }
  8212. }
  8213. // exit early if there are no `this` references or `func` is bound
  8214. if (bindData !== true && (bindData && bindData[1] & 1)) {
  8215. return func;
  8216. }
  8217. switch (argCount) {
  8218. case 1: return function(value) {
  8219. return func.call(thisArg, value);
  8220. };
  8221. case 2: return function(a, b) {
  8222. return func.call(thisArg, a, b);
  8223. };
  8224. case 3: return function(value, index, collection) {
  8225. return func.call(thisArg, value, index, collection);
  8226. };
  8227. case 4: return function(accumulator, value, index, collection) {
  8228. return func.call(thisArg, accumulator, value, index, collection);
  8229. };
  8230. }
  8231. return bind(func, thisArg);
  8232. }
  8233. /**
  8234. * The base implementation of `_.flatten` without support for callback
  8235. * shorthands or `thisArg` binding.
  8236. *
  8237. * @private
  8238. * @param {Array} array The array to flatten.
  8239. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
  8240. * @param {boolean} [isArgArrays=false] A flag to restrict flattening to arrays and `arguments` objects.
  8241. * @param {number} [fromIndex=0] The index to start from.
  8242. * @returns {Array} Returns a new flattened array.
  8243. */
  8244. function baseFlatten(array, isShallow, isArgArrays, fromIndex) {
  8245. var index = (fromIndex || 0) - 1,
  8246. length = array ? array.length : 0,
  8247. result = [];
  8248. while (++index < length) {
  8249. var value = array[index];
  8250. if (value && typeof value == 'object' && typeof value.length == 'number'
  8251. && (isArray(value) || isArguments(value))) {
  8252. // recursively flatten arrays (susceptible to call stack limits)
  8253. if (!isShallow) {
  8254. value = baseFlatten(value, isShallow, isArgArrays);
  8255. }
  8256. var valIndex = -1,
  8257. valLength = value.length,
  8258. resIndex = result.length;
  8259. result.length += valLength;
  8260. while (++valIndex < valLength) {
  8261. result[resIndex++] = value[valIndex];
  8262. }
  8263. } else if (!isArgArrays) {
  8264. result.push(value);
  8265. }
  8266. }
  8267. return result;
  8268. }
  8269. /**
  8270. * The base implementation of `_.isEqual`, without support for `thisArg` binding,
  8271. * that allows partial "_.where" style comparisons.
  8272. *
  8273. * @private
  8274. * @param {*} a The value to compare.
  8275. * @param {*} b The other value to compare.
  8276. * @param {Function} [callback] The function to customize comparing values.
  8277. * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons.
  8278. * @param {Array} [stackA=[]] Tracks traversed `a` objects.
  8279. * @param {Array} [stackB=[]] Tracks traversed `b` objects.
  8280. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  8281. */
  8282. function baseIsEqual(a, b, callback, isWhere, stackA, stackB) {
  8283. // used to indicate that when comparing objects, `a` has at least the properties of `b`
  8284. if (callback) {
  8285. var result = callback(a, b);
  8286. if (typeof result != 'undefined') {
  8287. return !!result;
  8288. }
  8289. }
  8290. // exit early for identical values
  8291. if (a === b) {
  8292. // treat `+0` vs. `-0` as not equal
  8293. return a !== 0 || (1 / a == 1 / b);
  8294. }
  8295. var type = typeof a,
  8296. otherType = typeof b;
  8297. // exit early for unlike primitive values
  8298. if (a === a &&
  8299. !(a && objectTypes[type]) &&
  8300. !(b && objectTypes[otherType])) {
  8301. return false;
  8302. }
  8303. // exit early for `null` and `undefined` avoiding ES3's Function#call behavior
  8304. // http://es5.github.io/#x15.3.4.4
  8305. if (a == null || b == null) {
  8306. return a === b;
  8307. }
  8308. // compare [[Class]] names
  8309. var className = toString.call(a),
  8310. otherClass = toString.call(b);
  8311. if (className == argsClass) {
  8312. className = objectClass;
  8313. }
  8314. if (otherClass == argsClass) {
  8315. otherClass = objectClass;
  8316. }
  8317. if (className != otherClass) {
  8318. return false;
  8319. }
  8320. switch (className) {
  8321. case boolClass:
  8322. case dateClass:
  8323. // coerce dates and booleans to numbers, dates to milliseconds and booleans
  8324. // to `1` or `0` treating invalid dates coerced to `NaN` as not equal
  8325. return +a == +b;
  8326. case numberClass:
  8327. // treat `NaN` vs. `NaN` as equal
  8328. return (a != +a)
  8329. ? b != +b
  8330. // but treat `+0` vs. `-0` as not equal
  8331. : (a == 0 ? (1 / a == 1 / b) : a == +b);
  8332. case regexpClass:
  8333. case stringClass:
  8334. // coerce regexes to strings (http://es5.github.io/#x15.10.6.4)
  8335. // treat string primitives and their corresponding object instances as equal
  8336. return a == String(b);
  8337. }
  8338. var isArr = className == arrayClass;
  8339. if (!isArr) {
  8340. // unwrap any `lodash` wrapped values
  8341. if (hasOwnProperty.call(a, '__wrapped__ ') || hasOwnProperty.call(b, '__wrapped__')) {
  8342. return baseIsEqual(a.__wrapped__ || a, b.__wrapped__ || b, callback, isWhere, stackA, stackB);
  8343. }
  8344. // exit for functions and DOM nodes
  8345. if (className != objectClass) {
  8346. return false;
  8347. }
  8348. // in older versions of Opera, `arguments` objects have `Array` constructors
  8349. var ctorA = a.constructor,
  8350. ctorB = b.constructor;
  8351. // non `Object` object instances with different constructors are not equal
  8352. if (ctorA != ctorB && !(
  8353. isFunction(ctorA) && ctorA instanceof ctorA &&
  8354. isFunction(ctorB) && ctorB instanceof ctorB
  8355. )) {
  8356. return false;
  8357. }
  8358. }
  8359. // assume cyclic structures are equal
  8360. // the algorithm for detecting cyclic structures is adapted from ES 5.1
  8361. // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3)
  8362. var initedStack = !stackA;
  8363. stackA || (stackA = getArray());
  8364. stackB || (stackB = getArray());
  8365. var length = stackA.length;
  8366. while (length--) {
  8367. if (stackA[length] == a) {
  8368. return stackB[length] == b;
  8369. }
  8370. }
  8371. var size = 0;
  8372. result = true;
  8373. // add `a` and `b` to the stack of traversed objects
  8374. stackA.push(a);
  8375. stackB.push(b);
  8376. // recursively compare objects and arrays (susceptible to call stack limits)
  8377. if (isArr) {
  8378. length = a.length;
  8379. size = b.length;
  8380. // compare lengths to determine if a deep comparison is necessary
  8381. result = size == a.length;
  8382. if (!result && !isWhere) {
  8383. return result;
  8384. }
  8385. // deep compare the contents, ignoring non-numeric properties
  8386. while (size--) {
  8387. var index = length,
  8388. value = b[size];
  8389. if (isWhere) {
  8390. while (index--) {
  8391. if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) {
  8392. break;
  8393. }
  8394. }
  8395. } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) {
  8396. break;
  8397. }
  8398. }
  8399. return result;
  8400. }
  8401. // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys`
  8402. // which, in this case, is more costly
  8403. forIn(b, function(value, key, b) {
  8404. if (hasOwnProperty.call(b, key)) {
  8405. // count the number of properties.
  8406. size++;
  8407. // deep compare each property value.
  8408. return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB));
  8409. }
  8410. });
  8411. if (result && !isWhere) {
  8412. // ensure both objects have the same number of properties
  8413. forIn(a, function(value, key, a) {
  8414. if (hasOwnProperty.call(a, key)) {
  8415. // `size` will be `-1` if `a` has more properties than `b`
  8416. return (result = --size > -1);
  8417. }
  8418. });
  8419. }
  8420. if (initedStack) {
  8421. releaseArray(stackA);
  8422. releaseArray(stackB);
  8423. }
  8424. return result;
  8425. }
  8426. /**
  8427. * The base implementation of `_.merge` without argument juggling or support
  8428. * for `thisArg` binding.
  8429. *
  8430. * @private
  8431. * @param {Object} object The destination object.
  8432. * @param {Object} source The source object.
  8433. * @param {Function} [callback] The function to customize merging properties.
  8434. * @param {Array} [stackA=[]] Tracks traversed source objects.
  8435. * @param {Array} [stackB=[]] Associates values with source counterparts.
  8436. */
  8437. function baseMerge(object, source, callback, stackA, stackB) {
  8438. (isArray(source) ? forEach : forOwn)(source, function(source, key) {
  8439. var found,
  8440. isArr,
  8441. result = source,
  8442. value = object[key];
  8443. if (source && ((isArr = isArray(source)) || isPlainObject(source))) {
  8444. // avoid merging previously merged cyclic sources
  8445. var stackLength = stackA.length;
  8446. while (stackLength--) {
  8447. if ((found = stackA[stackLength] == source)) {
  8448. value = stackB[stackLength];
  8449. break;
  8450. }
  8451. }
  8452. if (!found) {
  8453. var isShallow;
  8454. if (callback) {
  8455. result = callback(value, source);
  8456. if ((isShallow = typeof result != 'undefined')) {
  8457. value = result;
  8458. }
  8459. }
  8460. if (!isShallow) {
  8461. value = isArr
  8462. ? (isArray(value) ? value : [])
  8463. : (isPlainObject(value) ? value : {});
  8464. }
  8465. // add `source` and associated `value` to the stack of traversed objects
  8466. stackA.push(source);
  8467. stackB.push(value);
  8468. // recursively merge objects and arrays (susceptible to call stack limits)
  8469. if (!isShallow) {
  8470. baseMerge(value, source, callback, stackA, stackB);
  8471. }
  8472. }
  8473. }
  8474. else {
  8475. if (callback) {
  8476. result = callback(value, source);
  8477. if (typeof result == 'undefined') {
  8478. result = source;
  8479. }
  8480. }
  8481. if (typeof result != 'undefined') {
  8482. value = result;
  8483. }
  8484. }
  8485. object[key] = value;
  8486. });
  8487. }
  8488. /**
  8489. * The base implementation of `_.uniq` without support for callback shorthands
  8490. * or `thisArg` binding.
  8491. *
  8492. * @private
  8493. * @param {Array} array The array to process.
  8494. * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
  8495. * @param {Function} [callback] The function called per iteration.
  8496. * @returns {Array} Returns a duplicate-value-free array.
  8497. */
  8498. function baseUniq(array, isSorted, callback) {
  8499. var index = -1,
  8500. indexOf = getIndexOf(),
  8501. length = array ? array.length : 0,
  8502. result = [];
  8503. var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf,
  8504. seen = (callback || isLarge) ? getArray() : result;
  8505. if (isLarge) {
  8506. var cache = createCache(seen);
  8507. if (cache) {
  8508. indexOf = cacheIndexOf;
  8509. seen = cache;
  8510. } else {
  8511. isLarge = false;
  8512. seen = callback ? seen : (releaseArray(seen), result);
  8513. }
  8514. }
  8515. while (++index < length) {
  8516. var value = array[index],
  8517. computed = callback ? callback(value, index, array) : value;
  8518. if (isSorted
  8519. ? !index || seen[seen.length - 1] !== computed
  8520. : indexOf(seen, computed) < 0
  8521. ) {
  8522. if (callback || isLarge) {
  8523. seen.push(computed);
  8524. }
  8525. result.push(value);
  8526. }
  8527. }
  8528. if (isLarge) {
  8529. releaseArray(seen.array);
  8530. releaseObject(seen);
  8531. } else if (callback) {
  8532. releaseArray(seen);
  8533. }
  8534. return result;
  8535. }
  8536. /**
  8537. * Creates a function that aggregates a collection, creating an object composed
  8538. * of keys generated from the results of running each element of the collection
  8539. * through a callback. The given `setter` function sets the keys and values
  8540. * of the composed object.
  8541. *
  8542. * @private
  8543. * @param {Function} setter The setter function.
  8544. * @returns {Function} Returns the new aggregator function.
  8545. */
  8546. function createAggregator(setter) {
  8547. return function(collection, callback, thisArg) {
  8548. var result = {};
  8549. callback = lodash.createCallback(callback, thisArg, 3);
  8550. var index = -1,
  8551. length = collection ? collection.length : 0;
  8552. if (typeof length == 'number') {
  8553. while (++index < length) {
  8554. var value = collection[index];
  8555. setter(result, value, callback(value, index, collection), collection);
  8556. }
  8557. } else {
  8558. forOwn(collection, function(value, key, collection) {
  8559. setter(result, value, callback(value, key, collection), collection);
  8560. });
  8561. }
  8562. return result;
  8563. };
  8564. }
  8565. /**
  8566. * Creates a function that, when called, either curries or invokes `func`
  8567. * with an optional `this` binding and partially applied arguments.
  8568. *
  8569. * @private
  8570. * @param {Function|string} func The function or method name to reference.
  8571. * @param {number} bitmask The bitmask of method flags to compose.
  8572. * The bitmask may be composed of the following flags:
  8573. * 1 - `_.bind`
  8574. * 2 - `_.bindKey`
  8575. * 4 - `_.curry`
  8576. * 8 - `_.curry` (bound)
  8577. * 16 - `_.partial`
  8578. * 32 - `_.partialRight`
  8579. * @param {Array} [partialArgs] An array of arguments to prepend to those
  8580. * provided to the new function.
  8581. * @param {Array} [partialRightArgs] An array of arguments to append to those
  8582. * provided to the new function.
  8583. * @param {*} [thisArg] The `this` binding of `func`.
  8584. * @param {number} [arity] The arity of `func`.
  8585. * @returns {Function} Returns the new bound function.
  8586. */
  8587. function createBound(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) {
  8588. var isBind = bitmask & 1,
  8589. isBindKey = bitmask & 2,
  8590. isCurry = bitmask & 4,
  8591. isCurryBound = bitmask & 8,
  8592. isPartial = bitmask & 16,
  8593. isPartialRight = bitmask & 32,
  8594. key = func;
  8595. if (!isBindKey && !isFunction(func)) {
  8596. throw new TypeError;
  8597. }
  8598. if (isPartial && !partialArgs.length) {
  8599. bitmask &= ~16;
  8600. isPartial = partialArgs = false;
  8601. }
  8602. if (isPartialRight && !partialRightArgs.length) {
  8603. bitmask &= ~32;
  8604. isPartialRight = partialRightArgs = false;
  8605. }
  8606. var bindData = func && func.__bindData__;
  8607. if (bindData) {
  8608. if (isBind && !(bindData[1] & 1)) {
  8609. bindData[4] = thisArg;
  8610. }
  8611. if (!isBind && bindData[1] & 1) {
  8612. bitmask |= 8;
  8613. }
  8614. if (isCurry && !(bindData[1] & 4)) {
  8615. bindData[5] = arity;
  8616. }
  8617. if (isPartial) {
  8618. push.apply(bindData[2] || (bindData[2] = []), partialArgs);
  8619. }
  8620. if (isPartialRight) {
  8621. push.apply(bindData[3] || (bindData[3] = []), partialRightArgs);
  8622. }
  8623. bindData[1] |= bitmask;
  8624. return createBound.apply(null, bindData);
  8625. }
  8626. // use `Function#bind` if it exists and is fast
  8627. // (in V8 `Function#bind` is slower except when partially applied)
  8628. if (isBind && !(isBindKey || isCurry || isPartialRight) &&
  8629. (support.fastBind || (nativeBind && isPartial))) {
  8630. if (isPartial) {
  8631. var args = [thisArg];
  8632. push.apply(args, partialArgs);
  8633. }
  8634. var bound = isPartial
  8635. ? nativeBind.apply(func, args)
  8636. : nativeBind.call(func, thisArg);
  8637. }
  8638. else {
  8639. bound = function() {
  8640. // `Function#bind` spec
  8641. // http://es5.github.io/#x15.3.4.5
  8642. var args = arguments,
  8643. thisBinding = isBind ? thisArg : this;
  8644. if (isCurry || isPartial || isPartialRight) {
  8645. args = nativeSlice.call(args);
  8646. if (isPartial) {
  8647. unshift.apply(args, partialArgs);
  8648. }
  8649. if (isPartialRight) {
  8650. push.apply(args, partialRightArgs);
  8651. }
  8652. if (isCurry && args.length < arity) {
  8653. bitmask |= 16 & ~32;
  8654. return createBound(func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity);
  8655. }
  8656. }
  8657. if (isBindKey) {
  8658. func = thisBinding[key];
  8659. }
  8660. if (this instanceof bound) {
  8661. // ensure `new bound` is an instance of `func`
  8662. thisBinding = createObject(func.prototype);
  8663. // mimic the constructor's `return` behavior
  8664. // http://es5.github.io/#x13.2.2
  8665. var result = func.apply(thisBinding, args);
  8666. return isObject(result) ? result : thisBinding;
  8667. }
  8668. return func.apply(thisBinding, args);
  8669. };
  8670. }
  8671. setBindData(bound, nativeSlice.call(arguments));
  8672. return bound;
  8673. }
  8674. /**
  8675. * Creates a new object with the specified `prototype`.
  8676. *
  8677. * @private
  8678. * @param {Object} prototype The prototype object.
  8679. * @returns {Object} Returns the new object.
  8680. */
  8681. function createObject(prototype) {
  8682. return isObject(prototype) ? nativeCreate(prototype) : {};
  8683. }
  8684. // fallback for browsers without `Object.create`
  8685. if (!nativeCreate) {
  8686. createObject = function(prototype) {
  8687. if (isObject(prototype)) {
  8688. noop.prototype = prototype;
  8689. var result = new noop;
  8690. noop.prototype = null;
  8691. }
  8692. return result || {};
  8693. };
  8694. }
  8695. /**
  8696. * Used by `escape` to convert characters to HTML entities.
  8697. *
  8698. * @private
  8699. * @param {string} match The matched character to escape.
  8700. * @returns {string} Returns the escaped character.
  8701. */
  8702. function escapeHtmlChar(match) {
  8703. return htmlEscapes[match];
  8704. }
  8705. /**
  8706. * Gets the appropriate "indexOf" function. If the `_.indexOf` method is
  8707. * customized, this method returns the custom method, otherwise it returns
  8708. * the `baseIndexOf` function.
  8709. *
  8710. * @private
  8711. * @returns {Function} Returns the "indexOf" function.
  8712. */
  8713. function getIndexOf() {
  8714. var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result;
  8715. return result;
  8716. }
  8717. /**
  8718. * Sets `this` binding data on a given function.
  8719. *
  8720. * @private
  8721. * @param {Function} func The function to set data on.
  8722. * @param {*} value The value to set.
  8723. */
  8724. var setBindData = !defineProperty ? noop : function(func, value) {
  8725. descriptor.value = value;
  8726. defineProperty(func, '__bindData__', descriptor);
  8727. };
  8728. /**
  8729. * A fallback implementation of `isPlainObject` which checks if a given value
  8730. * is an object created by the `Object` constructor, assuming objects created
  8731. * by the `Object` constructor have no inherited enumerable properties and that
  8732. * there are no `Object.prototype` extensions.
  8733. *
  8734. * @private
  8735. * @param {*} value The value to check.
  8736. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  8737. */
  8738. function shimIsPlainObject(value) {
  8739. var ctor,
  8740. result;
  8741. // avoid non Object objects, `arguments` objects, and DOM elements
  8742. if (!(value && toString.call(value) == objectClass) ||
  8743. (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) {
  8744. return false;
  8745. }
  8746. // In most environments an object's own properties are iterated before
  8747. // its inherited properties. If the last iterated property is an object's
  8748. // own property then there are no inherited enumerable properties.
  8749. forIn(value, function(value, key) {
  8750. result = key;
  8751. });
  8752. return typeof result == 'undefined' || hasOwnProperty.call(value, result);
  8753. }
  8754. /**
  8755. * Used by `unescape` to convert HTML entities to characters.
  8756. *
  8757. * @private
  8758. * @param {string} match The matched character to unescape.
  8759. * @returns {string} Returns the unescaped character.
  8760. */
  8761. function unescapeHtmlChar(match) {
  8762. return htmlUnescapes[match];
  8763. }
  8764. /*--------------------------------------------------------------------------*/
  8765. /**
  8766. * Checks if `value` is an `arguments` object.
  8767. *
  8768. * @static
  8769. * @memberOf _
  8770. * @category Objects
  8771. * @param {*} value The value to check.
  8772. * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`.
  8773. * @example
  8774. *
  8775. * (function() { return _.isArguments(arguments); })(1, 2, 3);
  8776. * // => true
  8777. *
  8778. * _.isArguments([1, 2, 3]);
  8779. * // => false
  8780. */
  8781. function isArguments(value) {
  8782. return value && typeof value == 'object' && typeof value.length == 'number' &&
  8783. toString.call(value) == argsClass || false;
  8784. }
  8785. /**
  8786. * Checks if `value` is an array.
  8787. *
  8788. * @static
  8789. * @memberOf _
  8790. * @type Function
  8791. * @category Objects
  8792. * @param {*} value The value to check.
  8793. * @returns {boolean} Returns `true` if the `value` is an array, else `false`.
  8794. * @example
  8795. *
  8796. * (function() { return _.isArray(arguments); })();
  8797. * // => false
  8798. *
  8799. * _.isArray([1, 2, 3]);
  8800. * // => true
  8801. */
  8802. var isArray = nativeIsArray || function(value) {
  8803. return value && typeof value == 'object' && typeof value.length == 'number' &&
  8804. toString.call(value) == arrayClass || false;
  8805. };
  8806. /**
  8807. * A fallback implementation of `Object.keys` which produces an array of the
  8808. * given object's own enumerable property names.
  8809. *
  8810. * @private
  8811. * @type Function
  8812. * @param {Object} object The object to inspect.
  8813. * @returns {Array} Returns an array of property names.
  8814. */
  8815. var shimKeys = function(object) {
  8816. var index, iterable = object, result = [];
  8817. if (!iterable) return result;
  8818. if (!(objectTypes[typeof object])) return result;
  8819. for (index in iterable) {
  8820. if (hasOwnProperty.call(iterable, index)) {
  8821. result.push(index);
  8822. }
  8823. }
  8824. return result
  8825. };
  8826. /**
  8827. * Creates an array composed of the own enumerable property names of an object.
  8828. *
  8829. * @static
  8830. * @memberOf _
  8831. * @category Objects
  8832. * @param {Object} object The object to inspect.
  8833. * @returns {Array} Returns an array of property names.
  8834. * @example
  8835. *
  8836. * _.keys({ 'one': 1, 'two': 2, 'three': 3 });
  8837. * // => ['one', 'two', 'three'] (property order is not guaranteed across environments)
  8838. */
  8839. var keys = !nativeKeys ? shimKeys : function(object) {
  8840. if (!isObject(object)) {
  8841. return [];
  8842. }
  8843. return nativeKeys(object);
  8844. };
  8845. /**
  8846. * Used to convert characters to HTML entities:
  8847. *
  8848. * Though the `>` character is escaped for symmetry, characters like `>` and `/`
  8849. * don't require escaping in HTML and have no special meaning unless they're part
  8850. * of a tag or an unquoted attribute value.
  8851. * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact")
  8852. */
  8853. var htmlEscapes = {
  8854. '&': '&amp;',
  8855. '<': '&lt;',
  8856. '>': '&gt;',
  8857. '"': '&quot;',
  8858. "'": '&#39;'
  8859. };
  8860. /** Used to convert HTML entities to characters */
  8861. var htmlUnescapes = invert(htmlEscapes);
  8862. /** Used to match HTML entities and HTML characters */
  8863. var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'),
  8864. reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g');
  8865. /*--------------------------------------------------------------------------*/
  8866. /**
  8867. * Assigns own enumerable properties of source object(s) to the destination
  8868. * object. Subsequent sources will overwrite property assignments of previous
  8869. * sources. If a callback is provided it will be executed to produce the
  8870. * assigned values. The callback is bound to `thisArg` and invoked with two
  8871. * arguments; (objectValue, sourceValue).
  8872. *
  8873. * @static
  8874. * @memberOf _
  8875. * @type Function
  8876. * @alias extend
  8877. * @category Objects
  8878. * @param {Object} object The destination object.
  8879. * @param {...Object} [source] The source objects.
  8880. * @param {Function} [callback] The function to customize assigning values.
  8881. * @param {*} [thisArg] The `this` binding of `callback`.
  8882. * @returns {Object} Returns the destination object.
  8883. * @example
  8884. *
  8885. * _.assign({ 'name': 'moe' }, { 'age': 40 });
  8886. * // => { 'name': 'moe', 'age': 40 }
  8887. *
  8888. * var defaults = _.partialRight(_.assign, function(a, b) {
  8889. * return typeof a == 'undefined' ? b : a;
  8890. * });
  8891. *
  8892. * var food = { 'name': 'apple' };
  8893. * defaults(food, { 'name': 'banana', 'type': 'fruit' });
  8894. * // => { 'name': 'apple', 'type': 'fruit' }
  8895. */
  8896. var assign = function(object, source, guard) {
  8897. var index, iterable = object, result = iterable;
  8898. if (!iterable) return result;
  8899. var args = arguments,
  8900. argsIndex = 0,
  8901. argsLength = typeof guard == 'number' ? 2 : args.length;
  8902. if (argsLength > 3 && typeof args[argsLength - 2] == 'function') {
  8903. var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);
  8904. } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {
  8905. callback = args[--argsLength];
  8906. }
  8907. while (++argsIndex < argsLength) {
  8908. iterable = args[argsIndex];
  8909. if (iterable && objectTypes[typeof iterable]) {
  8910. var ownIndex = -1,
  8911. ownProps = objectTypes[typeof iterable] && keys(iterable),
  8912. length = ownProps ? ownProps.length : 0;
  8913. while (++ownIndex < length) {
  8914. index = ownProps[ownIndex];
  8915. result[index] = callback ? callback(result[index], iterable[index]) : iterable[index];
  8916. }
  8917. }
  8918. }
  8919. return result
  8920. };
  8921. /**
  8922. * Creates a clone of `value`. If `deep` is `true` nested objects will also
  8923. * be cloned, otherwise they will be assigned by reference. If a callback
  8924. * is provided it will be executed to produce the cloned values. If the
  8925. * callback returns `undefined` cloning will be handled by the method instead.
  8926. * The callback is bound to `thisArg` and invoked with one argument; (value).
  8927. *
  8928. * @static
  8929. * @memberOf _
  8930. * @category Objects
  8931. * @param {*} value The value to clone.
  8932. * @param {boolean} [deep=false] Specify a deep clone.
  8933. * @param {Function} [callback] The function to customize cloning values.
  8934. * @param {*} [thisArg] The `this` binding of `callback`.
  8935. * @returns {*} Returns the cloned value.
  8936. * @example
  8937. *
  8938. * var stooges = [
  8939. * { 'name': 'moe', 'age': 40 },
  8940. * { 'name': 'larry', 'age': 50 }
  8941. * ];
  8942. *
  8943. * var shallow = _.clone(stooges);
  8944. * shallow[0] === stooges[0];
  8945. * // => true
  8946. *
  8947. * var deep = _.clone(stooges, true);
  8948. * deep[0] === stooges[0];
  8949. * // => false
  8950. *
  8951. * _.mixin({
  8952. * 'clone': _.partialRight(_.clone, function(value) {
  8953. * return _.isElement(value) ? value.cloneNode(false) : undefined;
  8954. * })
  8955. * });
  8956. *
  8957. * var clone = _.clone(document.body);
  8958. * clone.childNodes.length;
  8959. * // => 0
  8960. */
  8961. function clone(value, deep, callback, thisArg) {
  8962. // allows working with "Collections" methods without using their `index`
  8963. // and `collection` arguments for `deep` and `callback`
  8964. if (typeof deep != 'boolean' && deep != null) {
  8965. thisArg = callback;
  8966. callback = deep;
  8967. deep = false;
  8968. }
  8969. return baseClone(value, deep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
  8970. }
  8971. /**
  8972. * Creates a deep clone of `value`. If a callback is provided it will be
  8973. * executed to produce the cloned values. If the callback returns `undefined`
  8974. * cloning will be handled by the method instead. The callback is bound to
  8975. * `thisArg` and invoked with one argument; (value).
  8976. *
  8977. * Note: This method is loosely based on the structured clone algorithm. Functions
  8978. * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and
  8979. * objects created by constructors other than `Object` are cloned to plain `Object` objects.
  8980. * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm.
  8981. *
  8982. * @static
  8983. * @memberOf _
  8984. * @category Objects
  8985. * @param {*} value The value to deep clone.
  8986. * @param {Function} [callback] The function to customize cloning values.
  8987. * @param {*} [thisArg] The `this` binding of `callback`.
  8988. * @returns {*} Returns the deep cloned value.
  8989. * @example
  8990. *
  8991. * var stooges = [
  8992. * { 'name': 'moe', 'age': 40 },
  8993. * { 'name': 'larry', 'age': 50 }
  8994. * ];
  8995. *
  8996. * var deep = _.cloneDeep(stooges);
  8997. * deep[0] === stooges[0];
  8998. * // => false
  8999. *
  9000. * var view = {
  9001. * 'label': 'docs',
  9002. * 'node': element
  9003. * };
  9004. *
  9005. * var clone = _.cloneDeep(view, function(value) {
  9006. * return _.isElement(value) ? value.cloneNode(true) : undefined;
  9007. * });
  9008. *
  9009. * clone.node == view.node;
  9010. * // => false
  9011. */
  9012. function cloneDeep(value, callback, thisArg) {
  9013. return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1));
  9014. }
  9015. /**
  9016. * Assigns own enumerable properties of source object(s) to the destination
  9017. * object for all destination properties that resolve to `undefined`. Once a
  9018. * property is set, additional defaults of the same property will be ignored.
  9019. *
  9020. * @static
  9021. * @memberOf _
  9022. * @type Function
  9023. * @category Objects
  9024. * @param {Object} object The destination object.
  9025. * @param {...Object} [source] The source objects.
  9026. * @param- {Object} [guard] Allows working with `_.reduce` without using its
  9027. * `key` and `object` arguments as sources.
  9028. * @returns {Object} Returns the destination object.
  9029. * @example
  9030. *
  9031. * var food = { 'name': 'apple' };
  9032. * _.defaults(food, { 'name': 'banana', 'type': 'fruit' });
  9033. * // => { 'name': 'apple', 'type': 'fruit' }
  9034. */
  9035. var defaults = function(object, source, guard) {
  9036. var index, iterable = object, result = iterable;
  9037. if (!iterable) return result;
  9038. var args = arguments,
  9039. argsIndex = 0,
  9040. argsLength = typeof guard == 'number' ? 2 : args.length;
  9041. while (++argsIndex < argsLength) {
  9042. iterable = args[argsIndex];
  9043. if (iterable && objectTypes[typeof iterable]) {
  9044. var ownIndex = -1,
  9045. ownProps = objectTypes[typeof iterable] && keys(iterable),
  9046. length = ownProps ? ownProps.length : 0;
  9047. while (++ownIndex < length) {
  9048. index = ownProps[ownIndex];
  9049. if (typeof result[index] == 'undefined') result[index] = iterable[index];
  9050. }
  9051. }
  9052. }
  9053. return result
  9054. };
  9055. /**
  9056. * This method is like `_.findIndex` except that it returns the key of the
  9057. * first element that passes the callback check, instead of the element itself.
  9058. *
  9059. * @static
  9060. * @memberOf _
  9061. * @category Objects
  9062. * @param {Object} object The object to search.
  9063. * @param {Function|Object|string} [callback=identity] The function called per
  9064. * iteration. If a property name or object is provided it will be used to
  9065. * create a "_.pluck" or "_.where" style callback, respectively.
  9066. * @param {*} [thisArg] The `this` binding of `callback`.
  9067. * @returns {string|undefined} Returns the key of the found element, else `undefined`.
  9068. * @example
  9069. *
  9070. * _.findKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
  9071. * return num % 2 == 0;
  9072. * });
  9073. * // => 'b' (property order is not guaranteed across environments)
  9074. */
  9075. function findKey(object, callback, thisArg) {
  9076. var result;
  9077. callback = lodash.createCallback(callback, thisArg, 3);
  9078. forOwn(object, function(value, key, object) {
  9079. if (callback(value, key, object)) {
  9080. result = key;
  9081. return false;
  9082. }
  9083. });
  9084. return result;
  9085. }
  9086. /**
  9087. * This method is like `_.findKey` except that it iterates over elements
  9088. * of a `collection` in the opposite order.
  9089. *
  9090. * @static
  9091. * @memberOf _
  9092. * @category Objects
  9093. * @param {Object} object The object to search.
  9094. * @param {Function|Object|string} [callback=identity] The function called per
  9095. * iteration. If a property name or object is provided it will be used to
  9096. * create a "_.pluck" or "_.where" style callback, respectively.
  9097. * @param {*} [thisArg] The `this` binding of `callback`.
  9098. * @returns {string|undefined} Returns the key of the found element, else `undefined`.
  9099. * @example
  9100. *
  9101. * _.findLastKey({ 'a': 1, 'b': 2, 'c': 3, 'd': 4 }, function(num) {
  9102. * return num % 2 == 1;
  9103. * });
  9104. * // => returns `c`, assuming `_.findKey` returns `a`
  9105. */
  9106. function findLastKey(object, callback, thisArg) {
  9107. var result;
  9108. callback = lodash.createCallback(callback, thisArg, 3);
  9109. forOwnRight(object, function(value, key, object) {
  9110. if (callback(value, key, object)) {
  9111. result = key;
  9112. return false;
  9113. }
  9114. });
  9115. return result;
  9116. }
  9117. /**
  9118. * Iterates over own and inherited enumerable properties of an object,
  9119. * executing the callback for each property. The callback is bound to `thisArg`
  9120. * and invoked with three arguments; (value, key, object). Callbacks may exit
  9121. * iteration early by explicitly returning `false`.
  9122. *
  9123. * @static
  9124. * @memberOf _
  9125. * @type Function
  9126. * @category Objects
  9127. * @param {Object} object The object to iterate over.
  9128. * @param {Function} [callback=identity] The function called per iteration.
  9129. * @param {*} [thisArg] The `this` binding of `callback`.
  9130. * @returns {Object} Returns `object`.
  9131. * @example
  9132. *
  9133. * function Dog(name) {
  9134. * this.name = name;
  9135. * }
  9136. *
  9137. * Dog.prototype.bark = function() {
  9138. * console.log('Woof, woof!');
  9139. * };
  9140. *
  9141. * _.forIn(new Dog('Dagny'), function(value, key) {
  9142. * console.log(key);
  9143. * });
  9144. * // => logs 'bark' and 'name' (property order is not guaranteed across environments)
  9145. */
  9146. var forIn = function(collection, callback, thisArg) {
  9147. var index, iterable = collection, result = iterable;
  9148. if (!iterable) return result;
  9149. if (!objectTypes[typeof iterable]) return result;
  9150. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  9151. for (index in iterable) {
  9152. if (callback(iterable[index], index, collection) === false) return result;
  9153. }
  9154. return result
  9155. };
  9156. /**
  9157. * This method is like `_.forIn` except that it iterates over elements
  9158. * of a `collection` in the opposite order.
  9159. *
  9160. * @static
  9161. * @memberOf _
  9162. * @category Objects
  9163. * @param {Object} object The object to iterate over.
  9164. * @param {Function} [callback=identity] The function called per iteration.
  9165. * @param {*} [thisArg] The `this` binding of `callback`.
  9166. * @returns {Object} Returns `object`.
  9167. * @example
  9168. *
  9169. * function Dog(name) {
  9170. * this.name = name;
  9171. * }
  9172. *
  9173. * Dog.prototype.bark = function() {
  9174. * console.log('Woof, woof!');
  9175. * };
  9176. *
  9177. * _.forInRight(new Dog('Dagny'), function(value, key) {
  9178. * console.log(key);
  9179. * });
  9180. * // => logs 'name' and 'bark' assuming `_.forIn ` logs 'bark' and 'name'
  9181. */
  9182. function forInRight(object, callback, thisArg) {
  9183. var pairs = [];
  9184. forIn(object, function(value, key) {
  9185. pairs.push(key, value);
  9186. });
  9187. var length = pairs.length;
  9188. callback = baseCreateCallback(callback, thisArg, 3);
  9189. while (length--) {
  9190. if (callback(pairs[length--], pairs[length], object) === false) {
  9191. break;
  9192. }
  9193. }
  9194. return object;
  9195. }
  9196. /**
  9197. * Iterates over own enumerable properties of an object, executing the callback
  9198. * for each property. The callback is bound to `thisArg` and invoked with three
  9199. * arguments; (value, key, object). Callbacks may exit iteration early by
  9200. * explicitly returning `false`.
  9201. *
  9202. * @static
  9203. * @memberOf _
  9204. * @type Function
  9205. * @category Objects
  9206. * @param {Object} object The object to iterate over.
  9207. * @param {Function} [callback=identity] The function called per iteration.
  9208. * @param {*} [thisArg] The `this` binding of `callback`.
  9209. * @returns {Object} Returns `object`.
  9210. * @example
  9211. *
  9212. * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  9213. * console.log(key);
  9214. * });
  9215. * // => logs '0', '1', and 'length' (property order is not guaranteed across environments)
  9216. */
  9217. var forOwn = function(collection, callback, thisArg) {
  9218. var index, iterable = collection, result = iterable;
  9219. if (!iterable) return result;
  9220. if (!objectTypes[typeof iterable]) return result;
  9221. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  9222. var ownIndex = -1,
  9223. ownProps = objectTypes[typeof iterable] && keys(iterable),
  9224. length = ownProps ? ownProps.length : 0;
  9225. while (++ownIndex < length) {
  9226. index = ownProps[ownIndex];
  9227. if (callback(iterable[index], index, collection) === false) return result;
  9228. }
  9229. return result
  9230. };
  9231. /**
  9232. * This method is like `_.forOwn` except that it iterates over elements
  9233. * of a `collection` in the opposite order.
  9234. *
  9235. * @static
  9236. * @memberOf _
  9237. * @category Objects
  9238. * @param {Object} object The object to iterate over.
  9239. * @param {Function} [callback=identity] The function called per iteration.
  9240. * @param {*} [thisArg] The `this` binding of `callback`.
  9241. * @returns {Object} Returns `object`.
  9242. * @example
  9243. *
  9244. * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) {
  9245. * console.log(key);
  9246. * });
  9247. * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length'
  9248. */
  9249. function forOwnRight(object, callback, thisArg) {
  9250. var props = keys(object),
  9251. length = props.length;
  9252. callback = baseCreateCallback(callback, thisArg, 3);
  9253. while (length--) {
  9254. var key = props[length];
  9255. if (callback(object[key], key, object) === false) {
  9256. break;
  9257. }
  9258. }
  9259. return object;
  9260. }
  9261. /**
  9262. * Creates a sorted array of property names of all enumerable properties,
  9263. * own and inherited, of `object` that have function values.
  9264. *
  9265. * @static
  9266. * @memberOf _
  9267. * @alias methods
  9268. * @category Objects
  9269. * @param {Object} object The object to inspect.
  9270. * @returns {Array} Returns an array of property names that have function values.
  9271. * @example
  9272. *
  9273. * _.functions(_);
  9274. * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...]
  9275. */
  9276. function functions(object) {
  9277. var result = [];
  9278. forIn(object, function(value, key) {
  9279. if (isFunction(value)) {
  9280. result.push(key);
  9281. }
  9282. });
  9283. return result.sort();
  9284. }
  9285. /**
  9286. * Checks if the specified object `property` exists and is a direct property,
  9287. * instead of an inherited property.
  9288. *
  9289. * @static
  9290. * @memberOf _
  9291. * @category Objects
  9292. * @param {Object} object The object to check.
  9293. * @param {string} property The property to check for.
  9294. * @returns {boolean} Returns `true` if key is a direct property, else `false`.
  9295. * @example
  9296. *
  9297. * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b');
  9298. * // => true
  9299. */
  9300. function has(object, property) {
  9301. return object ? hasOwnProperty.call(object, property) : false;
  9302. }
  9303. /**
  9304. * Creates an object composed of the inverted keys and values of the given object.
  9305. *
  9306. * @static
  9307. * @memberOf _
  9308. * @category Objects
  9309. * @param {Object} object The object to invert.
  9310. * @returns {Object} Returns the created inverted object.
  9311. * @example
  9312. *
  9313. * _.invert({ 'first': 'moe', 'second': 'larry' });
  9314. * // => { 'moe': 'first', 'larry': 'second' }
  9315. */
  9316. function invert(object) {
  9317. var index = -1,
  9318. props = keys(object),
  9319. length = props.length,
  9320. result = {};
  9321. while (++index < length) {
  9322. var key = props[index];
  9323. result[object[key]] = key;
  9324. }
  9325. return result;
  9326. }
  9327. /**
  9328. * Checks if `value` is a boolean value.
  9329. *
  9330. * @static
  9331. * @memberOf _
  9332. * @category Objects
  9333. * @param {*} value The value to check.
  9334. * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`.
  9335. * @example
  9336. *
  9337. * _.isBoolean(null);
  9338. * // => false
  9339. */
  9340. function isBoolean(value) {
  9341. return value === true || value === false || toString.call(value) == boolClass;
  9342. }
  9343. /**
  9344. * Checks if `value` is a date.
  9345. *
  9346. * @static
  9347. * @memberOf _
  9348. * @category Objects
  9349. * @param {*} value The value to check.
  9350. * @returns {boolean} Returns `true` if the `value` is a date, else `false`.
  9351. * @example
  9352. *
  9353. * _.isDate(new Date);
  9354. * // => true
  9355. */
  9356. function isDate(value) {
  9357. return value ? (typeof value == 'object' && toString.call(value) == dateClass) : false;
  9358. }
  9359. /**
  9360. * Checks if `value` is a DOM element.
  9361. *
  9362. * @static
  9363. * @memberOf _
  9364. * @category Objects
  9365. * @param {*} value The value to check.
  9366. * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`.
  9367. * @example
  9368. *
  9369. * _.isElement(document.body);
  9370. * // => true
  9371. */
  9372. function isElement(value) {
  9373. return value ? value.nodeType === 1 : false;
  9374. }
  9375. /**
  9376. * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
  9377. * length of `0` and objects with no own enumerable properties are considered
  9378. * "empty".
  9379. *
  9380. * @static
  9381. * @memberOf _
  9382. * @category Objects
  9383. * @param {Array|Object|string} value The value to inspect.
  9384. * @returns {boolean} Returns `true` if the `value` is empty, else `false`.
  9385. * @example
  9386. *
  9387. * _.isEmpty([1, 2, 3]);
  9388. * // => false
  9389. *
  9390. * _.isEmpty({});
  9391. * // => true
  9392. *
  9393. * _.isEmpty('');
  9394. * // => true
  9395. */
  9396. function isEmpty(value) {
  9397. var result = true;
  9398. if (!value) {
  9399. return result;
  9400. }
  9401. var className = toString.call(value),
  9402. length = value.length;
  9403. if ((className == arrayClass || className == stringClass || className == argsClass ) ||
  9404. (className == objectClass && typeof length == 'number' && isFunction(value.splice))) {
  9405. return !length;
  9406. }
  9407. forOwn(value, function() {
  9408. return (result = false);
  9409. });
  9410. return result;
  9411. }
  9412. /**
  9413. * Performs a deep comparison between two values to determine if they are
  9414. * equivalent to each other. If a callback is provided it will be executed
  9415. * to compare values. If the callback returns `undefined` comparisons will
  9416. * be handled by the method instead. The callback is bound to `thisArg` and
  9417. * invoked with two arguments; (a, b).
  9418. *
  9419. * @static
  9420. * @memberOf _
  9421. * @category Objects
  9422. * @param {*} a The value to compare.
  9423. * @param {*} b The other value to compare.
  9424. * @param {Function} [callback] The function to customize comparing values.
  9425. * @param {*} [thisArg] The `this` binding of `callback`.
  9426. * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
  9427. * @example
  9428. *
  9429. * var moe = { 'name': 'moe', 'age': 40 };
  9430. * var copy = { 'name': 'moe', 'age': 40 };
  9431. *
  9432. * moe == copy;
  9433. * // => false
  9434. *
  9435. * _.isEqual(moe, copy);
  9436. * // => true
  9437. *
  9438. * var words = ['hello', 'goodbye'];
  9439. * var otherWords = ['hi', 'goodbye'];
  9440. *
  9441. * _.isEqual(words, otherWords, function(a, b) {
  9442. * var reGreet = /^(?:hello|hi)$/i,
  9443. * aGreet = _.isString(a) && reGreet.test(a),
  9444. * bGreet = _.isString(b) && reGreet.test(b);
  9445. *
  9446. * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined;
  9447. * });
  9448. * // => true
  9449. */
  9450. function isEqual(a, b, callback, thisArg) {
  9451. return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2));
  9452. }
  9453. /**
  9454. * Checks if `value` is, or can be coerced to, a finite number.
  9455. *
  9456. * Note: This is not the same as native `isFinite` which will return true for
  9457. * booleans and empty strings. See http://es5.github.io/#x15.1.2.5.
  9458. *
  9459. * @static
  9460. * @memberOf _
  9461. * @category Objects
  9462. * @param {*} value The value to check.
  9463. * @returns {boolean} Returns `true` if the `value` is finite, else `false`.
  9464. * @example
  9465. *
  9466. * _.isFinite(-101);
  9467. * // => true
  9468. *
  9469. * _.isFinite('10');
  9470. * // => true
  9471. *
  9472. * _.isFinite(true);
  9473. * // => false
  9474. *
  9475. * _.isFinite('');
  9476. * // => false
  9477. *
  9478. * _.isFinite(Infinity);
  9479. * // => false
  9480. */
  9481. function isFinite(value) {
  9482. return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value));
  9483. }
  9484. /**
  9485. * Checks if `value` is a function.
  9486. *
  9487. * @static
  9488. * @memberOf _
  9489. * @category Objects
  9490. * @param {*} value The value to check.
  9491. * @returns {boolean} Returns `true` if the `value` is a function, else `false`.
  9492. * @example
  9493. *
  9494. * _.isFunction(_);
  9495. * // => true
  9496. */
  9497. function isFunction(value) {
  9498. return typeof value == 'function';
  9499. }
  9500. /**
  9501. * Checks if `value` is the language type of Object.
  9502. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
  9503. *
  9504. * @static
  9505. * @memberOf _
  9506. * @category Objects
  9507. * @param {*} value The value to check.
  9508. * @returns {boolean} Returns `true` if the `value` is an object, else `false`.
  9509. * @example
  9510. *
  9511. * _.isObject({});
  9512. * // => true
  9513. *
  9514. * _.isObject([1, 2, 3]);
  9515. * // => true
  9516. *
  9517. * _.isObject(1);
  9518. * // => false
  9519. */
  9520. function isObject(value) {
  9521. // check if the value is the ECMAScript language type of Object
  9522. // http://es5.github.io/#x8
  9523. // and avoid a V8 bug
  9524. // http://code.google.com/p/v8/issues/detail?id=2291
  9525. return !!(value && objectTypes[typeof value]);
  9526. }
  9527. /**
  9528. * Checks if `value` is `NaN`.
  9529. *
  9530. * Note: This is not the same as native `isNaN` which will return `true` for
  9531. * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4.
  9532. *
  9533. * @static
  9534. * @memberOf _
  9535. * @category Objects
  9536. * @param {*} value The value to check.
  9537. * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`.
  9538. * @example
  9539. *
  9540. * _.isNaN(NaN);
  9541. * // => true
  9542. *
  9543. * _.isNaN(new Number(NaN));
  9544. * // => true
  9545. *
  9546. * isNaN(undefined);
  9547. * // => true
  9548. *
  9549. * _.isNaN(undefined);
  9550. * // => false
  9551. */
  9552. function isNaN(value) {
  9553. // `NaN` as a primitive is the only value that is not equal to itself
  9554. // (perform the [[Class]] check first to avoid errors with some host objects in IE)
  9555. return isNumber(value) && value != +value;
  9556. }
  9557. /**
  9558. * Checks if `value` is `null`.
  9559. *
  9560. * @static
  9561. * @memberOf _
  9562. * @category Objects
  9563. * @param {*} value The value to check.
  9564. * @returns {boolean} Returns `true` if the `value` is `null`, else `false`.
  9565. * @example
  9566. *
  9567. * _.isNull(null);
  9568. * // => true
  9569. *
  9570. * _.isNull(undefined);
  9571. * // => false
  9572. */
  9573. function isNull(value) {
  9574. return value === null;
  9575. }
  9576. /**
  9577. * Checks if `value` is a number.
  9578. *
  9579. * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5.
  9580. *
  9581. * @static
  9582. * @memberOf _
  9583. * @category Objects
  9584. * @param {*} value The value to check.
  9585. * @returns {boolean} Returns `true` if the `value` is a number, else `false`.
  9586. * @example
  9587. *
  9588. * _.isNumber(8.4 * 5);
  9589. * // => true
  9590. */
  9591. function isNumber(value) {
  9592. return typeof value == 'number' || toString.call(value) == numberClass;
  9593. }
  9594. /**
  9595. * Checks if `value` is an object created by the `Object` constructor.
  9596. *
  9597. * @static
  9598. * @memberOf _
  9599. * @category Objects
  9600. * @param {*} value The value to check.
  9601. * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
  9602. * @example
  9603. *
  9604. * function Stooge(name, age) {
  9605. * this.name = name;
  9606. * this.age = age;
  9607. * }
  9608. *
  9609. * _.isPlainObject(new Stooge('moe', 40));
  9610. * // => false
  9611. *
  9612. * _.isPlainObject([1, 2, 3]);
  9613. * // => false
  9614. *
  9615. * _.isPlainObject({ 'name': 'moe', 'age': 40 });
  9616. * // => true
  9617. */
  9618. var isPlainObject = function(value) {
  9619. if (!(value && toString.call(value) == objectClass)) {
  9620. return false;
  9621. }
  9622. var valueOf = value.valueOf,
  9623. objProto = typeof valueOf == 'function' && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto);
  9624. return objProto
  9625. ? (value == objProto || getPrototypeOf(value) == objProto)
  9626. : shimIsPlainObject(value);
  9627. };
  9628. /**
  9629. * Checks if `value` is a regular expression.
  9630. *
  9631. * @static
  9632. * @memberOf _
  9633. * @category Objects
  9634. * @param {*} value The value to check.
  9635. * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`.
  9636. * @example
  9637. *
  9638. * _.isRegExp(/moe/);
  9639. * // => true
  9640. */
  9641. function isRegExp(value) {
  9642. return value ? (typeof value == 'object' && toString.call(value) == regexpClass) : false;
  9643. }
  9644. /**
  9645. * Checks if `value` is a string.
  9646. *
  9647. * @static
  9648. * @memberOf _
  9649. * @category Objects
  9650. * @param {*} value The value to check.
  9651. * @returns {boolean} Returns `true` if the `value` is a string, else `false`.
  9652. * @example
  9653. *
  9654. * _.isString('moe');
  9655. * // => true
  9656. */
  9657. function isString(value) {
  9658. return typeof value == 'string' || toString.call(value) == stringClass;
  9659. }
  9660. /**
  9661. * Checks if `value` is `undefined`.
  9662. *
  9663. * @static
  9664. * @memberOf _
  9665. * @category Objects
  9666. * @param {*} value The value to check.
  9667. * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`.
  9668. * @example
  9669. *
  9670. * _.isUndefined(void 0);
  9671. * // => true
  9672. */
  9673. function isUndefined(value) {
  9674. return typeof value == 'undefined';
  9675. }
  9676. /**
  9677. * Recursively merges own enumerable properties of the source object(s), that
  9678. * don't resolve to `undefined` into the destination object. Subsequent sources
  9679. * will overwrite property assignments of previous sources. If a callback is
  9680. * provided it will be executed to produce the merged values of the destination
  9681. * and source properties. If the callback returns `undefined` merging will
  9682. * be handled by the method instead. The callback is bound to `thisArg` and
  9683. * invoked with two arguments; (objectValue, sourceValue).
  9684. *
  9685. * @static
  9686. * @memberOf _
  9687. * @category Objects
  9688. * @param {Object} object The destination object.
  9689. * @param {...Object} [source] The source objects.
  9690. * @param {Function} [callback] The function to customize merging properties.
  9691. * @param {*} [thisArg] The `this` binding of `callback`.
  9692. * @returns {Object} Returns the destination object.
  9693. * @example
  9694. *
  9695. * var names = {
  9696. * 'stooges': [
  9697. * { 'name': 'moe' },
  9698. * { 'name': 'larry' }
  9699. * ]
  9700. * };
  9701. *
  9702. * var ages = {
  9703. * 'stooges': [
  9704. * { 'age': 40 },
  9705. * { 'age': 50 }
  9706. * ]
  9707. * };
  9708. *
  9709. * _.merge(names, ages);
  9710. * // => { 'stooges': [{ 'name': 'moe', 'age': 40 }, { 'name': 'larry', 'age': 50 }] }
  9711. *
  9712. * var food = {
  9713. * 'fruits': ['apple'],
  9714. * 'vegetables': ['beet']
  9715. * };
  9716. *
  9717. * var otherFood = {
  9718. * 'fruits': ['banana'],
  9719. * 'vegetables': ['carrot']
  9720. * };
  9721. *
  9722. * _.merge(food, otherFood, function(a, b) {
  9723. * return _.isArray(a) ? a.concat(b) : undefined;
  9724. * });
  9725. * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] }
  9726. */
  9727. function merge(object) {
  9728. var args = arguments,
  9729. length = 2;
  9730. if (!isObject(object)) {
  9731. return object;
  9732. }
  9733. // allows working with `_.reduce` and `_.reduceRight` without using
  9734. // their `index` and `collection` arguments
  9735. if (typeof args[2] != 'number') {
  9736. length = args.length;
  9737. }
  9738. if (length > 3 && typeof args[length - 2] == 'function') {
  9739. var callback = baseCreateCallback(args[--length - 1], args[length--], 2);
  9740. } else if (length > 2 && typeof args[length - 1] == 'function') {
  9741. callback = args[--length];
  9742. }
  9743. var sources = nativeSlice.call(arguments, 1, length),
  9744. index = -1,
  9745. stackA = getArray(),
  9746. stackB = getArray();
  9747. while (++index < length) {
  9748. baseMerge(object, sources[index], callback, stackA, stackB);
  9749. }
  9750. releaseArray(stackA);
  9751. releaseArray(stackB);
  9752. return object;
  9753. }
  9754. /**
  9755. * Creates a shallow clone of `object` excluding the specified properties.
  9756. * Property names may be specified as individual arguments or as arrays of
  9757. * property names. If a callback is provided it will be executed for each
  9758. * property of `object` omitting the properties the callback returns truey
  9759. * for. The callback is bound to `thisArg` and invoked with three arguments;
  9760. * (value, key, object).
  9761. *
  9762. * @static
  9763. * @memberOf _
  9764. * @category Objects
  9765. * @param {Object} object The source object.
  9766. * @param {Function|...string|string[]} [callback] The properties to omit or the
  9767. * function called per iteration.
  9768. * @param {*} [thisArg] The `this` binding of `callback`.
  9769. * @returns {Object} Returns an object without the omitted properties.
  9770. * @example
  9771. *
  9772. * _.omit({ 'name': 'moe', 'age': 40 }, 'age');
  9773. * // => { 'name': 'moe' }
  9774. *
  9775. * _.omit({ 'name': 'moe', 'age': 40 }, function(value) {
  9776. * return typeof value == 'number';
  9777. * });
  9778. * // => { 'name': 'moe' }
  9779. */
  9780. function omit(object, callback, thisArg) {
  9781. var indexOf = getIndexOf(),
  9782. isFunc = typeof callback == 'function',
  9783. result = {};
  9784. if (isFunc) {
  9785. callback = lodash.createCallback(callback, thisArg, 3);
  9786. } else {
  9787. var props = baseFlatten(arguments, true, false, 1);
  9788. }
  9789. forIn(object, function(value, key, object) {
  9790. if (isFunc
  9791. ? !callback(value, key, object)
  9792. : indexOf(props, key) < 0
  9793. ) {
  9794. result[key] = value;
  9795. }
  9796. });
  9797. return result;
  9798. }
  9799. /**
  9800. * Creates a two dimensional array of an object's key-value pairs,
  9801. * i.e. `[[key1, value1], [key2, value2]]`.
  9802. *
  9803. * @static
  9804. * @memberOf _
  9805. * @category Objects
  9806. * @param {Object} object The object to inspect.
  9807. * @returns {Array} Returns new array of key-value pairs.
  9808. * @example
  9809. *
  9810. * _.pairs({ 'moe': 30, 'larry': 40 });
  9811. * // => [['moe', 30], ['larry', 40]] (property order is not guaranteed across environments)
  9812. */
  9813. function pairs(object) {
  9814. var index = -1,
  9815. props = keys(object),
  9816. length = props.length,
  9817. result = Array(length);
  9818. while (++index < length) {
  9819. var key = props[index];
  9820. result[index] = [key, object[key]];
  9821. }
  9822. return result;
  9823. }
  9824. /**
  9825. * Creates a shallow clone of `object` composed of the specified properties.
  9826. * Property names may be specified as individual arguments or as arrays of
  9827. * property names. If a callback is provided it will be executed for each
  9828. * property of `object` picking the properties the callback returns truey
  9829. * for. The callback is bound to `thisArg` and invoked with three arguments;
  9830. * (value, key, object).
  9831. *
  9832. * @static
  9833. * @memberOf _
  9834. * @category Objects
  9835. * @param {Object} object The source object.
  9836. * @param {Function|...string|string[]} [callback] The function called per
  9837. * iteration or property names to pick, specified as individual property
  9838. * names or arrays of property names.
  9839. * @param {*} [thisArg] The `this` binding of `callback`.
  9840. * @returns {Object} Returns an object composed of the picked properties.
  9841. * @example
  9842. *
  9843. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, 'name');
  9844. * // => { 'name': 'moe' }
  9845. *
  9846. * _.pick({ 'name': 'moe', '_userid': 'moe1' }, function(value, key) {
  9847. * return key.charAt(0) != '_';
  9848. * });
  9849. * // => { 'name': 'moe' }
  9850. */
  9851. function pick(object, callback, thisArg) {
  9852. var result = {};
  9853. if (typeof callback != 'function') {
  9854. var index = -1,
  9855. props = baseFlatten(arguments, true, false, 1),
  9856. length = isObject(object) ? props.length : 0;
  9857. while (++index < length) {
  9858. var key = props[index];
  9859. if (key in object) {
  9860. result[key] = object[key];
  9861. }
  9862. }
  9863. } else {
  9864. callback = lodash.createCallback(callback, thisArg, 3);
  9865. forIn(object, function(value, key, object) {
  9866. if (callback(value, key, object)) {
  9867. result[key] = value;
  9868. }
  9869. });
  9870. }
  9871. return result;
  9872. }
  9873. /**
  9874. * An alternative to `_.reduce` this method transforms `object` to a new
  9875. * `accumulator` object which is the result of running each of its elements
  9876. * through a callback, with each callback execution potentially mutating
  9877. * the `accumulator` object. The callback is bound to `thisArg` and invoked
  9878. * with four arguments; (accumulator, value, key, object). Callbacks may exit
  9879. * iteration early by explicitly returning `false`.
  9880. *
  9881. * @static
  9882. * @memberOf _
  9883. * @category Objects
  9884. * @param {Array|Object} collection The collection to iterate over.
  9885. * @param {Function} [callback=identity] The function called per iteration.
  9886. * @param {*} [accumulator] The custom accumulator value.
  9887. * @param {*} [thisArg] The `this` binding of `callback`.
  9888. * @returns {*} Returns the accumulated value.
  9889. * @example
  9890. *
  9891. * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) {
  9892. * num *= num;
  9893. * if (num % 2) {
  9894. * return result.push(num) < 3;
  9895. * }
  9896. * });
  9897. * // => [1, 9, 25]
  9898. *
  9899. * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  9900. * result[key] = num * 3;
  9901. * });
  9902. * // => { 'a': 3, 'b': 6, 'c': 9 }
  9903. */
  9904. function transform(object, callback, accumulator, thisArg) {
  9905. var isArr = isArray(object);
  9906. callback = baseCreateCallback(callback, thisArg, 4);
  9907. if (accumulator == null) {
  9908. if (isArr) {
  9909. accumulator = [];
  9910. } else {
  9911. var ctor = object && object.constructor,
  9912. proto = ctor && ctor.prototype;
  9913. accumulator = createObject(proto);
  9914. }
  9915. }
  9916. (isArr ? forEach : forOwn)(object, function(value, index, object) {
  9917. return callback(accumulator, value, index, object);
  9918. });
  9919. return accumulator;
  9920. }
  9921. /**
  9922. * Creates an array composed of the own enumerable property values of `object`.
  9923. *
  9924. * @static
  9925. * @memberOf _
  9926. * @category Objects
  9927. * @param {Object} object The object to inspect.
  9928. * @returns {Array} Returns an array of property values.
  9929. * @example
  9930. *
  9931. * _.values({ 'one': 1, 'two': 2, 'three': 3 });
  9932. * // => [1, 2, 3] (property order is not guaranteed across environments)
  9933. */
  9934. function values(object) {
  9935. var index = -1,
  9936. props = keys(object),
  9937. length = props.length,
  9938. result = Array(length);
  9939. while (++index < length) {
  9940. result[index] = object[props[index]];
  9941. }
  9942. return result;
  9943. }
  9944. /*--------------------------------------------------------------------------*/
  9945. /**
  9946. * Creates an array of elements from the specified indexes, or keys, of the
  9947. * `collection`. Indexes may be specified as individual arguments or as arrays
  9948. * of indexes.
  9949. *
  9950. * @static
  9951. * @memberOf _
  9952. * @category Collections
  9953. * @param {Array|Object|string} collection The collection to iterate over.
  9954. * @param {...(number|number[]|string|string[])} [index] The indexes of `collection`
  9955. * to retrieve, specified as individual indexes or arrays of indexes.
  9956. * @returns {Array} Returns a new array of elements corresponding to the
  9957. * provided indexes.
  9958. * @example
  9959. *
  9960. * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]);
  9961. * // => ['a', 'c', 'e']
  9962. *
  9963. * _.at(['moe', 'larry', 'curly'], 0, 2);
  9964. * // => ['moe', 'curly']
  9965. */
  9966. function at(collection) {
  9967. var args = arguments,
  9968. index = -1,
  9969. props = baseFlatten(args, true, false, 1),
  9970. length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length,
  9971. result = Array(length);
  9972. while(++index < length) {
  9973. result[index] = collection[props[index]];
  9974. }
  9975. return result;
  9976. }
  9977. /**
  9978. * Checks if a given value is present in a collection using strict equality
  9979. * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the
  9980. * offset from the end of the collection.
  9981. *
  9982. * @static
  9983. * @memberOf _
  9984. * @alias include
  9985. * @category Collections
  9986. * @param {Array|Object|string} collection The collection to iterate over.
  9987. * @param {*} target The value to check for.
  9988. * @param {number} [fromIndex=0] The index to search from.
  9989. * @returns {boolean} Returns `true` if the `target` element is found, else `false`.
  9990. * @example
  9991. *
  9992. * _.contains([1, 2, 3], 1);
  9993. * // => true
  9994. *
  9995. * _.contains([1, 2, 3], 1, 2);
  9996. * // => false
  9997. *
  9998. * _.contains({ 'name': 'moe', 'age': 40 }, 'moe');
  9999. * // => true
  10000. *
  10001. * _.contains('curly', 'ur');
  10002. * // => true
  10003. */
  10004. function contains(collection, target, fromIndex) {
  10005. var index = -1,
  10006. indexOf = getIndexOf(),
  10007. length = collection ? collection.length : 0,
  10008. result = false;
  10009. fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0;
  10010. if (isArray(collection)) {
  10011. result = indexOf(collection, target, fromIndex) > -1;
  10012. } else if (typeof length == 'number') {
  10013. result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1;
  10014. } else {
  10015. forOwn(collection, function(value) {
  10016. if (++index >= fromIndex) {
  10017. return !(result = value === target);
  10018. }
  10019. });
  10020. }
  10021. return result;
  10022. }
  10023. /**
  10024. * Creates an object composed of keys generated from the results of running
  10025. * each element of `collection` through the callback. The corresponding value
  10026. * of each key is the number of times the key was returned by the callback.
  10027. * The callback is bound to `thisArg` and invoked with three arguments;
  10028. * (value, index|key, collection).
  10029. *
  10030. * If a property name is provided for `callback` the created "_.pluck" style
  10031. * callback will return the property value of the given element.
  10032. *
  10033. * If an object is provided for `callback` the created "_.where" style callback
  10034. * will return `true` for elements that have the properties of the given object,
  10035. * else `false`.
  10036. *
  10037. * @static
  10038. * @memberOf _
  10039. * @category Collections
  10040. * @param {Array|Object|string} collection The collection to iterate over.
  10041. * @param {Function|Object|string} [callback=identity] The function called
  10042. * per iteration. If a property name or object is provided it will be used
  10043. * to create a "_.pluck" or "_.where" style callback, respectively.
  10044. * @param {*} [thisArg] The `this` binding of `callback`.
  10045. * @returns {Object} Returns the composed aggregate object.
  10046. * @example
  10047. *
  10048. * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); });
  10049. * // => { '4': 1, '6': 2 }
  10050. *
  10051. * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  10052. * // => { '4': 1, '6': 2 }
  10053. *
  10054. * _.countBy(['one', 'two', 'three'], 'length');
  10055. * // => { '3': 2, '5': 1 }
  10056. */
  10057. var countBy = createAggregator(function(result, value, key) {
  10058. (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1);
  10059. });
  10060. /**
  10061. * Checks if the given callback returns truey value for **all** elements of
  10062. * a collection. The callback is bound to `thisArg` and invoked with three
  10063. * arguments; (value, index|key, collection).
  10064. *
  10065. * If a property name is provided for `callback` the created "_.pluck" style
  10066. * callback will return the property value of the given element.
  10067. *
  10068. * If an object is provided for `callback` the created "_.where" style callback
  10069. * will return `true` for elements that have the properties of the given object,
  10070. * else `false`.
  10071. *
  10072. * @static
  10073. * @memberOf _
  10074. * @alias all
  10075. * @category Collections
  10076. * @param {Array|Object|string} collection The collection to iterate over.
  10077. * @param {Function|Object|string} [callback=identity] The function called
  10078. * per iteration. If a property name or object is provided it will be used
  10079. * to create a "_.pluck" or "_.where" style callback, respectively.
  10080. * @param {*} [thisArg] The `this` binding of `callback`.
  10081. * @returns {boolean} Returns `true` if all elements passed the callback check,
  10082. * else `false`.
  10083. * @example
  10084. *
  10085. * _.every([true, 1, null, 'yes'], Boolean);
  10086. * // => false
  10087. *
  10088. * var stooges = [
  10089. * { 'name': 'moe', 'age': 40 },
  10090. * { 'name': 'larry', 'age': 50 }
  10091. * ];
  10092. *
  10093. * // using "_.pluck" callback shorthand
  10094. * _.every(stooges, 'age');
  10095. * // => true
  10096. *
  10097. * // using "_.where" callback shorthand
  10098. * _.every(stooges, { 'age': 50 });
  10099. * // => false
  10100. */
  10101. function every(collection, callback, thisArg) {
  10102. var result = true;
  10103. callback = lodash.createCallback(callback, thisArg, 3);
  10104. var index = -1,
  10105. length = collection ? collection.length : 0;
  10106. if (typeof length == 'number') {
  10107. while (++index < length) {
  10108. if (!(result = !!callback(collection[index], index, collection))) {
  10109. break;
  10110. }
  10111. }
  10112. } else {
  10113. forOwn(collection, function(value, index, collection) {
  10114. return (result = !!callback(value, index, collection));
  10115. });
  10116. }
  10117. return result;
  10118. }
  10119. /**
  10120. * Iterates over elements of a collection, returning an array of all elements
  10121. * the callback returns truey for. The callback is bound to `thisArg` and
  10122. * invoked with three arguments; (value, index|key, collection).
  10123. *
  10124. * If a property name is provided for `callback` the created "_.pluck" style
  10125. * callback will return the property value of the given element.
  10126. *
  10127. * If an object is provided for `callback` the created "_.where" style callback
  10128. * will return `true` for elements that have the properties of the given object,
  10129. * else `false`.
  10130. *
  10131. * @static
  10132. * @memberOf _
  10133. * @alias select
  10134. * @category Collections
  10135. * @param {Array|Object|string} collection The collection to iterate over.
  10136. * @param {Function|Object|string} [callback=identity] The function called
  10137. * per iteration. If a property name or object is provided it will be used
  10138. * to create a "_.pluck" or "_.where" style callback, respectively.
  10139. * @param {*} [thisArg] The `this` binding of `callback`.
  10140. * @returns {Array} Returns a new array of elements that passed the callback check.
  10141. * @example
  10142. *
  10143. * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  10144. * // => [2, 4, 6]
  10145. *
  10146. * var food = [
  10147. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  10148. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  10149. * ];
  10150. *
  10151. * // using "_.pluck" callback shorthand
  10152. * _.filter(food, 'organic');
  10153. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  10154. *
  10155. * // using "_.where" callback shorthand
  10156. * _.filter(food, { 'type': 'fruit' });
  10157. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  10158. */
  10159. function filter(collection, callback, thisArg) {
  10160. var result = [];
  10161. callback = lodash.createCallback(callback, thisArg, 3);
  10162. var index = -1,
  10163. length = collection ? collection.length : 0;
  10164. if (typeof length == 'number') {
  10165. while (++index < length) {
  10166. var value = collection[index];
  10167. if (callback(value, index, collection)) {
  10168. result.push(value);
  10169. }
  10170. }
  10171. } else {
  10172. forOwn(collection, function(value, index, collection) {
  10173. if (callback(value, index, collection)) {
  10174. result.push(value);
  10175. }
  10176. });
  10177. }
  10178. return result;
  10179. }
  10180. /**
  10181. * Iterates over elements of a collection, returning the first element that
  10182. * the callback returns truey for. The callback is bound to `thisArg` and
  10183. * invoked with three arguments; (value, index|key, collection).
  10184. *
  10185. * If a property name is provided for `callback` the created "_.pluck" style
  10186. * callback will return the property value of the given element.
  10187. *
  10188. * If an object is provided for `callback` the created "_.where" style callback
  10189. * will return `true` for elements that have the properties of the given object,
  10190. * else `false`.
  10191. *
  10192. * @static
  10193. * @memberOf _
  10194. * @alias detect, findWhere
  10195. * @category Collections
  10196. * @param {Array|Object|string} collection The collection to iterate over.
  10197. * @param {Function|Object|string} [callback=identity] The function called
  10198. * per iteration. If a property name or object is provided it will be used
  10199. * to create a "_.pluck" or "_.where" style callback, respectively.
  10200. * @param {*} [thisArg] The `this` binding of `callback`.
  10201. * @returns {*} Returns the found element, else `undefined`.
  10202. * @example
  10203. *
  10204. * _.find([1, 2, 3, 4], function(num) {
  10205. * return num % 2 == 0;
  10206. * });
  10207. * // => 2
  10208. *
  10209. * var food = [
  10210. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  10211. * { 'name': 'banana', 'organic': true, 'type': 'fruit' },
  10212. * { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  10213. * ];
  10214. *
  10215. * // using "_.where" callback shorthand
  10216. * _.find(food, { 'type': 'vegetable' });
  10217. * // => { 'name': 'beet', 'organic': false, 'type': 'vegetable' }
  10218. *
  10219. * // using "_.pluck" callback shorthand
  10220. * _.find(food, 'organic');
  10221. * // => { 'name': 'banana', 'organic': true, 'type': 'fruit' }
  10222. */
  10223. function find(collection, callback, thisArg) {
  10224. callback = lodash.createCallback(callback, thisArg, 3);
  10225. var index = -1,
  10226. length = collection ? collection.length : 0;
  10227. if (typeof length == 'number') {
  10228. while (++index < length) {
  10229. var value = collection[index];
  10230. if (callback(value, index, collection)) {
  10231. return value;
  10232. }
  10233. }
  10234. } else {
  10235. var result;
  10236. forOwn(collection, function(value, index, collection) {
  10237. if (callback(value, index, collection)) {
  10238. result = value;
  10239. return false;
  10240. }
  10241. });
  10242. return result;
  10243. }
  10244. }
  10245. /**
  10246. * This method is like `_.find` except that it iterates over elements
  10247. * of a `collection` from right to left.
  10248. *
  10249. * @static
  10250. * @memberOf _
  10251. * @category Collections
  10252. * @param {Array|Object|string} collection The collection to iterate over.
  10253. * @param {Function|Object|string} [callback=identity] The function called
  10254. * per iteration. If a property name or object is provided it will be used
  10255. * to create a "_.pluck" or "_.where" style callback, respectively.
  10256. * @param {*} [thisArg] The `this` binding of `callback`.
  10257. * @returns {*} Returns the found element, else `undefined`.
  10258. * @example
  10259. *
  10260. * _.findLast([1, 2, 3, 4], function(num) {
  10261. * return num % 2 == 1;
  10262. * });
  10263. * // => 3
  10264. */
  10265. function findLast(collection, callback, thisArg) {
  10266. var result;
  10267. callback = lodash.createCallback(callback, thisArg, 3);
  10268. forEachRight(collection, function(value, index, collection) {
  10269. if (callback(value, index, collection)) {
  10270. result = value;
  10271. return false;
  10272. }
  10273. });
  10274. return result;
  10275. }
  10276. /**
  10277. * Iterates over elements of a collection, executing the callback for each
  10278. * element. The callback is bound to `thisArg` and invoked with three arguments;
  10279. * (value, index|key, collection). Callbacks may exit iteration early by
  10280. * explicitly returning `false`.
  10281. *
  10282. * @static
  10283. * @memberOf _
  10284. * @alias each
  10285. * @category Collections
  10286. * @param {Array|Object|string} collection The collection to iterate over.
  10287. * @param {Function} [callback=identity] The function called per iteration.
  10288. * @param {*} [thisArg] The `this` binding of `callback`.
  10289. * @returns {Array|Object|string} Returns `collection`.
  10290. * @example
  10291. *
  10292. * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
  10293. * // => logs each number and returns '1,2,3'
  10294. *
  10295. * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
  10296. * // => logs each number and returns the object (property order is not guaranteed across environments)
  10297. */
  10298. function forEach(collection, callback, thisArg) {
  10299. var index = -1,
  10300. length = collection ? collection.length : 0;
  10301. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  10302. if (typeof length == 'number') {
  10303. while (++index < length) {
  10304. if (callback(collection[index], index, collection) === false) {
  10305. break;
  10306. }
  10307. }
  10308. } else {
  10309. forOwn(collection, callback);
  10310. }
  10311. return collection;
  10312. }
  10313. /**
  10314. * This method is like `_.forEach` except that it iterates over elements
  10315. * of a `collection` from right to left.
  10316. *
  10317. * @static
  10318. * @memberOf _
  10319. * @alias eachRight
  10320. * @category Collections
  10321. * @param {Array|Object|string} collection The collection to iterate over.
  10322. * @param {Function} [callback=identity] The function called per iteration.
  10323. * @param {*} [thisArg] The `this` binding of `callback`.
  10324. * @returns {Array|Object|string} Returns `collection`.
  10325. * @example
  10326. *
  10327. * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(',');
  10328. * // => logs each number from right to left and returns '3,2,1'
  10329. */
  10330. function forEachRight(collection, callback, thisArg) {
  10331. var length = collection ? collection.length : 0;
  10332. callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3);
  10333. if (typeof length == 'number') {
  10334. while (length--) {
  10335. if (callback(collection[length], length, collection) === false) {
  10336. break;
  10337. }
  10338. }
  10339. } else {
  10340. var props = keys(collection);
  10341. length = props.length;
  10342. forOwn(collection, function(value, key, collection) {
  10343. key = props ? props[--length] : --length;
  10344. return callback(collection[key], key, collection);
  10345. });
  10346. }
  10347. return collection;
  10348. }
  10349. /**
  10350. * Creates an object composed of keys generated from the results of running
  10351. * each element of a collection through the callback. The corresponding value
  10352. * of each key is an array of the elements responsible for generating the key.
  10353. * The callback is bound to `thisArg` and invoked with three arguments;
  10354. * (value, index|key, collection).
  10355. *
  10356. * If a property name is provided for `callback` the created "_.pluck" style
  10357. * callback will return the property value of the given element.
  10358. *
  10359. * If an object is provided for `callback` the created "_.where" style callback
  10360. * will return `true` for elements that have the properties of the given object,
  10361. * else `false`
  10362. *
  10363. * @static
  10364. * @memberOf _
  10365. * @category Collections
  10366. * @param {Array|Object|string} collection The collection to iterate over.
  10367. * @param {Function|Object|string} [callback=identity] The function called
  10368. * per iteration. If a property name or object is provided it will be used
  10369. * to create a "_.pluck" or "_.where" style callback, respectively.
  10370. * @param {*} [thisArg] The `this` binding of `callback`.
  10371. * @returns {Object} Returns the composed aggregate object.
  10372. * @example
  10373. *
  10374. * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); });
  10375. * // => { '4': [4.2], '6': [6.1, 6.4] }
  10376. *
  10377. * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math);
  10378. * // => { '4': [4.2], '6': [6.1, 6.4] }
  10379. *
  10380. * // using "_.pluck" callback shorthand
  10381. * _.groupBy(['one', 'two', 'three'], 'length');
  10382. * // => { '3': ['one', 'two'], '5': ['three'] }
  10383. */
  10384. var groupBy = createAggregator(function(result, value, key) {
  10385. (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value);
  10386. });
  10387. /**
  10388. * Creates an object composed of keys generated from the results of running
  10389. * each element of the collection through the given callback. The corresponding
  10390. * value of each key is the last element responsible for generating the key.
  10391. * The callback is bound to `thisArg` and invoked with three arguments;
  10392. * (value, index|key, collection).
  10393. *
  10394. * If a property name is provided for `callback` the created "_.pluck" style
  10395. * callback will return the property value of the given element.
  10396. *
  10397. * If an object is provided for `callback` the created "_.where" style callback
  10398. * will return `true` for elements that have the properties of the given object,
  10399. * else `false`.
  10400. *
  10401. * @static
  10402. * @memberOf _
  10403. * @category Collections
  10404. * @param {Array|Object|string} collection The collection to iterate over.
  10405. * @param {Function|Object|string} [callback=identity] The function called
  10406. * per iteration. If a property name or object is provided it will be used
  10407. * to create a "_.pluck" or "_.where" style callback, respectively.
  10408. * @param {*} [thisArg] The `this` binding of `callback`.
  10409. * @returns {Object} Returns the composed aggregate object.
  10410. * @example
  10411. *
  10412. * var keys = [
  10413. * { 'dir': 'left', 'code': 97 },
  10414. * { 'dir': 'right', 'code': 100 }
  10415. * ];
  10416. *
  10417. * _.indexBy(keys, 'dir');
  10418. * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
  10419. *
  10420. * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); });
  10421. * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
  10422. *
  10423. * _.indexBy(stooges, function(key) { this.fromCharCode(key.code); }, String);
  10424. * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
  10425. */
  10426. var indexBy = createAggregator(function(result, value, key) {
  10427. result[key] = value;
  10428. });
  10429. /**
  10430. * Invokes the method named by `methodName` on each element in the `collection`
  10431. * returning an array of the results of each invoked method. Additional arguments
  10432. * will be provided to each invoked method. If `methodName` is a function it
  10433. * will be invoked for, and `this` bound to, each element in the `collection`.
  10434. *
  10435. * @static
  10436. * @memberOf _
  10437. * @category Collections
  10438. * @param {Array|Object|string} collection The collection to iterate over.
  10439. * @param {Function|string} methodName The name of the method to invoke or
  10440. * the function invoked per iteration.
  10441. * @param {...*} [arg] Arguments to invoke the method with.
  10442. * @returns {Array} Returns a new array of the results of each invoked method.
  10443. * @example
  10444. *
  10445. * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort');
  10446. * // => [[1, 5, 7], [1, 2, 3]]
  10447. *
  10448. * _.invoke([123, 456], String.prototype.split, '');
  10449. * // => [['1', '2', '3'], ['4', '5', '6']]
  10450. */
  10451. function invoke(collection, methodName) {
  10452. var args = nativeSlice.call(arguments, 2),
  10453. index = -1,
  10454. isFunc = typeof methodName == 'function',
  10455. length = collection ? collection.length : 0,
  10456. result = Array(typeof length == 'number' ? length : 0);
  10457. forEach(collection, function(value) {
  10458. result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args);
  10459. });
  10460. return result;
  10461. }
  10462. /**
  10463. * Creates an array of values by running each element in the collection
  10464. * through the callback. The callback is bound to `thisArg` and invoked with
  10465. * three arguments; (value, index|key, collection).
  10466. *
  10467. * If a property name is provided for `callback` the created "_.pluck" style
  10468. * callback will return the property value of the given element.
  10469. *
  10470. * If an object is provided for `callback` the created "_.where" style callback
  10471. * will return `true` for elements that have the properties of the given object,
  10472. * else `false`.
  10473. *
  10474. * @static
  10475. * @memberOf _
  10476. * @alias collect
  10477. * @category Collections
  10478. * @param {Array|Object|string} collection The collection to iterate over.
  10479. * @param {Function|Object|string} [callback=identity] The function called
  10480. * per iteration. If a property name or object is provided it will be used
  10481. * to create a "_.pluck" or "_.where" style callback, respectively.
  10482. * @param {*} [thisArg] The `this` binding of `callback`.
  10483. * @returns {Array} Returns a new array of the results of each `callback` execution.
  10484. * @example
  10485. *
  10486. * _.map([1, 2, 3], function(num) { return num * 3; });
  10487. * // => [3, 6, 9]
  10488. *
  10489. * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; });
  10490. * // => [3, 6, 9] (property order is not guaranteed across environments)
  10491. *
  10492. * var stooges = [
  10493. * { 'name': 'moe', 'age': 40 },
  10494. * { 'name': 'larry', 'age': 50 }
  10495. * ];
  10496. *
  10497. * // using "_.pluck" callback shorthand
  10498. * _.map(stooges, 'name');
  10499. * // => ['moe', 'larry']
  10500. */
  10501. function map(collection, callback, thisArg) {
  10502. var index = -1,
  10503. length = collection ? collection.length : 0;
  10504. callback = lodash.createCallback(callback, thisArg, 3);
  10505. if (typeof length == 'number') {
  10506. var result = Array(length);
  10507. while (++index < length) {
  10508. result[index] = callback(collection[index], index, collection);
  10509. }
  10510. } else {
  10511. result = [];
  10512. forOwn(collection, function(value, key, collection) {
  10513. result[++index] = callback(value, key, collection);
  10514. });
  10515. }
  10516. return result;
  10517. }
  10518. /**
  10519. * Retrieves the maximum value of a collection. If the collection is empty or
  10520. * falsey `-Infinity` is returned. If a callback is provided it will be executed
  10521. * for each value in the collection to generate the criterion by which the value
  10522. * is ranked. The callback is bound to `thisArg` and invoked with three
  10523. * arguments; (value, index, collection).
  10524. *
  10525. * If a property name is provided for `callback` the created "_.pluck" style
  10526. * callback will return the property value of the given element.
  10527. *
  10528. * If an object is provided for `callback` the created "_.where" style callback
  10529. * will return `true` for elements that have the properties of the given object,
  10530. * else `false`.
  10531. *
  10532. * @static
  10533. * @memberOf _
  10534. * @category Collections
  10535. * @param {Array|Object|string} collection The collection to iterate over.
  10536. * @param {Function|Object|string} [callback=identity] The function called
  10537. * per iteration. If a property name or object is provided it will be used
  10538. * to create a "_.pluck" or "_.where" style callback, respectively.
  10539. * @param {*} [thisArg] The `this` binding of `callback`.
  10540. * @returns {*} Returns the maximum value.
  10541. * @example
  10542. *
  10543. * _.max([4, 2, 8, 6]);
  10544. * // => 8
  10545. *
  10546. * var stooges = [
  10547. * { 'name': 'moe', 'age': 40 },
  10548. * { 'name': 'larry', 'age': 50 }
  10549. * ];
  10550. *
  10551. * _.max(stooges, function(stooge) { return stooge.age; });
  10552. * // => { 'name': 'larry', 'age': 50 };
  10553. *
  10554. * // using "_.pluck" callback shorthand
  10555. * _.max(stooges, 'age');
  10556. * // => { 'name': 'larry', 'age': 50 };
  10557. */
  10558. function max(collection, callback, thisArg) {
  10559. var computed = -Infinity,
  10560. result = computed;
  10561. if (!callback && isArray(collection)) {
  10562. var index = -1,
  10563. length = collection.length;
  10564. while (++index < length) {
  10565. var value = collection[index];
  10566. if (value > result) {
  10567. result = value;
  10568. }
  10569. }
  10570. } else {
  10571. callback = (!callback && isString(collection))
  10572. ? charAtCallback
  10573. : lodash.createCallback(callback, thisArg, 3);
  10574. forEach(collection, function(value, index, collection) {
  10575. var current = callback(value, index, collection);
  10576. if (current > computed) {
  10577. computed = current;
  10578. result = value;
  10579. }
  10580. });
  10581. }
  10582. return result;
  10583. }
  10584. /**
  10585. * Retrieves the minimum value of a collection. If the collection is empty or
  10586. * falsey `Infinity` is returned. If a callback is provided it will be executed
  10587. * for each value in the collection to generate the criterion by which the value
  10588. * is ranked. The callback is bound to `thisArg` and invoked with three
  10589. * arguments; (value, index, collection).
  10590. *
  10591. * If a property name is provided for `callback` the created "_.pluck" style
  10592. * callback will return the property value of the given element.
  10593. *
  10594. * If an object is provided for `callback` the created "_.where" style callback
  10595. * will return `true` for elements that have the properties of the given object,
  10596. * else `false`.
  10597. *
  10598. * @static
  10599. * @memberOf _
  10600. * @category Collections
  10601. * @param {Array|Object|string} collection The collection to iterate over.
  10602. * @param {Function|Object|string} [callback=identity] The function called
  10603. * per iteration. If a property name or object is provided it will be used
  10604. * to create a "_.pluck" or "_.where" style callback, respectively.
  10605. * @param {*} [thisArg] The `this` binding of `callback`.
  10606. * @returns {*} Returns the minimum value.
  10607. * @example
  10608. *
  10609. * _.min([4, 2, 8, 6]);
  10610. * // => 2
  10611. *
  10612. * var stooges = [
  10613. * { 'name': 'moe', 'age': 40 },
  10614. * { 'name': 'larry', 'age': 50 }
  10615. * ];
  10616. *
  10617. * _.min(stooges, function(stooge) { return stooge.age; });
  10618. * // => { 'name': 'moe', 'age': 40 };
  10619. *
  10620. * // using "_.pluck" callback shorthand
  10621. * _.min(stooges, 'age');
  10622. * // => { 'name': 'moe', 'age': 40 };
  10623. */
  10624. function min(collection, callback, thisArg) {
  10625. var computed = Infinity,
  10626. result = computed;
  10627. if (!callback && isArray(collection)) {
  10628. var index = -1,
  10629. length = collection.length;
  10630. while (++index < length) {
  10631. var value = collection[index];
  10632. if (value < result) {
  10633. result = value;
  10634. }
  10635. }
  10636. } else {
  10637. callback = (!callback && isString(collection))
  10638. ? charAtCallback
  10639. : lodash.createCallback(callback, thisArg, 3);
  10640. forEach(collection, function(value, index, collection) {
  10641. var current = callback(value, index, collection);
  10642. if (current < computed) {
  10643. computed = current;
  10644. result = value;
  10645. }
  10646. });
  10647. }
  10648. return result;
  10649. }
  10650. /**
  10651. * Retrieves the value of a specified property from all elements in the `collection`.
  10652. *
  10653. * @static
  10654. * @memberOf _
  10655. * @type Function
  10656. * @category Collections
  10657. * @param {Array|Object|string} collection The collection to iterate over.
  10658. * @param {string} property The property to pluck.
  10659. * @returns {Array} Returns a new array of property values.
  10660. * @example
  10661. *
  10662. * var stooges = [
  10663. * { 'name': 'moe', 'age': 40 },
  10664. * { 'name': 'larry', 'age': 50 }
  10665. * ];
  10666. *
  10667. * _.pluck(stooges, 'name');
  10668. * // => ['moe', 'larry']
  10669. */
  10670. function pluck(collection, property) {
  10671. var index = -1,
  10672. length = collection ? collection.length : 0;
  10673. if (typeof length == 'number') {
  10674. var result = Array(length);
  10675. while (++index < length) {
  10676. result[index] = collection[index][property];
  10677. }
  10678. }
  10679. return result || map(collection, property);
  10680. }
  10681. /**
  10682. * Reduces a collection to a value which is the accumulated result of running
  10683. * each element in the collection through the callback, where each successive
  10684. * callback execution consumes the return value of the previous execution. If
  10685. * `accumulator` is not provided the first element of the collection will be
  10686. * used as the initial `accumulator` value. The callback is bound to `thisArg`
  10687. * and invoked with four arguments; (accumulator, value, index|key, collection).
  10688. *
  10689. * @static
  10690. * @memberOf _
  10691. * @alias foldl, inject
  10692. * @category Collections
  10693. * @param {Array|Object|string} collection The collection to iterate over.
  10694. * @param {Function} [callback=identity] The function called per iteration.
  10695. * @param {*} [accumulator] Initial value of the accumulator.
  10696. * @param {*} [thisArg] The `this` binding of `callback`.
  10697. * @returns {*} Returns the accumulated value.
  10698. * @example
  10699. *
  10700. * var sum = _.reduce([1, 2, 3], function(sum, num) {
  10701. * return sum + num;
  10702. * });
  10703. * // => 6
  10704. *
  10705. * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) {
  10706. * result[key] = num * 3;
  10707. * return result;
  10708. * }, {});
  10709. * // => { 'a': 3, 'b': 6, 'c': 9 }
  10710. */
  10711. function reduce(collection, callback, accumulator, thisArg) {
  10712. if (!collection) return accumulator;
  10713. var noaccum = arguments.length < 3;
  10714. callback = baseCreateCallback(callback, thisArg, 4);
  10715. var index = -1,
  10716. length = collection.length;
  10717. if (typeof length == 'number') {
  10718. if (noaccum) {
  10719. accumulator = collection[++index];
  10720. }
  10721. while (++index < length) {
  10722. accumulator = callback(accumulator, collection[index], index, collection);
  10723. }
  10724. } else {
  10725. forOwn(collection, function(value, index, collection) {
  10726. accumulator = noaccum
  10727. ? (noaccum = false, value)
  10728. : callback(accumulator, value, index, collection)
  10729. });
  10730. }
  10731. return accumulator;
  10732. }
  10733. /**
  10734. * This method is like `_.reduce` except that it iterates over elements
  10735. * of a `collection` from right to left.
  10736. *
  10737. * @static
  10738. * @memberOf _
  10739. * @alias foldr
  10740. * @category Collections
  10741. * @param {Array|Object|string} collection The collection to iterate over.
  10742. * @param {Function} [callback=identity] The function called per iteration.
  10743. * @param {*} [accumulator] Initial value of the accumulator.
  10744. * @param {*} [thisArg] The `this` binding of `callback`.
  10745. * @returns {*} Returns the accumulated value.
  10746. * @example
  10747. *
  10748. * var list = [[0, 1], [2, 3], [4, 5]];
  10749. * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []);
  10750. * // => [4, 5, 2, 3, 0, 1]
  10751. */
  10752. function reduceRight(collection, callback, accumulator, thisArg) {
  10753. var noaccum = arguments.length < 3;
  10754. callback = baseCreateCallback(callback, thisArg, 4);
  10755. forEachRight(collection, function(value, index, collection) {
  10756. accumulator = noaccum
  10757. ? (noaccum = false, value)
  10758. : callback(accumulator, value, index, collection);
  10759. });
  10760. return accumulator;
  10761. }
  10762. /**
  10763. * The opposite of `_.filter` this method returns the elements of a
  10764. * collection that the callback does **not** return truey for.
  10765. *
  10766. * If a property name is provided for `callback` the created "_.pluck" style
  10767. * callback will return the property value of the given element.
  10768. *
  10769. * If an object is provided for `callback` the created "_.where" style callback
  10770. * will return `true` for elements that have the properties of the given object,
  10771. * else `false`.
  10772. *
  10773. * @static
  10774. * @memberOf _
  10775. * @category Collections
  10776. * @param {Array|Object|string} collection The collection to iterate over.
  10777. * @param {Function|Object|string} [callback=identity] The function called
  10778. * per iteration. If a property name or object is provided it will be used
  10779. * to create a "_.pluck" or "_.where" style callback, respectively.
  10780. * @param {*} [thisArg] The `this` binding of `callback`.
  10781. * @returns {Array} Returns a new array of elements that failed the callback check.
  10782. * @example
  10783. *
  10784. * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; });
  10785. * // => [1, 3, 5]
  10786. *
  10787. * var food = [
  10788. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  10789. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  10790. * ];
  10791. *
  10792. * // using "_.pluck" callback shorthand
  10793. * _.reject(food, 'organic');
  10794. * // => [{ 'name': 'apple', 'organic': false, 'type': 'fruit' }]
  10795. *
  10796. * // using "_.where" callback shorthand
  10797. * _.reject(food, { 'type': 'fruit' });
  10798. * // => [{ 'name': 'carrot', 'organic': true, 'type': 'vegetable' }]
  10799. */
  10800. function reject(collection, callback, thisArg) {
  10801. callback = lodash.createCallback(callback, thisArg, 3);
  10802. return filter(collection, function(value, index, collection) {
  10803. return !callback(value, index, collection);
  10804. });
  10805. }
  10806. /**
  10807. * Retrieves a random element or `n` random elements from a collection.
  10808. *
  10809. * @static
  10810. * @memberOf _
  10811. * @category Collections
  10812. * @param {Array|Object|string} collection The collection to sample.
  10813. * @param {number} [n] The number of elements to sample.
  10814. * @param- {Object} [guard] Allows working with functions, like `_.map`,
  10815. * without using their `key` and `object` arguments as sources.
  10816. * @returns {Array} Returns the random sample(s) of `collection`.
  10817. * @example
  10818. *
  10819. * _.sample([1, 2, 3, 4]);
  10820. * // => 2
  10821. *
  10822. * _.sample([1, 2, 3, 4], 2);
  10823. * // => [3, 1]
  10824. */
  10825. function sample(collection, n, guard) {
  10826. var length = collection ? collection.length : 0;
  10827. if (typeof length != 'number') {
  10828. collection = values(collection);
  10829. }
  10830. if (n == null || guard) {
  10831. return collection ? collection[random(length - 1)] : undefined;
  10832. }
  10833. var result = shuffle(collection);
  10834. result.length = nativeMin(nativeMax(0, n), result.length);
  10835. return result;
  10836. }
  10837. /**
  10838. * Creates an array of shuffled values, using a version of the Fisher-Yates
  10839. * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle.
  10840. *
  10841. * @static
  10842. * @memberOf _
  10843. * @category Collections
  10844. * @param {Array|Object|string} collection The collection to shuffle.
  10845. * @returns {Array} Returns a new shuffled collection.
  10846. * @example
  10847. *
  10848. * _.shuffle([1, 2, 3, 4, 5, 6]);
  10849. * // => [4, 1, 6, 3, 5, 2]
  10850. */
  10851. function shuffle(collection) {
  10852. var index = -1,
  10853. length = collection ? collection.length : 0,
  10854. result = Array(typeof length == 'number' ? length : 0);
  10855. forEach(collection, function(value) {
  10856. var rand = random(++index);
  10857. result[index] = result[rand];
  10858. result[rand] = value;
  10859. });
  10860. return result;
  10861. }
  10862. /**
  10863. * Gets the size of the `collection` by returning `collection.length` for arrays
  10864. * and array-like objects or the number of own enumerable properties for objects.
  10865. *
  10866. * @static
  10867. * @memberOf _
  10868. * @category Collections
  10869. * @param {Array|Object|string} collection The collection to inspect.
  10870. * @returns {number} Returns `collection.length` or number of own enumerable properties.
  10871. * @example
  10872. *
  10873. * _.size([1, 2]);
  10874. * // => 2
  10875. *
  10876. * _.size({ 'one': 1, 'two': 2, 'three': 3 });
  10877. * // => 3
  10878. *
  10879. * _.size('curly');
  10880. * // => 5
  10881. */
  10882. function size(collection) {
  10883. var length = collection ? collection.length : 0;
  10884. return typeof length == 'number' ? length : keys(collection).length;
  10885. }
  10886. /**
  10887. * Checks if the callback returns a truey value for **any** element of a
  10888. * collection. The function returns as soon as it finds a passing value and
  10889. * does not iterate over the entire collection. The callback is bound to
  10890. * `thisArg` and invoked with three arguments; (value, index|key, collection).
  10891. *
  10892. * If a property name is provided for `callback` the created "_.pluck" style
  10893. * callback will return the property value of the given element.
  10894. *
  10895. * If an object is provided for `callback` the created "_.where" style callback
  10896. * will return `true` for elements that have the properties of the given object,
  10897. * else `false`.
  10898. *
  10899. * @static
  10900. * @memberOf _
  10901. * @alias any
  10902. * @category Collections
  10903. * @param {Array|Object|string} collection The collection to iterate over.
  10904. * @param {Function|Object|string} [callback=identity] The function called
  10905. * per iteration. If a property name or object is provided it will be used
  10906. * to create a "_.pluck" or "_.where" style callback, respectively.
  10907. * @param {*} [thisArg] The `this` binding of `callback`.
  10908. * @returns {boolean} Returns `true` if any element passed the callback check,
  10909. * else `false`.
  10910. * @example
  10911. *
  10912. * _.some([null, 0, 'yes', false], Boolean);
  10913. * // => true
  10914. *
  10915. * var food = [
  10916. * { 'name': 'apple', 'organic': false, 'type': 'fruit' },
  10917. * { 'name': 'carrot', 'organic': true, 'type': 'vegetable' }
  10918. * ];
  10919. *
  10920. * // using "_.pluck" callback shorthand
  10921. * _.some(food, 'organic');
  10922. * // => true
  10923. *
  10924. * // using "_.where" callback shorthand
  10925. * _.some(food, { 'type': 'meat' });
  10926. * // => false
  10927. */
  10928. function some(collection, callback, thisArg) {
  10929. var result;
  10930. callback = lodash.createCallback(callback, thisArg, 3);
  10931. var index = -1,
  10932. length = collection ? collection.length : 0;
  10933. if (typeof length == 'number') {
  10934. while (++index < length) {
  10935. if ((result = callback(collection[index], index, collection))) {
  10936. break;
  10937. }
  10938. }
  10939. } else {
  10940. forOwn(collection, function(value, index, collection) {
  10941. return !(result = callback(value, index, collection));
  10942. });
  10943. }
  10944. return !!result;
  10945. }
  10946. /**
  10947. * Creates an array of elements, sorted in ascending order by the results of
  10948. * running each element in a collection through the callback. This method
  10949. * performs a stable sort, that is, it will preserve the original sort order
  10950. * of equal elements. The callback is bound to `thisArg` and invoked with
  10951. * three arguments; (value, index|key, collection).
  10952. *
  10953. * If a property name is provided for `callback` the created "_.pluck" style
  10954. * callback will return the property value of the given element.
  10955. *
  10956. * If an object is provided for `callback` the created "_.where" style callback
  10957. * will return `true` for elements that have the properties of the given object,
  10958. * else `false`.
  10959. *
  10960. * @static
  10961. * @memberOf _
  10962. * @category Collections
  10963. * @param {Array|Object|string} collection The collection to iterate over.
  10964. * @param {Function|Object|string} [callback=identity] The function called
  10965. * per iteration. If a property name or object is provided it will be used
  10966. * to create a "_.pluck" or "_.where" style callback, respectively.
  10967. * @param {*} [thisArg] The `this` binding of `callback`.
  10968. * @returns {Array} Returns a new array of sorted elements.
  10969. * @example
  10970. *
  10971. * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); });
  10972. * // => [3, 1, 2]
  10973. *
  10974. * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math);
  10975. * // => [3, 1, 2]
  10976. *
  10977. * // using "_.pluck" callback shorthand
  10978. * _.sortBy(['banana', 'strawberry', 'apple'], 'length');
  10979. * // => ['apple', 'banana', 'strawberry']
  10980. */
  10981. function sortBy(collection, callback, thisArg) {
  10982. var index = -1,
  10983. length = collection ? collection.length : 0,
  10984. result = Array(typeof length == 'number' ? length : 0);
  10985. callback = lodash.createCallback(callback, thisArg, 3);
  10986. forEach(collection, function(value, key, collection) {
  10987. var object = result[++index] = getObject();
  10988. object.criteria = callback(value, key, collection);
  10989. object.index = index;
  10990. object.value = value;
  10991. });
  10992. length = result.length;
  10993. result.sort(compareAscending);
  10994. while (length--) {
  10995. var object = result[length];
  10996. result[length] = object.value;
  10997. releaseObject(object);
  10998. }
  10999. return result;
  11000. }
  11001. /**
  11002. * Converts the `collection` to an array.
  11003. *
  11004. * @static
  11005. * @memberOf _
  11006. * @category Collections
  11007. * @param {Array|Object|string} collection The collection to convert.
  11008. * @returns {Array} Returns the new converted array.
  11009. * @example
  11010. *
  11011. * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4);
  11012. * // => [2, 3, 4]
  11013. */
  11014. function toArray(collection) {
  11015. if (collection && typeof collection.length == 'number') {
  11016. return slice(collection);
  11017. }
  11018. return values(collection);
  11019. }
  11020. /**
  11021. * Performs a deep comparison of each element in a `collection` to the given
  11022. * `properties` object, returning an array of all elements that have equivalent
  11023. * property values.
  11024. *
  11025. * @static
  11026. * @memberOf _
  11027. * @type Function
  11028. * @category Collections
  11029. * @param {Array|Object|string} collection The collection to iterate over.
  11030. * @param {Object} properties The object of property values to filter by.
  11031. * @returns {Array} Returns a new array of elements that have the given properties.
  11032. * @example
  11033. *
  11034. * var stooges = [
  11035. * { 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
  11036. * { 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }
  11037. * ];
  11038. *
  11039. * _.where(stooges, { 'age': 40 });
  11040. * // => [{ 'name': 'moe', 'age': 40, 'quotes': ['Spread out!', 'You knucklehead!'] }]
  11041. *
  11042. * _.where(stooges, { 'quotes': ['Poifect!'] });
  11043. * // => [{ 'name': 'curly', 'age': 30, 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] }]
  11044. */
  11045. var where = filter;
  11046. /*--------------------------------------------------------------------------*/
  11047. /**
  11048. * Creates an array with all falsey values removed. The values `false`, `null`,
  11049. * `0`, `""`, `undefined`, and `NaN` are all falsey.
  11050. *
  11051. * @static
  11052. * @memberOf _
  11053. * @category Arrays
  11054. * @param {Array} array The array to compact.
  11055. * @returns {Array} Returns a new array of filtered values.
  11056. * @example
  11057. *
  11058. * _.compact([0, 1, false, 2, '', 3]);
  11059. * // => [1, 2, 3]
  11060. */
  11061. function compact(array) {
  11062. var index = -1,
  11063. length = array ? array.length : 0,
  11064. result = [];
  11065. while (++index < length) {
  11066. var value = array[index];
  11067. if (value) {
  11068. result.push(value);
  11069. }
  11070. }
  11071. return result;
  11072. }
  11073. /**
  11074. * Creates an array excluding all values of the provided arrays using strict
  11075. * equality for comparisons, i.e. `===`.
  11076. *
  11077. * @static
  11078. * @memberOf _
  11079. * @category Arrays
  11080. * @param {Array} array The array to process.
  11081. * @param {...Array} [array] The arrays of values to exclude.
  11082. * @returns {Array} Returns a new array of filtered values.
  11083. * @example
  11084. *
  11085. * _.difference([1, 2, 3, 4, 5], [5, 2, 10]);
  11086. * // => [1, 3, 4]
  11087. */
  11088. function difference(array) {
  11089. var index = -1,
  11090. indexOf = getIndexOf(),
  11091. length = array ? array.length : 0,
  11092. seen = baseFlatten(arguments, true, true, 1),
  11093. result = [];
  11094. var isLarge = length >= largeArraySize && indexOf === baseIndexOf;
  11095. if (isLarge) {
  11096. var cache = createCache(seen);
  11097. if (cache) {
  11098. indexOf = cacheIndexOf;
  11099. seen = cache;
  11100. } else {
  11101. isLarge = false;
  11102. }
  11103. }
  11104. while (++index < length) {
  11105. var value = array[index];
  11106. if (indexOf(seen, value) < 0) {
  11107. result.push(value);
  11108. }
  11109. }
  11110. if (isLarge) {
  11111. releaseObject(seen);
  11112. }
  11113. return result;
  11114. }
  11115. /**
  11116. * This method is like `_.find` except that it returns the index of the first
  11117. * element that passes the callback check, instead of the element itself.
  11118. *
  11119. * @static
  11120. * @memberOf _
  11121. * @category Arrays
  11122. * @param {Array} array The array to search.
  11123. * @param {Function|Object|string} [callback=identity] The function called
  11124. * per iteration. If a property name or object is provided it will be used
  11125. * to create a "_.pluck" or "_.where" style callback, respectively.
  11126. * @param {*} [thisArg] The `this` binding of `callback`.
  11127. * @returns {number} Returns the index of the found element, else `-1`.
  11128. * @example
  11129. *
  11130. * _.findIndex(['apple', 'banana', 'beet'], function(food) {
  11131. * return /^b/.test(food);
  11132. * });
  11133. * // => 1
  11134. */
  11135. function findIndex(array, callback, thisArg) {
  11136. var index = -1,
  11137. length = array ? array.length : 0;
  11138. callback = lodash.createCallback(callback, thisArg, 3);
  11139. while (++index < length) {
  11140. if (callback(array[index], index, array)) {
  11141. return index;
  11142. }
  11143. }
  11144. return -1;
  11145. }
  11146. /**
  11147. * This method is like `_.findIndex` except that it iterates over elements
  11148. * of a `collection` from right to left.
  11149. *
  11150. * @static
  11151. * @memberOf _
  11152. * @category Arrays
  11153. * @param {Array} array The array to search.
  11154. * @param {Function|Object|string} [callback=identity] The function called
  11155. * per iteration. If a property name or object is provided it will be used
  11156. * to create a "_.pluck" or "_.where" style callback, respectively.
  11157. * @param {*} [thisArg] The `this` binding of `callback`.
  11158. * @returns {number} Returns the index of the found element, else `-1`.
  11159. * @example
  11160. *
  11161. * _.findLastIndex(['apple', 'banana', 'beet'], function(food) {
  11162. * return /^b/.test(food);
  11163. * });
  11164. * // => 2
  11165. */
  11166. function findLastIndex(array, callback, thisArg) {
  11167. var length = array ? array.length : 0;
  11168. callback = lodash.createCallback(callback, thisArg, 3);
  11169. while (length--) {
  11170. if (callback(array[length], length, array)) {
  11171. return length;
  11172. }
  11173. }
  11174. return -1;
  11175. }
  11176. /**
  11177. * Gets the first element or first `n` elements of an array. If a callback
  11178. * is provided elements at the beginning of the array are returned as long
  11179. * as the callback returns truey. The callback is bound to `thisArg` and
  11180. * invoked with three arguments; (value, index, array).
  11181. *
  11182. * If a property name is provided for `callback` the created "_.pluck" style
  11183. * callback will return the property value of the given element.
  11184. *
  11185. * If an object is provided for `callback` the created "_.where" style callback
  11186. * will return `true` for elements that have the properties of the given object,
  11187. * else `false`.
  11188. *
  11189. * @static
  11190. * @memberOf _
  11191. * @alias head, take
  11192. * @category Arrays
  11193. * @param {Array} array The array to query.
  11194. * @param {Function|Object|number|string} [callback] The function called
  11195. * per element or the number of elements to return. If a property name or
  11196. * object is provided it will be used to create a "_.pluck" or "_.where"
  11197. * style callback, respectively.
  11198. * @param {*} [thisArg] The `this` binding of `callback`.
  11199. * @returns {*} Returns the first element(s) of `array`.
  11200. * @example
  11201. *
  11202. * _.first([1, 2, 3]);
  11203. * // => 1
  11204. *
  11205. * _.first([1, 2, 3], 2);
  11206. * // => [1, 2]
  11207. *
  11208. * _.first([1, 2, 3], function(num) {
  11209. * return num < 3;
  11210. * });
  11211. * // => [1, 2]
  11212. *
  11213. * var food = [
  11214. * { 'name': 'banana', 'organic': true },
  11215. * { 'name': 'beet', 'organic': false },
  11216. * ];
  11217. *
  11218. * // using "_.pluck" callback shorthand
  11219. * _.first(food, 'organic');
  11220. * // => [{ 'name': 'banana', 'organic': true }]
  11221. *
  11222. * var food = [
  11223. * { 'name': 'apple', 'type': 'fruit' },
  11224. * { 'name': 'banana', 'type': 'fruit' },
  11225. * { 'name': 'beet', 'type': 'vegetable' }
  11226. * ];
  11227. *
  11228. * // using "_.where" callback shorthand
  11229. * _.first(food, { 'type': 'fruit' });
  11230. * // => [{ 'name': 'apple', 'type': 'fruit' }, { 'name': 'banana', 'type': 'fruit' }]
  11231. */
  11232. function first(array, callback, thisArg) {
  11233. var n = 0,
  11234. length = array ? array.length : 0;
  11235. if (typeof callback != 'number' && callback != null) {
  11236. var index = -1;
  11237. callback = lodash.createCallback(callback, thisArg, 3);
  11238. while (++index < length && callback(array[index], index, array)) {
  11239. n++;
  11240. }
  11241. } else {
  11242. n = callback;
  11243. if (n == null || thisArg) {
  11244. return array ? array[0] : undefined;
  11245. }
  11246. }
  11247. return slice(array, 0, nativeMin(nativeMax(0, n), length));
  11248. }
  11249. /**
  11250. * Flattens a nested array (the nesting can be to any depth). If `isShallow`
  11251. * is truey, the array will only be flattened a single level. If a callback
  11252. * is provided each element of the array is passed through the callback before
  11253. * flattening. The callback is bound to `thisArg` and invoked with three
  11254. * arguments; (value, index, array).
  11255. *
  11256. * If a property name is provided for `callback` the created "_.pluck" style
  11257. * callback will return the property value of the given element.
  11258. *
  11259. * If an object is provided for `callback` the created "_.where" style callback
  11260. * will return `true` for elements that have the properties of the given object,
  11261. * else `false`.
  11262. *
  11263. * @static
  11264. * @memberOf _
  11265. * @category Arrays
  11266. * @param {Array} array The array to flatten.
  11267. * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level.
  11268. * @param {Function|Object|string} [callback=identity] The function called
  11269. * per iteration. If a property name or object is provided it will be used
  11270. * to create a "_.pluck" or "_.where" style callback, respectively.
  11271. * @param {*} [thisArg] The `this` binding of `callback`.
  11272. * @returns {Array} Returns a new flattened array.
  11273. * @example
  11274. *
  11275. * _.flatten([1, [2], [3, [[4]]]]);
  11276. * // => [1, 2, 3, 4];
  11277. *
  11278. * _.flatten([1, [2], [3, [[4]]]], true);
  11279. * // => [1, 2, 3, [[4]]];
  11280. *
  11281. * var stooges = [
  11282. * { 'name': 'curly', 'quotes': ['Oh, a wise guy, eh?', 'Poifect!'] },
  11283. * { 'name': 'moe', 'quotes': ['Spread out!', 'You knucklehead!'] }
  11284. * ];
  11285. *
  11286. * // using "_.pluck" callback shorthand
  11287. * _.flatten(stooges, 'quotes');
  11288. * // => ['Oh, a wise guy, eh?', 'Poifect!', 'Spread out!', 'You knucklehead!']
  11289. */
  11290. function flatten(array, isShallow, callback, thisArg) {
  11291. // juggle arguments
  11292. if (typeof isShallow != 'boolean' && isShallow != null) {
  11293. thisArg = callback;
  11294. callback = !(thisArg && thisArg[isShallow] === array) ? isShallow : null;
  11295. isShallow = false;
  11296. }
  11297. if (callback != null) {
  11298. array = map(array, callback, thisArg);
  11299. }
  11300. return baseFlatten(array, isShallow);
  11301. }
  11302. /**
  11303. * Gets the index at which the first occurrence of `value` is found using
  11304. * strict equality for comparisons, i.e. `===`. If the array is already sorted
  11305. * providing `true` for `fromIndex` will run a faster binary search.
  11306. *
  11307. * @static
  11308. * @memberOf _
  11309. * @category Arrays
  11310. * @param {Array} array The array to search.
  11311. * @param {*} value The value to search for.
  11312. * @param {boolean|number} [fromIndex=0] The index to search from or `true`
  11313. * to perform a binary search on a sorted array.
  11314. * @returns {number} Returns the index of the matched value or `-1`.
  11315. * @example
  11316. *
  11317. * _.indexOf([1, 2, 3, 1, 2, 3], 2);
  11318. * // => 1
  11319. *
  11320. * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3);
  11321. * // => 4
  11322. *
  11323. * _.indexOf([1, 1, 2, 2, 3, 3], 2, true);
  11324. * // => 2
  11325. */
  11326. function indexOf(array, value, fromIndex) {
  11327. if (typeof fromIndex == 'number') {
  11328. var length = array ? array.length : 0;
  11329. fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0);
  11330. } else if (fromIndex) {
  11331. var index = sortedIndex(array, value);
  11332. return array[index] === value ? index : -1;
  11333. }
  11334. return baseIndexOf(array, value, fromIndex);
  11335. }
  11336. /**
  11337. * Gets all but the last element or last `n` elements of an array. If a
  11338. * callback is provided elements at the end of the array are excluded from
  11339. * the result as long as the callback returns truey. The callback is bound
  11340. * to `thisArg` and invoked with three arguments; (value, index, array).
  11341. *
  11342. * If a property name is provided for `callback` the created "_.pluck" style
  11343. * callback will return the property value of the given element.
  11344. *
  11345. * If an object is provided for `callback` the created "_.where" style callback
  11346. * will return `true` for elements that have the properties of the given object,
  11347. * else `false`.
  11348. *
  11349. * @static
  11350. * @memberOf _
  11351. * @category Arrays
  11352. * @param {Array} array The array to query.
  11353. * @param {Function|Object|number|string} [callback=1] The function called
  11354. * per element or the number of elements to exclude. If a property name or
  11355. * object is provided it will be used to create a "_.pluck" or "_.where"
  11356. * style callback, respectively.
  11357. * @param {*} [thisArg] The `this` binding of `callback`.
  11358. * @returns {Array} Returns a slice of `array`.
  11359. * @example
  11360. *
  11361. * _.initial([1, 2, 3]);
  11362. * // => [1, 2]
  11363. *
  11364. * _.initial([1, 2, 3], 2);
  11365. * // => [1]
  11366. *
  11367. * _.initial([1, 2, 3], function(num) {
  11368. * return num > 1;
  11369. * });
  11370. * // => [1]
  11371. *
  11372. * var food = [
  11373. * { 'name': 'beet', 'organic': false },
  11374. * { 'name': 'carrot', 'organic': true }
  11375. * ];
  11376. *
  11377. * // using "_.pluck" callback shorthand
  11378. * _.initial(food, 'organic');
  11379. * // => [{ 'name': 'beet', 'organic': false }]
  11380. *
  11381. * var food = [
  11382. * { 'name': 'banana', 'type': 'fruit' },
  11383. * { 'name': 'beet', 'type': 'vegetable' },
  11384. * { 'name': 'carrot', 'type': 'vegetable' }
  11385. * ];
  11386. *
  11387. * // using "_.where" callback shorthand
  11388. * _.initial(food, { 'type': 'vegetable' });
  11389. * // => [{ 'name': 'banana', 'type': 'fruit' }]
  11390. */
  11391. function initial(array, callback, thisArg) {
  11392. var n = 0,
  11393. length = array ? array.length : 0;
  11394. if (typeof callback != 'number' && callback != null) {
  11395. var index = length;
  11396. callback = lodash.createCallback(callback, thisArg, 3);
  11397. while (index-- && callback(array[index], index, array)) {
  11398. n++;
  11399. }
  11400. } else {
  11401. n = (callback == null || thisArg) ? 1 : callback || n;
  11402. }
  11403. return slice(array, 0, nativeMin(nativeMax(0, length - n), length));
  11404. }
  11405. /**
  11406. * Creates an array of unique values present in all provided arrays using
  11407. * strict equality for comparisons, i.e. `===`.
  11408. *
  11409. * @static
  11410. * @memberOf _
  11411. * @category Arrays
  11412. * @param {...Array} [array] The arrays to inspect.
  11413. * @returns {Array} Returns an array of composite values.
  11414. * @example
  11415. *
  11416. * _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  11417. * // => [1, 2]
  11418. */
  11419. function intersection(array) {
  11420. var args = arguments,
  11421. argsLength = args.length,
  11422. argsIndex = -1,
  11423. caches = getArray(),
  11424. index = -1,
  11425. indexOf = getIndexOf(),
  11426. length = array ? array.length : 0,
  11427. result = [],
  11428. seen = getArray();
  11429. while (++argsIndex < argsLength) {
  11430. var value = args[argsIndex];
  11431. caches[argsIndex] = indexOf === baseIndexOf &&
  11432. (value ? value.length : 0) >= largeArraySize &&
  11433. createCache(argsIndex ? args[argsIndex] : seen);
  11434. }
  11435. outer:
  11436. while (++index < length) {
  11437. var cache = caches[0];
  11438. value = array[index];
  11439. if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) {
  11440. argsIndex = argsLength;
  11441. (cache || seen).push(value);
  11442. while (--argsIndex) {
  11443. cache = caches[argsIndex];
  11444. if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) {
  11445. continue outer;
  11446. }
  11447. }
  11448. result.push(value);
  11449. }
  11450. }
  11451. while (argsLength--) {
  11452. cache = caches[argsLength];
  11453. if (cache) {
  11454. releaseObject(cache);
  11455. }
  11456. }
  11457. releaseArray(caches);
  11458. releaseArray(seen);
  11459. return result;
  11460. }
  11461. /**
  11462. * Gets the last element or last `n` elements of an array. If a callback is
  11463. * provided elements at the end of the array are returned as long as the
  11464. * callback returns truey. The callback is bound to `thisArg` and invoked
  11465. * with three arguments; (value, index, array).
  11466. *
  11467. * If a property name is provided for `callback` the created "_.pluck" style
  11468. * callback will return the property value of the given element.
  11469. *
  11470. * If an object is provided for `callback` the created "_.where" style callback
  11471. * will return `true` for elements that have the properties of the given object,
  11472. * else `false`.
  11473. *
  11474. * @static
  11475. * @memberOf _
  11476. * @category Arrays
  11477. * @param {Array} array The array to query.
  11478. * @param {Function|Object|number|string} [callback] The function called
  11479. * per element or the number of elements to return. If a property name or
  11480. * object is provided it will be used to create a "_.pluck" or "_.where"
  11481. * style callback, respectively.
  11482. * @param {*} [thisArg] The `this` binding of `callback`.
  11483. * @returns {*} Returns the last element(s) of `array`.
  11484. * @example
  11485. *
  11486. * _.last([1, 2, 3]);
  11487. * // => 3
  11488. *
  11489. * _.last([1, 2, 3], 2);
  11490. * // => [2, 3]
  11491. *
  11492. * _.last([1, 2, 3], function(num) {
  11493. * return num > 1;
  11494. * });
  11495. * // => [2, 3]
  11496. *
  11497. * var food = [
  11498. * { 'name': 'beet', 'organic': false },
  11499. * { 'name': 'carrot', 'organic': true }
  11500. * ];
  11501. *
  11502. * // using "_.pluck" callback shorthand
  11503. * _.last(food, 'organic');
  11504. * // => [{ 'name': 'carrot', 'organic': true }]
  11505. *
  11506. * var food = [
  11507. * { 'name': 'banana', 'type': 'fruit' },
  11508. * { 'name': 'beet', 'type': 'vegetable' },
  11509. * { 'name': 'carrot', 'type': 'vegetable' }
  11510. * ];
  11511. *
  11512. * // using "_.where" callback shorthand
  11513. * _.last(food, { 'type': 'vegetable' });
  11514. * // => [{ 'name': 'beet', 'type': 'vegetable' }, { 'name': 'carrot', 'type': 'vegetable' }]
  11515. */
  11516. function last(array, callback, thisArg) {
  11517. var n = 0,
  11518. length = array ? array.length : 0;
  11519. if (typeof callback != 'number' && callback != null) {
  11520. var index = length;
  11521. callback = lodash.createCallback(callback, thisArg, 3);
  11522. while (index-- && callback(array[index], index, array)) {
  11523. n++;
  11524. }
  11525. } else {
  11526. n = callback;
  11527. if (n == null || thisArg) {
  11528. return array ? array[length - 1] : undefined;
  11529. }
  11530. }
  11531. return slice(array, nativeMax(0, length - n));
  11532. }
  11533. /**
  11534. * Gets the index at which the last occurrence of `value` is found using strict
  11535. * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used
  11536. * as the offset from the end of the collection.
  11537. *
  11538. * @static
  11539. * @memberOf _
  11540. * @category Arrays
  11541. * @param {Array} array The array to search.
  11542. * @param {*} value The value to search for.
  11543. * @param {number} [fromIndex=array.length-1] The index to search from.
  11544. * @returns {number} Returns the index of the matched value or `-1`.
  11545. * @example
  11546. *
  11547. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2);
  11548. * // => 4
  11549. *
  11550. * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3);
  11551. * // => 1
  11552. */
  11553. function lastIndexOf(array, value, fromIndex) {
  11554. var index = array ? array.length : 0;
  11555. if (typeof fromIndex == 'number') {
  11556. index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1;
  11557. }
  11558. while (index--) {
  11559. if (array[index] === value) {
  11560. return index;
  11561. }
  11562. }
  11563. return -1;
  11564. }
  11565. /**
  11566. * Removes all provided values from the given array using strict equality for
  11567. * comparisons, i.e. `===`.
  11568. *
  11569. * @static
  11570. * @memberOf _
  11571. * @category Arrays
  11572. * @param {Array} array The array to modify.
  11573. * @param {...*} [value] The values to remove.
  11574. * @returns {Array} Returns `array`.
  11575. * @example
  11576. *
  11577. * var array = [1, 2, 3, 1, 2, 3];
  11578. * _.pull(array, 2, 3);
  11579. * console.log(array);
  11580. * // => [1, 1]
  11581. */
  11582. function pull(array) {
  11583. var args = arguments,
  11584. argsIndex = 0,
  11585. argsLength = args.length,
  11586. length = array ? array.length : 0;
  11587. while (++argsIndex < argsLength) {
  11588. var index = -1,
  11589. value = args[argsIndex];
  11590. while (++index < length) {
  11591. if (array[index] === value) {
  11592. splice.call(array, index--, 1);
  11593. length--;
  11594. }
  11595. }
  11596. }
  11597. return array;
  11598. }
  11599. /**
  11600. * Creates an array of numbers (positive and/or negative) progressing from
  11601. * `start` up to but not including `end`. If `start` is less than `stop` a
  11602. * zero-length range is created unless a negative `step` is specified.
  11603. *
  11604. * @static
  11605. * @memberOf _
  11606. * @category Arrays
  11607. * @param {number} [start=0] The start of the range.
  11608. * @param {number} end The end of the range.
  11609. * @param {number} [step=1] The value to increment or decrement by.
  11610. * @returns {Array} Returns a new range array.
  11611. * @example
  11612. *
  11613. * _.range(10);
  11614. * // => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  11615. *
  11616. * _.range(1, 11);
  11617. * // => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  11618. *
  11619. * _.range(0, 30, 5);
  11620. * // => [0, 5, 10, 15, 20, 25]
  11621. *
  11622. * _.range(0, -10, -1);
  11623. * // => [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
  11624. *
  11625. * _.range(1, 4, 0);
  11626. * // => [1, 1, 1]
  11627. *
  11628. * _.range(0);
  11629. * // => []
  11630. */
  11631. function range(start, end, step) {
  11632. start = +start || 0;
  11633. step = typeof step == 'number' ? step : (+step || 1);
  11634. if (end == null) {
  11635. end = start;
  11636. start = 0;
  11637. }
  11638. // use `Array(length)` so engines, like Chakra and V8, avoid slower modes
  11639. // http://youtu.be/XAqIpGU8ZZk#t=17m25s
  11640. var index = -1,
  11641. length = nativeMax(0, ceil((end - start) / (step || 1))),
  11642. result = Array(length);
  11643. while (++index < length) {
  11644. result[index] = start;
  11645. start += step;
  11646. }
  11647. return result;
  11648. }
  11649. /**
  11650. * Removes all elements from an array that the callback returns truey for
  11651. * and returns an array of removed elements. The callback is bound to `thisArg`
  11652. * and invoked with three arguments; (value, index, array).
  11653. *
  11654. * If a property name is provided for `callback` the created "_.pluck" style
  11655. * callback will return the property value of the given element.
  11656. *
  11657. * If an object is provided for `callback` the created "_.where" style callback
  11658. * will return `true` for elements that have the properties of the given object,
  11659. * else `false`.
  11660. *
  11661. * @static
  11662. * @memberOf _
  11663. * @category Arrays
  11664. * @param {Array} array The array to modify.
  11665. * @param {Function|Object|string} [callback=identity] The function called
  11666. * per iteration. If a property name or object is provided it will be used
  11667. * to create a "_.pluck" or "_.where" style callback, respectively.
  11668. * @param {*} [thisArg] The `this` binding of `callback`.
  11669. * @returns {Array} Returns a new array of removed elements.
  11670. * @example
  11671. *
  11672. * var array = [1, 2, 3, 4, 5, 6];
  11673. * var evens = _.remove(array, function(num) { return num % 2 == 0; });
  11674. *
  11675. * console.log(array);
  11676. * // => [1, 3, 5]
  11677. *
  11678. * console.log(evens);
  11679. * // => [2, 4, 6]
  11680. */
  11681. function remove(array, callback, thisArg) {
  11682. var index = -1,
  11683. length = array ? array.length : 0,
  11684. result = [];
  11685. callback = lodash.createCallback(callback, thisArg, 3);
  11686. while (++index < length) {
  11687. var value = array[index];
  11688. if (callback(value, index, array)) {
  11689. result.push(value);
  11690. splice.call(array, index--, 1);
  11691. length--;
  11692. }
  11693. }
  11694. return result;
  11695. }
  11696. /**
  11697. * The opposite of `_.initial` this method gets all but the first element or
  11698. * first `n` elements of an array. If a callback function is provided elements
  11699. * at the beginning of the array are excluded from the result as long as the
  11700. * callback returns truey. The callback is bound to `thisArg` and invoked
  11701. * with three arguments; (value, index, array).
  11702. *
  11703. * If a property name is provided for `callback` the created "_.pluck" style
  11704. * callback will return the property value of the given element.
  11705. *
  11706. * If an object is provided for `callback` the created "_.where" style callback
  11707. * will return `true` for elements that have the properties of the given object,
  11708. * else `false`.
  11709. *
  11710. * @static
  11711. * @memberOf _
  11712. * @alias drop, tail
  11713. * @category Arrays
  11714. * @param {Array} array The array to query.
  11715. * @param {Function|Object|number|string} [callback=1] The function called
  11716. * per element or the number of elements to exclude. If a property name or
  11717. * object is provided it will be used to create a "_.pluck" or "_.where"
  11718. * style callback, respectively.
  11719. * @param {*} [thisArg] The `this` binding of `callback`.
  11720. * @returns {Array} Returns a slice of `array`.
  11721. * @example
  11722. *
  11723. * _.rest([1, 2, 3]);
  11724. * // => [2, 3]
  11725. *
  11726. * _.rest([1, 2, 3], 2);
  11727. * // => [3]
  11728. *
  11729. * _.rest([1, 2, 3], function(num) {
  11730. * return num < 3;
  11731. * });
  11732. * // => [3]
  11733. *
  11734. * var food = [
  11735. * { 'name': 'banana', 'organic': true },
  11736. * { 'name': 'beet', 'organic': false },
  11737. * ];
  11738. *
  11739. * // using "_.pluck" callback shorthand
  11740. * _.rest(food, 'organic');
  11741. * // => [{ 'name': 'beet', 'organic': false }]
  11742. *
  11743. * var food = [
  11744. * { 'name': 'apple', 'type': 'fruit' },
  11745. * { 'name': 'banana', 'type': 'fruit' },
  11746. * { 'name': 'beet', 'type': 'vegetable' }
  11747. * ];
  11748. *
  11749. * // using "_.where" callback shorthand
  11750. * _.rest(food, { 'type': 'fruit' });
  11751. * // => [{ 'name': 'beet', 'type': 'vegetable' }]
  11752. */
  11753. function rest(array, callback, thisArg) {
  11754. if (typeof callback != 'number' && callback != null) {
  11755. var n = 0,
  11756. index = -1,
  11757. length = array ? array.length : 0;
  11758. callback = lodash.createCallback(callback, thisArg, 3);
  11759. while (++index < length && callback(array[index], index, array)) {
  11760. n++;
  11761. }
  11762. } else {
  11763. n = (callback == null || thisArg) ? 1 : nativeMax(0, callback);
  11764. }
  11765. return slice(array, n);
  11766. }
  11767. /**
  11768. * Uses a binary search to determine the smallest index at which a value
  11769. * should be inserted into a given sorted array in order to maintain the sort
  11770. * order of the array. If a callback is provided it will be executed for
  11771. * `value` and each element of `array` to compute their sort ranking. The
  11772. * callback is bound to `thisArg` and invoked with one argument; (value).
  11773. *
  11774. * If a property name is provided for `callback` the created "_.pluck" style
  11775. * callback will return the property value of the given element.
  11776. *
  11777. * If an object is provided for `callback` the created "_.where" style callback
  11778. * will return `true` for elements that have the properties of the given object,
  11779. * else `false`.
  11780. *
  11781. * @static
  11782. * @memberOf _
  11783. * @category Arrays
  11784. * @param {Array} array The array to inspect.
  11785. * @param {*} value The value to evaluate.
  11786. * @param {Function|Object|string} [callback=identity] The function called
  11787. * per iteration. If a property name or object is provided it will be used
  11788. * to create a "_.pluck" or "_.where" style callback, respectively.
  11789. * @param {*} [thisArg] The `this` binding of `callback`.
  11790. * @returns {number} Returns the index at which `value` should be inserted
  11791. * into `array`.
  11792. * @example
  11793. *
  11794. * _.sortedIndex([20, 30, 50], 40);
  11795. * // => 2
  11796. *
  11797. * // using "_.pluck" callback shorthand
  11798. * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x');
  11799. * // => 2
  11800. *
  11801. * var dict = {
  11802. * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 }
  11803. * };
  11804. *
  11805. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  11806. * return dict.wordToNumber[word];
  11807. * });
  11808. * // => 2
  11809. *
  11810. * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) {
  11811. * return this.wordToNumber[word];
  11812. * }, dict);
  11813. * // => 2
  11814. */
  11815. function sortedIndex(array, value, callback, thisArg) {
  11816. var low = 0,
  11817. high = array ? array.length : low;
  11818. // explicitly reference `identity` for better inlining in Firefox
  11819. callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity;
  11820. value = callback(value);
  11821. while (low < high) {
  11822. var mid = (low + high) >>> 1;
  11823. (callback(array[mid]) < value)
  11824. ? low = mid + 1
  11825. : high = mid;
  11826. }
  11827. return low;
  11828. }
  11829. /**
  11830. * Creates an array of unique values, in order, of the provided arrays using
  11831. * strict equality for comparisons, i.e. `===`.
  11832. *
  11833. * @static
  11834. * @memberOf _
  11835. * @category Arrays
  11836. * @param {...Array} [array] The arrays to inspect.
  11837. * @returns {Array} Returns an array of composite values.
  11838. * @example
  11839. *
  11840. * _.union([1, 2, 3], [101, 2, 1, 10], [2, 1]);
  11841. * // => [1, 2, 3, 101, 10]
  11842. */
  11843. function union(array) {
  11844. return baseUniq(baseFlatten(arguments, true, true));
  11845. }
  11846. /**
  11847. * Creates a duplicate-value-free version of an array using strict equality
  11848. * for comparisons, i.e. `===`. If the array is sorted, providing
  11849. * `true` for `isSorted` will use a faster algorithm. If a callback is provided
  11850. * each element of `array` is passed through the callback before uniqueness
  11851. * is computed. The callback is bound to `thisArg` and invoked with three
  11852. * arguments; (value, index, array).
  11853. *
  11854. * If a property name is provided for `callback` the created "_.pluck" style
  11855. * callback will return the property value of the given element.
  11856. *
  11857. * If an object is provided for `callback` the created "_.where" style callback
  11858. * will return `true` for elements that have the properties of the given object,
  11859. * else `false`.
  11860. *
  11861. * @static
  11862. * @memberOf _
  11863. * @alias unique
  11864. * @category Arrays
  11865. * @param {Array} array The array to process.
  11866. * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted.
  11867. * @param {Function|Object|string} [callback=identity] The function called
  11868. * per iteration. If a property name or object is provided it will be used
  11869. * to create a "_.pluck" or "_.where" style callback, respectively.
  11870. * @param {*} [thisArg] The `this` binding of `callback`.
  11871. * @returns {Array} Returns a duplicate-value-free array.
  11872. * @example
  11873. *
  11874. * _.uniq([1, 2, 1, 3, 1]);
  11875. * // => [1, 2, 3]
  11876. *
  11877. * _.uniq([1, 1, 2, 2, 3], true);
  11878. * // => [1, 2, 3]
  11879. *
  11880. * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); });
  11881. * // => ['A', 'b', 'C']
  11882. *
  11883. * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math);
  11884. * // => [1, 2.5, 3]
  11885. *
  11886. * // using "_.pluck" callback shorthand
  11887. * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x');
  11888. * // => [{ 'x': 1 }, { 'x': 2 }]
  11889. */
  11890. function uniq(array, isSorted, callback, thisArg) {
  11891. // juggle arguments
  11892. if (typeof isSorted != 'boolean' && isSorted != null) {
  11893. thisArg = callback;
  11894. callback = !(thisArg && thisArg[isSorted] === array) ? isSorted : null;
  11895. isSorted = false;
  11896. }
  11897. if (callback != null) {
  11898. callback = lodash.createCallback(callback, thisArg, 3);
  11899. }
  11900. return baseUniq(array, isSorted, callback);
  11901. }
  11902. /**
  11903. * Creates an array excluding all provided values using strict equality for
  11904. * comparisons, i.e. `===`.
  11905. *
  11906. * @static
  11907. * @memberOf _
  11908. * @category Arrays
  11909. * @param {Array} array The array to filter.
  11910. * @param {...*} [value] The values to exclude.
  11911. * @returns {Array} Returns a new array of filtered values.
  11912. * @example
  11913. *
  11914. * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1);
  11915. * // => [2, 3, 4]
  11916. */
  11917. function without(array) {
  11918. return difference(array, nativeSlice.call(arguments, 1));
  11919. }
  11920. /**
  11921. * Creates an array of grouped elements, the first of which contains the first
  11922. * elements of the given arrays, the second of which contains the second
  11923. * elements of the given arrays, and so on.
  11924. *
  11925. * @static
  11926. * @memberOf _
  11927. * @alias unzip
  11928. * @category Arrays
  11929. * @param {...Array} [array] Arrays to process.
  11930. * @returns {Array} Returns a new array of grouped elements.
  11931. * @example
  11932. *
  11933. * _.zip(['moe', 'larry'], [30, 40], [true, false]);
  11934. * // => [['moe', 30, true], ['larry', 40, false]]
  11935. */
  11936. function zip() {
  11937. var array = arguments.length > 1 ? arguments : arguments[0],
  11938. index = -1,
  11939. length = array ? max(pluck(array, 'length')) : 0,
  11940. result = Array(length < 0 ? 0 : length);
  11941. while (++index < length) {
  11942. result[index] = pluck(array, index);
  11943. }
  11944. return result;
  11945. }
  11946. /**
  11947. * Creates an object composed from arrays of `keys` and `values`. Provide
  11948. * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]`
  11949. * or two arrays, one of `keys` and one of corresponding `values`.
  11950. *
  11951. * @static
  11952. * @memberOf _
  11953. * @alias object
  11954. * @category Arrays
  11955. * @param {Array} keys The array of keys.
  11956. * @param {Array} [values=[]] The array of values.
  11957. * @returns {Object} Returns an object composed of the given keys and
  11958. * corresponding values.
  11959. * @example
  11960. *
  11961. * _.zipObject(['moe', 'larry'], [30, 40]);
  11962. * // => { 'moe': 30, 'larry': 40 }
  11963. */
  11964. function zipObject(keys, values) {
  11965. var index = -1,
  11966. length = keys ? keys.length : 0,
  11967. result = {};
  11968. while (++index < length) {
  11969. var key = keys[index];
  11970. if (values) {
  11971. result[key] = values[index];
  11972. } else if (key) {
  11973. result[key[0]] = key[1];
  11974. }
  11975. }
  11976. return result;
  11977. }
  11978. /*--------------------------------------------------------------------------*/
  11979. /**
  11980. * Creates a function that executes `func`, with the `this` binding and
  11981. * arguments of the created function, only after being called `n` times.
  11982. *
  11983. * @static
  11984. * @memberOf _
  11985. * @category Functions
  11986. * @param {number} n The number of times the function must be called before
  11987. * `func` is executed.
  11988. * @param {Function} func The function to restrict.
  11989. * @returns {Function} Returns the new restricted function.
  11990. * @example
  11991. *
  11992. * var saves = ['profile', 'settings'];
  11993. *
  11994. * var done = _.after(saves.length, function() {
  11995. * console.log('Done saving!');
  11996. * });
  11997. *
  11998. * _.forEach(saves, function(type) {
  11999. * asyncSave({ 'type': type, 'complete': done });
  12000. * });
  12001. * // => logs 'Done saving!', after all saves have completed
  12002. */
  12003. function after(n, func) {
  12004. if (!isFunction(func)) {
  12005. throw new TypeError;
  12006. }
  12007. return function() {
  12008. if (--n < 1) {
  12009. return func.apply(this, arguments);
  12010. }
  12011. };
  12012. }
  12013. /**
  12014. * Creates a function that, when called, invokes `func` with the `this`
  12015. * binding of `thisArg` and prepends any additional `bind` arguments to those
  12016. * provided to the bound function.
  12017. *
  12018. * @static
  12019. * @memberOf _
  12020. * @category Functions
  12021. * @param {Function} func The function to bind.
  12022. * @param {*} [thisArg] The `this` binding of `func`.
  12023. * @param {...*} [arg] Arguments to be partially applied.
  12024. * @returns {Function} Returns the new bound function.
  12025. * @example
  12026. *
  12027. * var func = function(greeting) {
  12028. * return greeting + ' ' + this.name;
  12029. * };
  12030. *
  12031. * func = _.bind(func, { 'name': 'moe' }, 'hi');
  12032. * func();
  12033. * // => 'hi moe'
  12034. */
  12035. function bind(func, thisArg) {
  12036. return arguments.length > 2
  12037. ? createBound(func, 17, nativeSlice.call(arguments, 2), null, thisArg)
  12038. : createBound(func, 1, null, null, thisArg);
  12039. }
  12040. /**
  12041. * Binds methods of an object to the object itself, overwriting the existing
  12042. * method. Method names may be specified as individual arguments or as arrays
  12043. * of method names. If no method names are provided all the function properties
  12044. * of `object` will be bound.
  12045. *
  12046. * @static
  12047. * @memberOf _
  12048. * @category Functions
  12049. * @param {Object} object The object to bind and assign the bound methods to.
  12050. * @param {...string} [methodName] The object method names to
  12051. * bind, specified as individual method names or arrays of method names.
  12052. * @returns {Object} Returns `object`.
  12053. * @example
  12054. *
  12055. * var view = {
  12056. * 'label': 'docs',
  12057. * 'onClick': function() { console.log('clicked ' + this.label); }
  12058. * };
  12059. *
  12060. * _.bindAll(view);
  12061. * jQuery('#docs').on('click', view.onClick);
  12062. * // => logs 'clicked docs', when the button is clicked
  12063. */
  12064. function bindAll(object) {
  12065. var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object),
  12066. index = -1,
  12067. length = funcs.length;
  12068. while (++index < length) {
  12069. var key = funcs[index];
  12070. object[key] = createBound(object[key], 1, null, null, object);
  12071. }
  12072. return object;
  12073. }
  12074. /**
  12075. * Creates a function that, when called, invokes the method at `object[key]`
  12076. * and prepends any additional `bindKey` arguments to those provided to the bound
  12077. * function. This method differs from `_.bind` by allowing bound functions to
  12078. * reference methods that will be redefined or don't yet exist.
  12079. * See http://michaux.ca/articles/lazy-function-definition-pattern.
  12080. *
  12081. * @static
  12082. * @memberOf _
  12083. * @category Functions
  12084. * @param {Object} object The object the method belongs to.
  12085. * @param {string} key The key of the method.
  12086. * @param {...*} [arg] Arguments to be partially applied.
  12087. * @returns {Function} Returns the new bound function.
  12088. * @example
  12089. *
  12090. * var object = {
  12091. * 'name': 'moe',
  12092. * 'greet': function(greeting) {
  12093. * return greeting + ' ' + this.name;
  12094. * }
  12095. * };
  12096. *
  12097. * var func = _.bindKey(object, 'greet', 'hi');
  12098. * func();
  12099. * // => 'hi moe'
  12100. *
  12101. * object.greet = function(greeting) {
  12102. * return greeting + ', ' + this.name + '!';
  12103. * };
  12104. *
  12105. * func();
  12106. * // => 'hi, moe!'
  12107. */
  12108. function bindKey(object, key) {
  12109. return arguments.length > 2
  12110. ? createBound(key, 19, nativeSlice.call(arguments, 2), null, object)
  12111. : createBound(key, 3, null, null, object);
  12112. }
  12113. /**
  12114. * Creates a function that is the composition of the provided functions,
  12115. * where each function consumes the return value of the function that follows.
  12116. * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`.
  12117. * Each function is executed with the `this` binding of the composed function.
  12118. *
  12119. * @static
  12120. * @memberOf _
  12121. * @category Functions
  12122. * @param {...Function} [func] Functions to compose.
  12123. * @returns {Function} Returns the new composed function.
  12124. * @example
  12125. *
  12126. * var realNameMap = {
  12127. * 'curly': 'jerome'
  12128. * };
  12129. *
  12130. * var format = function(name) {
  12131. * name = realNameMap[name.toLowerCase()] || name;
  12132. * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
  12133. * };
  12134. *
  12135. * var greet = function(formatted) {
  12136. * return 'Hiya ' + formatted + '!';
  12137. * };
  12138. *
  12139. * var welcome = _.compose(greet, format);
  12140. * welcome('curly');
  12141. * // => 'Hiya Jerome!'
  12142. */
  12143. function compose() {
  12144. var funcs = arguments,
  12145. length = funcs.length;
  12146. while (length--) {
  12147. if (!isFunction(funcs[length])) {
  12148. throw new TypeError;
  12149. }
  12150. }
  12151. return function() {
  12152. var args = arguments,
  12153. length = funcs.length;
  12154. while (length--) {
  12155. args = [funcs[length].apply(this, args)];
  12156. }
  12157. return args[0];
  12158. };
  12159. }
  12160. /**
  12161. * Produces a callback bound to an optional `thisArg`. If `func` is a property
  12162. * name the created callback will return the property value for a given element.
  12163. * If `func` is an object the created callback will return `true` for elements
  12164. * that contain the equivalent object properties, otherwise it will return `false`.
  12165. *
  12166. * @static
  12167. * @memberOf _
  12168. * @category Functions
  12169. * @param {*} [func=identity] The value to convert to a callback.
  12170. * @param {*} [thisArg] The `this` binding of the created callback.
  12171. * @param {number} [argCount] The number of arguments the callback accepts.
  12172. * @returns {Function} Returns a callback function.
  12173. * @example
  12174. *
  12175. * var stooges = [
  12176. * { 'name': 'moe', 'age': 40 },
  12177. * { 'name': 'larry', 'age': 50 }
  12178. * ];
  12179. *
  12180. * // wrap to create custom callback shorthands
  12181. * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) {
  12182. * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback);
  12183. * return !match ? func(callback, thisArg) : function(object) {
  12184. * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3];
  12185. * };
  12186. * });
  12187. *
  12188. * _.filter(stooges, 'age__gt45');
  12189. * // => [{ 'name': 'larry', 'age': 50 }]
  12190. */
  12191. function createCallback(func, thisArg, argCount) {
  12192. var type = typeof func;
  12193. if (func == null || type == 'function') {
  12194. return baseCreateCallback(func, thisArg, argCount);
  12195. }
  12196. // handle "_.pluck" style callback shorthands
  12197. if (type != 'object') {
  12198. return function(object) {
  12199. return object[func];
  12200. };
  12201. }
  12202. var props = keys(func),
  12203. key = props[0],
  12204. a = func[key];
  12205. // handle "_.where" style callback shorthands
  12206. if (props.length == 1 && a === a && !isObject(a)) {
  12207. // fast path the common case of providing an object with a single
  12208. // property containing a primitive value
  12209. return function(object) {
  12210. var b = object[key];
  12211. return a === b && (a !== 0 || (1 / a == 1 / b));
  12212. };
  12213. }
  12214. return function(object) {
  12215. var length = props.length,
  12216. result = false;
  12217. while (length--) {
  12218. if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) {
  12219. break;
  12220. }
  12221. }
  12222. return result;
  12223. };
  12224. }
  12225. /**
  12226. * Creates a function which accepts one or more arguments of `func` that when
  12227. * invoked either executes `func` returning its result, if all `func` arguments
  12228. * have been provided, or returns a function that accepts one or more of the
  12229. * remaining `func` arguments, and so on. The arity of `func` can be specified
  12230. * if `func.length` is not sufficient.
  12231. *
  12232. * @static
  12233. * @memberOf _
  12234. * @category Functions
  12235. * @param {Function} func The function to curry.
  12236. * @param {number} [arity=func.length] The arity of `func`.
  12237. * @returns {Function} Returns the new curried function.
  12238. * @example
  12239. *
  12240. * var curried = _.curry(function(a, b, c) {
  12241. * console.log(a + b + c);
  12242. * });
  12243. *
  12244. * curried(1)(2)(3);
  12245. * // => 6
  12246. *
  12247. * curried(1, 2)(3);
  12248. * // => 6
  12249. *
  12250. * curried(1, 2, 3);
  12251. * // => 6
  12252. */
  12253. function curry(func, arity) {
  12254. arity = typeof arity == 'number' ? arity : (+arity || func.length);
  12255. return createBound(func, 4, null, null, null, arity);
  12256. }
  12257. /**
  12258. * Creates a function that will delay the execution of `func` until after
  12259. * `wait` milliseconds have elapsed since the last time it was invoked.
  12260. * Provide an options object to indicate that `func` should be invoked on
  12261. * the leading and/or trailing edge of the `wait` timeout. Subsequent calls
  12262. * to the debounced function will return the result of the last `func` call.
  12263. *
  12264. * Note: If `leading` and `trailing` options are `true` `func` will be called
  12265. * on the trailing edge of the timeout only if the the debounced function is
  12266. * invoked more than once during the `wait` timeout.
  12267. *
  12268. * @static
  12269. * @memberOf _
  12270. * @category Functions
  12271. * @param {Function} func The function to debounce.
  12272. * @param {number} wait The number of milliseconds to delay.
  12273. * @param {Object} [options] The options object.
  12274. * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout.
  12275. * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called.
  12276. * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
  12277. * @returns {Function} Returns the new debounced function.
  12278. * @example
  12279. *
  12280. * // avoid costly calculations while the window size is in flux
  12281. * var lazyLayout = _.debounce(calculateLayout, 150);
  12282. * jQuery(window).on('resize', lazyLayout);
  12283. *
  12284. * // execute `sendMail` when the click event is fired, debouncing subsequent calls
  12285. * jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
  12286. * 'leading': true,
  12287. * 'trailing': false
  12288. * });
  12289. *
  12290. * // ensure `batchLog` is executed once after 1 second of debounced calls
  12291. * var source = new EventSource('/stream');
  12292. * source.addEventListener('message', _.debounce(batchLog, 250, {
  12293. * 'maxWait': 1000
  12294. * }, false);
  12295. */
  12296. function debounce(func, wait, options) {
  12297. var args,
  12298. maxTimeoutId,
  12299. result,
  12300. stamp,
  12301. thisArg,
  12302. timeoutId,
  12303. trailingCall,
  12304. lastCalled = 0,
  12305. maxWait = false,
  12306. trailing = true;
  12307. if (!isFunction(func)) {
  12308. throw new TypeError;
  12309. }
  12310. wait = nativeMax(0, wait) || 0;
  12311. if (options === true) {
  12312. var leading = true;
  12313. trailing = false;
  12314. } else if (isObject(options)) {
  12315. leading = options.leading;
  12316. maxWait = 'maxWait' in options && (nativeMax(wait, options.maxWait) || 0);
  12317. trailing = 'trailing' in options ? options.trailing : trailing;
  12318. }
  12319. var delayed = function() {
  12320. var remaining = wait - (now() - stamp);
  12321. if (remaining <= 0) {
  12322. if (maxTimeoutId) {
  12323. clearTimeout(maxTimeoutId);
  12324. }
  12325. var isCalled = trailingCall;
  12326. maxTimeoutId = timeoutId = trailingCall = undefined;
  12327. if (isCalled) {
  12328. lastCalled = now();
  12329. result = func.apply(thisArg, args);
  12330. }
  12331. } else {
  12332. timeoutId = setTimeout(delayed, remaining);
  12333. }
  12334. };
  12335. var maxDelayed = function() {
  12336. if (timeoutId) {
  12337. clearTimeout(timeoutId);
  12338. }
  12339. maxTimeoutId = timeoutId = trailingCall = undefined;
  12340. if (trailing || (maxWait !== wait)) {
  12341. lastCalled = now();
  12342. result = func.apply(thisArg, args);
  12343. }
  12344. };
  12345. return function() {
  12346. args = arguments;
  12347. stamp = now();
  12348. thisArg = this;
  12349. trailingCall = trailing && (timeoutId || !leading);
  12350. if (maxWait === false) {
  12351. var leadingCall = leading && !timeoutId;
  12352. } else {
  12353. if (!maxTimeoutId && !leading) {
  12354. lastCalled = stamp;
  12355. }
  12356. var remaining = maxWait - (stamp - lastCalled);
  12357. if (remaining <= 0) {
  12358. if (maxTimeoutId) {
  12359. maxTimeoutId = clearTimeout(maxTimeoutId);
  12360. }
  12361. lastCalled = stamp;
  12362. result = func.apply(thisArg, args);
  12363. }
  12364. else if (!maxTimeoutId) {
  12365. maxTimeoutId = setTimeout(maxDelayed, remaining);
  12366. }
  12367. }
  12368. if (!timeoutId && wait !== maxWait) {
  12369. timeoutId = setTimeout(delayed, wait);
  12370. }
  12371. if (leadingCall) {
  12372. result = func.apply(thisArg, args);
  12373. }
  12374. return result;
  12375. };
  12376. }
  12377. /**
  12378. * Defers executing the `func` function until the current call stack has cleared.
  12379. * Additional arguments will be provided to `func` when it is invoked.
  12380. *
  12381. * @static
  12382. * @memberOf _
  12383. * @category Functions
  12384. * @param {Function} func The function to defer.
  12385. * @param {...*} [arg] Arguments to invoke the function with.
  12386. * @returns {number} Returns the timer id.
  12387. * @example
  12388. *
  12389. * _.defer(function() { console.log('deferred'); });
  12390. * // returns from the function before 'deferred' is logged
  12391. */
  12392. function defer(func) {
  12393. if (!isFunction(func)) {
  12394. throw new TypeError;
  12395. }
  12396. var args = nativeSlice.call(arguments, 1);
  12397. return setTimeout(function() { func.apply(undefined, args); }, 1);
  12398. }
  12399. // use `setImmediate` if available in Node.js
  12400. if (isV8 && moduleExports && typeof setImmediate == 'function') {
  12401. defer = function(func) {
  12402. if (!isFunction(func)) {
  12403. throw new TypeError;
  12404. }
  12405. return setImmediate.apply(context, arguments);
  12406. };
  12407. }
  12408. /**
  12409. * Executes the `func` function after `wait` milliseconds. Additional arguments
  12410. * will be provided to `func` when it is invoked.
  12411. *
  12412. * @static
  12413. * @memberOf _
  12414. * @category Functions
  12415. * @param {Function} func The function to delay.
  12416. * @param {number} wait The number of milliseconds to delay execution.
  12417. * @param {...*} [arg] Arguments to invoke the function with.
  12418. * @returns {number} Returns the timer id.
  12419. * @example
  12420. *
  12421. * var log = _.bind(console.log, console);
  12422. * _.delay(log, 1000, 'logged later');
  12423. * // => 'logged later' (Appears after one second.)
  12424. */
  12425. function delay(func, wait) {
  12426. if (!isFunction(func)) {
  12427. throw new TypeError;
  12428. }
  12429. var args = nativeSlice.call(arguments, 2);
  12430. return setTimeout(function() { func.apply(undefined, args); }, wait);
  12431. }
  12432. /**
  12433. * Creates a function that memoizes the result of `func`. If `resolver` is
  12434. * provided it will be used to determine the cache key for storing the result
  12435. * based on the arguments provided to the memoized function. By default, the
  12436. * first argument provided to the memoized function is used as the cache key.
  12437. * The `func` is executed with the `this` binding of the memoized function.
  12438. * The result cache is exposed as the `cache` property on the memoized function.
  12439. *
  12440. * @static
  12441. * @memberOf _
  12442. * @category Functions
  12443. * @param {Function} func The function to have its output memoized.
  12444. * @param {Function} [resolver] A function used to resolve the cache key.
  12445. * @returns {Function} Returns the new memoizing function.
  12446. * @example
  12447. *
  12448. * var fibonacci = _.memoize(function(n) {
  12449. * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);
  12450. * });
  12451. *
  12452. * var data = {
  12453. * 'moe': { 'name': 'moe', 'age': 40 },
  12454. * 'curly': { 'name': 'curly', 'age': 60 }
  12455. * };
  12456. *
  12457. * // modifying the result cache
  12458. * var stooge = _.memoize(function(name) { return data[name]; }, _.identity);
  12459. * stooge('curly');
  12460. * // => { 'name': 'curly', 'age': 60 }
  12461. *
  12462. * stooge.cache.curly.name = 'jerome';
  12463. * stooge('curly');
  12464. * // => { 'name': 'jerome', 'age': 60 }
  12465. */
  12466. function memoize(func, resolver) {
  12467. if (!isFunction(func)) {
  12468. throw new TypeError;
  12469. }
  12470. var memoized = function() {
  12471. var cache = memoized.cache,
  12472. key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0];
  12473. return hasOwnProperty.call(cache, key)
  12474. ? cache[key]
  12475. : (cache[key] = func.apply(this, arguments));
  12476. }
  12477. memoized.cache = {};
  12478. return memoized;
  12479. }
  12480. /**
  12481. * Creates a function that is restricted to execute `func` once. Repeat calls to
  12482. * the function will return the value of the first call. The `func` is executed
  12483. * with the `this` binding of the created function.
  12484. *
  12485. * @static
  12486. * @memberOf _
  12487. * @category Functions
  12488. * @param {Function} func The function to restrict.
  12489. * @returns {Function} Returns the new restricted function.
  12490. * @example
  12491. *
  12492. * var initialize = _.once(createApplication);
  12493. * initialize();
  12494. * initialize();
  12495. * // `initialize` executes `createApplication` once
  12496. */
  12497. function once(func) {
  12498. var ran,
  12499. result;
  12500. if (!isFunction(func)) {
  12501. throw new TypeError;
  12502. }
  12503. return function() {
  12504. if (ran) {
  12505. return result;
  12506. }
  12507. ran = true;
  12508. result = func.apply(this, arguments);
  12509. // clear the `func` variable so the function may be garbage collected
  12510. func = null;
  12511. return result;
  12512. };
  12513. }
  12514. /**
  12515. * Creates a function that, when called, invokes `func` with any additional
  12516. * `partial` arguments prepended to those provided to the new function. This
  12517. * method is similar to `_.bind` except it does **not** alter the `this` binding.
  12518. *
  12519. * @static
  12520. * @memberOf _
  12521. * @category Functions
  12522. * @param {Function} func The function to partially apply arguments to.
  12523. * @param {...*} [arg] Arguments to be partially applied.
  12524. * @returns {Function} Returns the new partially applied function.
  12525. * @example
  12526. *
  12527. * var greet = function(greeting, name) { return greeting + ' ' + name; };
  12528. * var hi = _.partial(greet, 'hi');
  12529. * hi('moe');
  12530. * // => 'hi moe'
  12531. */
  12532. function partial(func) {
  12533. return createBound(func, 16, nativeSlice.call(arguments, 1));
  12534. }
  12535. /**
  12536. * This method is like `_.partial` except that `partial` arguments are
  12537. * appended to those provided to the new function.
  12538. *
  12539. * @static
  12540. * @memberOf _
  12541. * @category Functions
  12542. * @param {Function} func The function to partially apply arguments to.
  12543. * @param {...*} [arg] Arguments to be partially applied.
  12544. * @returns {Function} Returns the new partially applied function.
  12545. * @example
  12546. *
  12547. * var defaultsDeep = _.partialRight(_.merge, _.defaults);
  12548. *
  12549. * var options = {
  12550. * 'variable': 'data',
  12551. * 'imports': { 'jq': $ }
  12552. * };
  12553. *
  12554. * defaultsDeep(options, _.templateSettings);
  12555. *
  12556. * options.variable
  12557. * // => 'data'
  12558. *
  12559. * options.imports
  12560. * // => { '_': _, 'jq': $ }
  12561. */
  12562. function partialRight(func) {
  12563. return createBound(func, 32, null, nativeSlice.call(arguments, 1));
  12564. }
  12565. /**
  12566. * Creates a function that, when executed, will only call the `func` function
  12567. * at most once per every `wait` milliseconds. Provide an options object to
  12568. * indicate that `func` should be invoked on the leading and/or trailing edge
  12569. * of the `wait` timeout. Subsequent calls to the throttled function will
  12570. * return the result of the last `func` call.
  12571. *
  12572. * Note: If `leading` and `trailing` options are `true` `func` will be called
  12573. * on the trailing edge of the timeout only if the the throttled function is
  12574. * invoked more than once during the `wait` timeout.
  12575. *
  12576. * @static
  12577. * @memberOf _
  12578. * @category Functions
  12579. * @param {Function} func The function to throttle.
  12580. * @param {number} wait The number of milliseconds to throttle executions to.
  12581. * @param {Object} [options] The options object.
  12582. * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout.
  12583. * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout.
  12584. * @returns {Function} Returns the new throttled function.
  12585. * @example
  12586. *
  12587. * // avoid excessively updating the position while scrolling
  12588. * var throttled = _.throttle(updatePosition, 100);
  12589. * jQuery(window).on('scroll', throttled);
  12590. *
  12591. * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes
  12592. * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
  12593. * 'trailing': false
  12594. * }));
  12595. */
  12596. function throttle(func, wait, options) {
  12597. var leading = true,
  12598. trailing = true;
  12599. if (!isFunction(func)) {
  12600. throw new TypeError;
  12601. }
  12602. if (options === false) {
  12603. leading = false;
  12604. } else if (isObject(options)) {
  12605. leading = 'leading' in options ? options.leading : leading;
  12606. trailing = 'trailing' in options ? options.trailing : trailing;
  12607. }
  12608. debounceOptions.leading = leading;
  12609. debounceOptions.maxWait = wait;
  12610. debounceOptions.trailing = trailing;
  12611. var result = debounce(func, wait, debounceOptions);
  12612. return result;
  12613. }
  12614. /**
  12615. * Creates a function that provides `value` to the wrapper function as its
  12616. * first argument. Additional arguments provided to the function are appended
  12617. * to those provided to the wrapper function. The wrapper is executed with
  12618. * the `this` binding of the created function.
  12619. *
  12620. * @static
  12621. * @memberOf _
  12622. * @category Functions
  12623. * @param {*} value The value to wrap.
  12624. * @param {Function} wrapper The wrapper function.
  12625. * @returns {Function} Returns the new function.
  12626. * @example
  12627. *
  12628. * var hello = function(name) { return 'hello ' + name; };
  12629. * hello = _.wrap(hello, function(func) {
  12630. * return 'before, ' + func('moe') + ', after';
  12631. * });
  12632. * hello();
  12633. * // => 'before, hello moe, after'
  12634. */
  12635. function wrap(value, wrapper) {
  12636. if (!isFunction(wrapper)) {
  12637. throw new TypeError;
  12638. }
  12639. return function() {
  12640. var args = [value];
  12641. push.apply(args, arguments);
  12642. return wrapper.apply(this, args);
  12643. };
  12644. }
  12645. /*--------------------------------------------------------------------------*/
  12646. /**
  12647. * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their
  12648. * corresponding HTML entities.
  12649. *
  12650. * @static
  12651. * @memberOf _
  12652. * @category Utilities
  12653. * @param {string} string The string to escape.
  12654. * @returns {string} Returns the escaped string.
  12655. * @example
  12656. *
  12657. * _.escape('Moe, Larry & Curly');
  12658. * // => 'Moe, Larry &amp; Curly'
  12659. */
  12660. function escape(string) {
  12661. return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar);
  12662. }
  12663. /**
  12664. * This method returns the first argument provided to it.
  12665. *
  12666. * @static
  12667. * @memberOf _
  12668. * @category Utilities
  12669. * @param {*} value Any value.
  12670. * @returns {*} Returns `value`.
  12671. * @example
  12672. *
  12673. * var moe = { 'name': 'moe' };
  12674. * moe === _.identity(moe);
  12675. * // => true
  12676. */
  12677. function identity(value) {
  12678. return value;
  12679. }
  12680. /**
  12681. * Adds function properties of a source object to the `lodash` function and
  12682. * chainable wrapper.
  12683. *
  12684. * @static
  12685. * @memberOf _
  12686. * @category Utilities
  12687. * @param {Object} object The object of function properties to add to `lodash`.
  12688. * @param {Object} object The object of function properties to add to `lodash`.
  12689. * @example
  12690. *
  12691. * _.mixin({
  12692. * 'capitalize': function(string) {
  12693. * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase();
  12694. * }
  12695. * });
  12696. *
  12697. * _.capitalize('moe');
  12698. * // => 'Moe'
  12699. *
  12700. * _('moe').capitalize();
  12701. * // => 'Moe'
  12702. */
  12703. function mixin(object, source) {
  12704. var ctor = object,
  12705. isFunc = !source || isFunction(ctor);
  12706. if (!source) {
  12707. ctor = lodashWrapper;
  12708. source = object;
  12709. object = lodash;
  12710. }
  12711. forEach(functions(source), function(methodName) {
  12712. var func = object[methodName] = source[methodName];
  12713. if (isFunc) {
  12714. ctor.prototype[methodName] = function() {
  12715. var value = this.__wrapped__,
  12716. args = [value];
  12717. push.apply(args, arguments);
  12718. var result = func.apply(object, args);
  12719. if (value && typeof value == 'object' && value === result) {
  12720. return this;
  12721. }
  12722. result = new ctor(result);
  12723. result.__chain__ = this.__chain__;
  12724. return result;
  12725. };
  12726. }
  12727. });
  12728. }
  12729. /**
  12730. * Reverts the '_' variable to its previous value and returns a reference to
  12731. * the `lodash` function.
  12732. *
  12733. * @static
  12734. * @memberOf _
  12735. * @category Utilities
  12736. * @returns {Function} Returns the `lodash` function.
  12737. * @example
  12738. *
  12739. * var lodash = _.noConflict();
  12740. */
  12741. function noConflict() {
  12742. context._ = oldDash;
  12743. return this;
  12744. }
  12745. /**
  12746. * Converts the given value into an integer of the specified radix.
  12747. * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the
  12748. * `value` is a hexadecimal, in which case a `radix` of `16` is used.
  12749. *
  12750. * Note: This method avoids differences in native ES3 and ES5 `parseInt`
  12751. * implementations. See http://es5.github.io/#E.
  12752. *
  12753. * @static
  12754. * @memberOf _
  12755. * @category Utilities
  12756. * @param {string} value The value to parse.
  12757. * @param {number} [radix] The radix used to interpret the value to parse.
  12758. * @returns {number} Returns the new integer value.
  12759. * @example
  12760. *
  12761. * _.parseInt('08');
  12762. * // => 8
  12763. */
  12764. var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) {
  12765. // Firefox and Opera still follow the ES3 specified implementation of `parseInt`
  12766. return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0);
  12767. };
  12768. /**
  12769. * Produces a random number between `min` and `max` (inclusive). If only one
  12770. * argument is provided a number between `0` and the given number will be
  12771. * returned. If `floating` is truey or either `min` or `max` are floats a
  12772. * floating-point number will be returned instead of an integer.
  12773. *
  12774. * @static
  12775. * @memberOf _
  12776. * @category Utilities
  12777. * @param {number} [min=0] The minimum possible value.
  12778. * @param {number} [max=1] The maximum possible value.
  12779. * @param {boolean} [floating=false] Specify returning a floating-point number.
  12780. * @returns {number} Returns a random number.
  12781. * @example
  12782. *
  12783. * _.random(0, 5);
  12784. * // => an integer between 0 and 5
  12785. *
  12786. * _.random(5);
  12787. * // => also an integer between 0 and 5
  12788. *
  12789. * _.random(5, true);
  12790. * // => a floating-point number between 0 and 5
  12791. *
  12792. * _.random(1.2, 5.2);
  12793. * // => a floating-point number between 1.2 and 5.2
  12794. */
  12795. function random(min, max, floating) {
  12796. var noMin = min == null,
  12797. noMax = max == null;
  12798. if (floating == null) {
  12799. if (typeof min == 'boolean' && noMax) {
  12800. floating = min;
  12801. min = 1;
  12802. }
  12803. else if (!noMax && typeof max == 'boolean') {
  12804. floating = max;
  12805. noMax = true;
  12806. }
  12807. }
  12808. if (noMin && noMax) {
  12809. max = 1;
  12810. }
  12811. min = +min || 0;
  12812. if (noMax) {
  12813. max = min;
  12814. min = 0;
  12815. } else {
  12816. max = +max || 0;
  12817. }
  12818. var rand = nativeRandom();
  12819. return (floating || min % 1 || max % 1)
  12820. ? nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand +'').length - 1)))), max)
  12821. : min + floor(rand * (max - min + 1));
  12822. }
  12823. /**
  12824. * Resolves the value of `property` on `object`. If `property` is a function
  12825. * it will be invoked with the `this` binding of `object` and its result returned,
  12826. * else the property value is returned. If `object` is falsey then `undefined`
  12827. * is returned.
  12828. *
  12829. * @static
  12830. * @memberOf _
  12831. * @category Utilities
  12832. * @param {Object} object The object to inspect.
  12833. * @param {string} property The property to get the value of.
  12834. * @returns {*} Returns the resolved value.
  12835. * @example
  12836. *
  12837. * var object = {
  12838. * 'cheese': 'crumpets',
  12839. * 'stuff': function() {
  12840. * return 'nonsense';
  12841. * }
  12842. * };
  12843. *
  12844. * _.result(object, 'cheese');
  12845. * // => 'crumpets'
  12846. *
  12847. * _.result(object, 'stuff');
  12848. * // => 'nonsense'
  12849. */
  12850. function result(object, property) {
  12851. if (object) {
  12852. var value = object[property];
  12853. return isFunction(value) ? object[property]() : value;
  12854. }
  12855. }
  12856. /**
  12857. * A micro-templating method that handles arbitrary delimiters, preserves
  12858. * whitespace, and correctly escapes quotes within interpolated code.
  12859. *
  12860. * Note: In the development build, `_.template` utilizes sourceURLs for easier
  12861. * debugging. See http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  12862. *
  12863. * For more information on precompiling templates see:
  12864. * http://lodash.com/#custom-builds
  12865. *
  12866. * For more information on Chrome extension sandboxes see:
  12867. * http://developer.chrome.com/stable/extensions/sandboxingEval.html
  12868. *
  12869. * @static
  12870. * @memberOf _
  12871. * @category Utilities
  12872. * @param {string} text The template text.
  12873. * @param {Object} data The data object used to populate the text.
  12874. * @param {Object} [options] The options object.
  12875. * @param {RegExp} [options.escape] The "escape" delimiter.
  12876. * @param {RegExp} [options.evaluate] The "evaluate" delimiter.
  12877. * @param {Object} [options.imports] An object to import into the template as local variables.
  12878. * @param {RegExp} [options.interpolate] The "interpolate" delimiter.
  12879. * @param {string} [sourceURL] The sourceURL of the template's compiled source.
  12880. * @param {string} [variable] The data object variable name.
  12881. * @returns {Function|string} Returns a compiled function when no `data` object
  12882. * is given, else it returns the interpolated text.
  12883. * @example
  12884. *
  12885. * // using the "interpolate" delimiter to create a compiled template
  12886. * var compiled = _.template('hello <%= name %>');
  12887. * compiled({ 'name': 'moe' });
  12888. * // => 'hello moe'
  12889. *
  12890. * // using the "escape" delimiter to escape HTML in data property values
  12891. * _.template('<b><%- value %></b>', { 'value': '<script>' });
  12892. * // => '<b>&lt;script&gt;</b>'
  12893. *
  12894. * // using the "evaluate" delimiter to generate HTML
  12895. * var list = '<% _.forEach(people, function(name) { %><li><%- name %></li><% }); %>';
  12896. * _.template(list, { 'people': ['moe', 'larry'] });
  12897. * // => '<li>moe</li><li>larry</li>'
  12898. *
  12899. * // using the ES6 delimiter as an alternative to the default "interpolate" delimiter
  12900. * _.template('hello ${ name }', { 'name': 'curly' });
  12901. * // => 'hello curly'
  12902. *
  12903. * // using the internal `print` function in "evaluate" delimiters
  12904. * _.template('<% print("hello " + name); %>!', { 'name': 'larry' });
  12905. * // => 'hello larry!'
  12906. *
  12907. * // using a custom template delimiters
  12908. * _.templateSettings = {
  12909. * 'interpolate': /{{([\s\S]+?)}}/g
  12910. * };
  12911. *
  12912. * _.template('hello {{ name }}!', { 'name': 'mustache' });
  12913. * // => 'hello mustache!'
  12914. *
  12915. * // using the `imports` option to import jQuery
  12916. * var list = '<% $.each(people, function(name) { %><li><%- name %></li><% }); %>';
  12917. * _.template(list, { 'people': ['moe', 'larry'] }, { 'imports': { '$': jQuery } });
  12918. * // => '<li>moe</li><li>larry</li>'
  12919. *
  12920. * // using the `sourceURL` option to specify a custom sourceURL for the template
  12921. * var compiled = _.template('hello <%= name %>', null, { 'sourceURL': '/basic/greeting.jst' });
  12922. * compiled(data);
  12923. * // => find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector
  12924. *
  12925. * // using the `variable` option to ensure a with-statement isn't used in the compiled template
  12926. * var compiled = _.template('hi <%= data.name %>!', null, { 'variable': 'data' });
  12927. * compiled.source;
  12928. * // => function(data) {
  12929. * var __t, __p = '', __e = _.escape;
  12930. * __p += 'hi ' + ((__t = ( data.name )) == null ? '' : __t) + '!';
  12931. * return __p;
  12932. * }
  12933. *
  12934. * // using the `source` property to inline compiled templates for meaningful
  12935. * // line numbers in error messages and a stack trace
  12936. * fs.writeFileSync(path.join(cwd, 'jst.js'), '\
  12937. * var JST = {\
  12938. * "main": ' + _.template(mainText).source + '\
  12939. * };\
  12940. * ');
  12941. */
  12942. function template(text, data, options) {
  12943. // based on John Resig's `tmpl` implementation
  12944. // http://ejohn.org/blog/javascript-micro-templating/
  12945. // and Laura Doktorova's doT.js
  12946. // https://github.com/olado/doT
  12947. var settings = lodash.templateSettings;
  12948. text || (text = '');
  12949. // avoid missing dependencies when `iteratorTemplate` is not defined
  12950. options = defaults({}, options, settings);
  12951. var imports = defaults({}, options.imports, settings.imports),
  12952. importsKeys = keys(imports),
  12953. importsValues = values(imports);
  12954. var isEvaluating,
  12955. index = 0,
  12956. interpolate = options.interpolate || reNoMatch,
  12957. source = "__p += '";
  12958. // compile the regexp to match each delimiter
  12959. var reDelimiters = RegExp(
  12960. (options.escape || reNoMatch).source + '|' +
  12961. interpolate.source + '|' +
  12962. (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' +
  12963. (options.evaluate || reNoMatch).source + '|$'
  12964. , 'g');
  12965. text.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) {
  12966. interpolateValue || (interpolateValue = esTemplateValue);
  12967. // escape characters that cannot be included in string literals
  12968. source += text.slice(index, offset).replace(reUnescapedString, escapeStringChar);
  12969. // replace delimiters with snippets
  12970. if (escapeValue) {
  12971. source += "' +\n__e(" + escapeValue + ") +\n'";
  12972. }
  12973. if (evaluateValue) {
  12974. isEvaluating = true;
  12975. source += "';\n" + evaluateValue + ";\n__p += '";
  12976. }
  12977. if (interpolateValue) {
  12978. source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'";
  12979. }
  12980. index = offset + match.length;
  12981. // the JS engine embedded in Adobe products requires returning the `match`
  12982. // string in order to produce the correct `offset` value
  12983. return match;
  12984. });
  12985. source += "';\n";
  12986. // if `variable` is not specified, wrap a with-statement around the generated
  12987. // code to add the data object to the top of the scope chain
  12988. var variable = options.variable,
  12989. hasVariable = variable;
  12990. if (!hasVariable) {
  12991. variable = 'obj';
  12992. source = 'with (' + variable + ') {\n' + source + '\n}\n';
  12993. }
  12994. // cleanup code by stripping empty strings
  12995. source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source)
  12996. .replace(reEmptyStringMiddle, '$1')
  12997. .replace(reEmptyStringTrailing, '$1;');
  12998. // frame code as the function body
  12999. source = 'function(' + variable + ') {\n' +
  13000. (hasVariable ? '' : variable + ' || (' + variable + ' = {});\n') +
  13001. "var __t, __p = '', __e = _.escape" +
  13002. (isEvaluating
  13003. ? ', __j = Array.prototype.join;\n' +
  13004. "function print() { __p += __j.call(arguments, '') }\n"
  13005. : ';\n'
  13006. ) +
  13007. source +
  13008. 'return __p\n}';
  13009. // Use a sourceURL for easier debugging.
  13010. // http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl
  13011. var sourceURL = '\n/*\n//# sourceURL=' + (options.sourceURL || '/lodash/template/source[' + (templateCounter++) + ']') + '\n*/';
  13012. try {
  13013. var result = Function(importsKeys, 'return ' + source + sourceURL).apply(undefined, importsValues);
  13014. } catch(e) {
  13015. e.source = source;
  13016. throw e;
  13017. }
  13018. if (data) {
  13019. return result(data);
  13020. }
  13021. // provide the compiled function's source by its `toString` method, in
  13022. // supported environments, or the `source` property as a convenience for
  13023. // inlining compiled templates during the build process
  13024. result.source = source;
  13025. return result;
  13026. }
  13027. /**
  13028. * Executes the callback `n` times, returning an array of the results
  13029. * of each callback execution. The callback is bound to `thisArg` and invoked
  13030. * with one argument; (index).
  13031. *
  13032. * @static
  13033. * @memberOf _
  13034. * @category Utilities
  13035. * @param {number} n The number of times to execute the callback.
  13036. * @param {Function} callback The function called per iteration.
  13037. * @param {*} [thisArg] The `this` binding of `callback`.
  13038. * @returns {Array} Returns an array of the results of each `callback` execution.
  13039. * @example
  13040. *
  13041. * var diceRolls = _.times(3, _.partial(_.random, 1, 6));
  13042. * // => [3, 6, 4]
  13043. *
  13044. * _.times(3, function(n) { mage.castSpell(n); });
  13045. * // => calls `mage.castSpell(n)` three times, passing `n` of `0`, `1`, and `2` respectively
  13046. *
  13047. * _.times(3, function(n) { this.cast(n); }, mage);
  13048. * // => also calls `mage.castSpell(n)` three times
  13049. */
  13050. function times(n, callback, thisArg) {
  13051. n = (n = +n) > -1 ? n : 0;
  13052. var index = -1,
  13053. result = Array(n);
  13054. callback = baseCreateCallback(callback, thisArg, 1);
  13055. while (++index < n) {
  13056. result[index] = callback(index);
  13057. }
  13058. return result;
  13059. }
  13060. /**
  13061. * The inverse of `_.escape` this method converts the HTML entities
  13062. * `&amp;`, `&lt;`, `&gt;`, `&quot;`, and `&#39;` in `string` to their
  13063. * corresponding characters.
  13064. *
  13065. * @static
  13066. * @memberOf _
  13067. * @category Utilities
  13068. * @param {string} string The string to unescape.
  13069. * @returns {string} Returns the unescaped string.
  13070. * @example
  13071. *
  13072. * _.unescape('Moe, Larry &amp; Curly');
  13073. * // => 'Moe, Larry & Curly'
  13074. */
  13075. function unescape(string) {
  13076. return string == null ? '' : String(string).replace(reEscapedHtml, unescapeHtmlChar);
  13077. }
  13078. /**
  13079. * Generates a unique ID. If `prefix` is provided the ID will be appended to it.
  13080. *
  13081. * @static
  13082. * @memberOf _
  13083. * @category Utilities
  13084. * @param {string} [prefix] The value to prefix the ID with.
  13085. * @returns {string} Returns the unique ID.
  13086. * @example
  13087. *
  13088. * _.uniqueId('contact_');
  13089. * // => 'contact_104'
  13090. *
  13091. * _.uniqueId();
  13092. * // => '105'
  13093. */
  13094. function uniqueId(prefix) {
  13095. var id = ++idCounter;
  13096. return String(prefix == null ? '' : prefix) + id;
  13097. }
  13098. /*--------------------------------------------------------------------------*/
  13099. /**
  13100. * Creates a `lodash` object that wraps the given value with explicit
  13101. * method chaining enabled.
  13102. *
  13103. * @static
  13104. * @memberOf _
  13105. * @category Chaining
  13106. * @param {*} value The value to wrap.
  13107. * @returns {Object} Returns the wrapper object.
  13108. * @example
  13109. *
  13110. * var stooges = [
  13111. * { 'name': 'moe', 'age': 40 },
  13112. * { 'name': 'larry', 'age': 50 },
  13113. * { 'name': 'curly', 'age': 60 }
  13114. * ];
  13115. *
  13116. * var youngest = _.chain(stooges)
  13117. * .sortBy('age')
  13118. * .map(function(stooge) { return stooge.name + ' is ' + stooge.age; })
  13119. * .first()
  13120. * .value();
  13121. * // => 'moe is 40'
  13122. */
  13123. function chain(value) {
  13124. value = new lodashWrapper(value);
  13125. value.__chain__ = true;
  13126. return value;
  13127. }
  13128. /**
  13129. * Invokes `interceptor` with the `value` as the first argument and then
  13130. * returns `value`. The purpose of this method is to "tap into" a method
  13131. * chain in order to perform operations on intermediate results within
  13132. * the chain.
  13133. *
  13134. * @static
  13135. * @memberOf _
  13136. * @category Chaining
  13137. * @param {*} value The value to provide to `interceptor`.
  13138. * @param {Function} interceptor The function to invoke.
  13139. * @returns {*} Returns `value`.
  13140. * @example
  13141. *
  13142. * _([1, 2, 3, 4])
  13143. * .filter(function(num) { return num % 2 == 0; })
  13144. * .tap(function(array) { console.log(array); })
  13145. * .map(function(num) { return num * num; })
  13146. * .value();
  13147. * // => // [2, 4] (logged)
  13148. * // => [4, 16]
  13149. */
  13150. function tap(value, interceptor) {
  13151. interceptor(value);
  13152. return value;
  13153. }
  13154. /**
  13155. * Enables explicit method chaining on the wrapper object.
  13156. *
  13157. * @name chain
  13158. * @memberOf _
  13159. * @category Chaining
  13160. * @returns {*} Returns the wrapper object.
  13161. * @example
  13162. *
  13163. * var stooges = [
  13164. * { 'name': 'moe', 'age': 40 },
  13165. * { 'name': 'larry', 'age': 50 }
  13166. * ];
  13167. *
  13168. * // without explicit chaining
  13169. * _(stooges).first();
  13170. * // => { 'name': 'moe', 'age': 40 }
  13171. *
  13172. * // with explicit chaining
  13173. * _(stooges).chain()
  13174. * .first()
  13175. * .pick('age')
  13176. * .value()
  13177. * // => { 'age': 40 }
  13178. */
  13179. function wrapperChain() {
  13180. this.__chain__ = true;
  13181. return this;
  13182. }
  13183. /**
  13184. * Produces the `toString` result of the wrapped value.
  13185. *
  13186. * @name toString
  13187. * @memberOf _
  13188. * @category Chaining
  13189. * @returns {string} Returns the string result.
  13190. * @example
  13191. *
  13192. * _([1, 2, 3]).toString();
  13193. * // => '1,2,3'
  13194. */
  13195. function wrapperToString() {
  13196. return String(this.__wrapped__);
  13197. }
  13198. /**
  13199. * Extracts the wrapped value.
  13200. *
  13201. * @name valueOf
  13202. * @memberOf _
  13203. * @alias value
  13204. * @category Chaining
  13205. * @returns {*} Returns the wrapped value.
  13206. * @example
  13207. *
  13208. * _([1, 2, 3]).valueOf();
  13209. * // => [1, 2, 3]
  13210. */
  13211. function wrapperValueOf() {
  13212. return this.__wrapped__;
  13213. }
  13214. /*--------------------------------------------------------------------------*/
  13215. // add functions that return wrapped values when chaining
  13216. lodash.after = after;
  13217. lodash.assign = assign;
  13218. lodash.at = at;
  13219. lodash.bind = bind;
  13220. lodash.bindAll = bindAll;
  13221. lodash.bindKey = bindKey;
  13222. lodash.chain = chain;
  13223. lodash.compact = compact;
  13224. lodash.compose = compose;
  13225. lodash.countBy = countBy;
  13226. lodash.createCallback = createCallback;
  13227. lodash.curry = curry;
  13228. lodash.debounce = debounce;
  13229. lodash.defaults = defaults;
  13230. lodash.defer = defer;
  13231. lodash.delay = delay;
  13232. lodash.difference = difference;
  13233. lodash.filter = filter;
  13234. lodash.flatten = flatten;
  13235. lodash.forEach = forEach;
  13236. lodash.forEachRight = forEachRight;
  13237. lodash.forIn = forIn;
  13238. lodash.forInRight = forInRight;
  13239. lodash.forOwn = forOwn;
  13240. lodash.forOwnRight = forOwnRight;
  13241. lodash.functions = functions;
  13242. lodash.groupBy = groupBy;
  13243. lodash.indexBy = indexBy;
  13244. lodash.initial = initial;
  13245. lodash.intersection = intersection;
  13246. lodash.invert = invert;
  13247. lodash.invoke = invoke;
  13248. lodash.keys = keys;
  13249. lodash.map = map;
  13250. lodash.max = max;
  13251. lodash.memoize = memoize;
  13252. lodash.merge = merge;
  13253. lodash.min = min;
  13254. lodash.omit = omit;
  13255. lodash.once = once;
  13256. lodash.pairs = pairs;
  13257. lodash.partial = partial;
  13258. lodash.partialRight = partialRight;
  13259. lodash.pick = pick;
  13260. lodash.pluck = pluck;
  13261. lodash.pull = pull;
  13262. lodash.range = range;
  13263. lodash.reject = reject;
  13264. lodash.remove = remove;
  13265. lodash.rest = rest;
  13266. lodash.shuffle = shuffle;
  13267. lodash.sortBy = sortBy;
  13268. lodash.tap = tap;
  13269. lodash.throttle = throttle;
  13270. lodash.times = times;
  13271. lodash.toArray = toArray;
  13272. lodash.transform = transform;
  13273. lodash.union = union;
  13274. lodash.uniq = uniq;
  13275. lodash.values = values;
  13276. lodash.where = where;
  13277. lodash.without = without;
  13278. lodash.wrap = wrap;
  13279. lodash.zip = zip;
  13280. lodash.zipObject = zipObject;
  13281. // add aliases
  13282. lodash.collect = map;
  13283. lodash.drop = rest;
  13284. lodash.each = forEach;
  13285. lodash.eachRight = forEachRight;
  13286. lodash.extend = assign;
  13287. lodash.methods = functions;
  13288. lodash.object = zipObject;
  13289. lodash.select = filter;
  13290. lodash.tail = rest;
  13291. lodash.unique = uniq;
  13292. lodash.unzip = zip;
  13293. // add functions to `lodash.prototype`
  13294. mixin(lodash);
  13295. /*--------------------------------------------------------------------------*/
  13296. // add functions that return unwrapped values when chaining
  13297. lodash.clone = clone;
  13298. lodash.cloneDeep = cloneDeep;
  13299. lodash.contains = contains;
  13300. lodash.escape = escape;
  13301. lodash.every = every;
  13302. lodash.find = find;
  13303. lodash.findIndex = findIndex;
  13304. lodash.findKey = findKey;
  13305. lodash.findLast = findLast;
  13306. lodash.findLastIndex = findLastIndex;
  13307. lodash.findLastKey = findLastKey;
  13308. lodash.has = has;
  13309. lodash.identity = identity;
  13310. lodash.indexOf = indexOf;
  13311. lodash.isArguments = isArguments;
  13312. lodash.isArray = isArray;
  13313. lodash.isBoolean = isBoolean;
  13314. lodash.isDate = isDate;
  13315. lodash.isElement = isElement;
  13316. lodash.isEmpty = isEmpty;
  13317. lodash.isEqual = isEqual;
  13318. lodash.isFinite = isFinite;
  13319. lodash.isFunction = isFunction;
  13320. lodash.isNaN = isNaN;
  13321. lodash.isNull = isNull;
  13322. lodash.isNumber = isNumber;
  13323. lodash.isObject = isObject;
  13324. lodash.isPlainObject = isPlainObject;
  13325. lodash.isRegExp = isRegExp;
  13326. lodash.isString = isString;
  13327. lodash.isUndefined = isUndefined;
  13328. lodash.lastIndexOf = lastIndexOf;
  13329. lodash.mixin = mixin;
  13330. lodash.noConflict = noConflict;
  13331. lodash.parseInt = parseInt;
  13332. lodash.random = random;
  13333. lodash.reduce = reduce;
  13334. lodash.reduceRight = reduceRight;
  13335. lodash.result = result;
  13336. lodash.runInContext = runInContext;
  13337. lodash.size = size;
  13338. lodash.some = some;
  13339. lodash.sortedIndex = sortedIndex;
  13340. lodash.template = template;
  13341. lodash.unescape = unescape;
  13342. lodash.uniqueId = uniqueId;
  13343. // add aliases
  13344. lodash.all = every;
  13345. lodash.any = some;
  13346. lodash.detect = find;
  13347. lodash.findWhere = find;
  13348. lodash.foldl = reduce;
  13349. lodash.foldr = reduceRight;
  13350. lodash.include = contains;
  13351. lodash.inject = reduce;
  13352. forOwn(lodash, function(func, methodName) {
  13353. if (!lodash.prototype[methodName]) {
  13354. lodash.prototype[methodName] = function() {
  13355. var args = [this.__wrapped__],
  13356. chainAll = this.__chain__;
  13357. push.apply(args, arguments);
  13358. var result = func.apply(lodash, args);
  13359. return chainAll
  13360. ? new lodashWrapper(result, chainAll)
  13361. : result;
  13362. };
  13363. }
  13364. });
  13365. /*--------------------------------------------------------------------------*/
  13366. // add functions capable of returning wrapped and unwrapped values when chaining
  13367. lodash.first = first;
  13368. lodash.last = last;
  13369. lodash.sample = sample;
  13370. // add aliases
  13371. lodash.take = first;
  13372. lodash.head = first;
  13373. forOwn(lodash, function(func, methodName) {
  13374. var callbackable = methodName !== 'sample';
  13375. if (!lodash.prototype[methodName]) {
  13376. lodash.prototype[methodName]= function(n, guard) {
  13377. var chainAll = this.__chain__,
  13378. result = func(this.__wrapped__, n, guard);
  13379. return !chainAll && (n == null || (guard && !(callbackable && typeof n == 'function')))
  13380. ? result
  13381. : new lodashWrapper(result, chainAll);
  13382. };
  13383. }
  13384. });
  13385. /*--------------------------------------------------------------------------*/
  13386. /**
  13387. * The semantic version number.
  13388. *
  13389. * @static
  13390. * @memberOf _
  13391. * @type string
  13392. */
  13393. lodash.VERSION = '2.2.1';
  13394. // add "Chaining" functions to the wrapper
  13395. lodash.prototype.chain = wrapperChain;
  13396. lodash.prototype.toString = wrapperToString;
  13397. lodash.prototype.value = wrapperValueOf;
  13398. lodash.prototype.valueOf = wrapperValueOf;
  13399. // add `Array` functions that return unwrapped values
  13400. forEach(['join', 'pop', 'shift'], function(methodName) {
  13401. var func = arrayRef[methodName];
  13402. lodash.prototype[methodName] = function() {
  13403. var chainAll = this.__chain__,
  13404. result = func.apply(this.__wrapped__, arguments);
  13405. return chainAll
  13406. ? new lodashWrapper(result, chainAll)
  13407. : result;
  13408. };
  13409. });
  13410. // add `Array` functions that return the wrapped value
  13411. forEach(['push', 'reverse', 'sort', 'unshift'], function(methodName) {
  13412. var func = arrayRef[methodName];
  13413. lodash.prototype[methodName] = function() {
  13414. func.apply(this.__wrapped__, arguments);
  13415. return this;
  13416. };
  13417. });
  13418. // add `Array` functions that return new wrapped values
  13419. forEach(['concat', 'slice', 'splice'], function(methodName) {
  13420. var func = arrayRef[methodName];
  13421. lodash.prototype[methodName] = function() {
  13422. return new lodashWrapper(func.apply(this.__wrapped__, arguments), this.__chain__);
  13423. };
  13424. });
  13425. return lodash;
  13426. }
  13427. /*--------------------------------------------------------------------------*/
  13428. // expose Lo-Dash
  13429. var _ = runInContext();
  13430. // some AMD build optimizers, like r.js, check for condition patterns like the following:
  13431. if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) {
  13432. // Expose Lo-Dash to the global object even when an AMD loader is present in
  13433. // case Lo-Dash was injected by a third-party script and not intended to be
  13434. // loaded as a module. The global assignment can be reverted in the Lo-Dash
  13435. // module by its `noConflict()` method.
  13436. root._ = _;
  13437. // define as an anonymous module so, through path mapping, it can be
  13438. // referenced as the "underscore" module
  13439. define(function() {
  13440. return _;
  13441. });
  13442. }
  13443. // check for `exports` after `define` in case a build optimizer adds an `exports` object
  13444. else if (freeExports && freeModule) {
  13445. // in Node.js or RingoJS
  13446. if (moduleExports) {
  13447. (freeModule.exports = _)._ = _;
  13448. }
  13449. // in Narwhal or Rhino -require
  13450. else {
  13451. freeExports._ = _;
  13452. }
  13453. }
  13454. else {
  13455. // in a browser or Rhino
  13456. root._ = _;
  13457. }
  13458. }.call(this));
  13459. // Backbone.js 1.0.0
  13460. // (c) 2010-2013 Jeremy Ashkenas, DocumentCloud Inc.
  13461. // Backbone may be freely distributed under the MIT license.
  13462. // For all details and documentation:
  13463. // http://backbonejs.org
  13464. (function(){
  13465. // Initial Setup
  13466. // -------------
  13467. // Save a reference to the global object (`window` in the browser, `exports`
  13468. // on the server).
  13469. var root = this;
  13470. // Save the previous value of the `Backbone` variable, so that it can be
  13471. // restored later on, if `noConflict` is used.
  13472. var previousBackbone = root.Backbone;
  13473. // Create local references to array methods we'll want to use later.
  13474. var array = [];
  13475. var push = array.push;
  13476. var slice = array.slice;
  13477. var splice = array.splice;
  13478. // The top-level namespace. All public Backbone classes and modules will
  13479. // be attached to this. Exported for both the browser and the server.
  13480. var Backbone;
  13481. if (typeof exports !== 'undefined') {
  13482. Backbone = exports;
  13483. } else {
  13484. Backbone = root.Backbone = {};
  13485. }
  13486. // Current version of the library. Keep in sync with `package.json`.
  13487. Backbone.VERSION = '1.0.0';
  13488. // Require Underscore, if we're on the server, and it's not already present.
  13489. var _ = root._;
  13490. if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
  13491. // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
  13492. // the `$` variable.
  13493. Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
  13494. // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
  13495. // to its previous owner. Returns a reference to this Backbone object.
  13496. Backbone.noConflict = function() {
  13497. root.Backbone = previousBackbone;
  13498. return this;
  13499. };
  13500. // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
  13501. // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
  13502. // set a `X-Http-Method-Override` header.
  13503. Backbone.emulateHTTP = false;
  13504. // Turn on `emulateJSON` to support legacy servers that can't deal with direct
  13505. // `application/json` requests ... will encode the body as
  13506. // `application/x-www-form-urlencoded` instead and will send the model in a
  13507. // form param named `model`.
  13508. Backbone.emulateJSON = false;
  13509. // Backbone.Events
  13510. // ---------------
  13511. // A module that can be mixed in to *any object* in order to provide it with
  13512. // custom events. You may bind with `on` or remove with `off` callback
  13513. // functions to an event; `trigger`-ing an event fires all callbacks in
  13514. // succession.
  13515. //
  13516. // var object = {};
  13517. // _.extend(object, Backbone.Events);
  13518. // object.on('expand', function(){ alert('expanded'); });
  13519. // object.trigger('expand');
  13520. //
  13521. var Events = Backbone.Events = {
  13522. // Bind an event to a `callback` function. Passing `"all"` will bind
  13523. // the callback to all events fired.
  13524. on: function(name, callback, context) {
  13525. if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
  13526. this._events || (this._events = {});
  13527. var events = this._events[name] || (this._events[name] = []);
  13528. events.push({callback: callback, context: context, ctx: context || this});
  13529. return this;
  13530. },
  13531. // Bind an event to only be triggered a single time. After the first time
  13532. // the callback is invoked, it will be removed.
  13533. once: function(name, callback, context) {
  13534. if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
  13535. var self = this;
  13536. var once = _.once(function() {
  13537. self.off(name, once);
  13538. callback.apply(this, arguments);
  13539. });
  13540. once._callback = callback;
  13541. return this.on(name, once, context);
  13542. },
  13543. // Remove one or many callbacks. If `context` is null, removes all
  13544. // callbacks with that function. If `callback` is null, removes all
  13545. // callbacks for the event. If `name` is null, removes all bound
  13546. // callbacks for all events.
  13547. off: function(name, callback, context) {
  13548. var retain, ev, events, names, i, l, j, k;
  13549. if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
  13550. if (!name && !callback && !context) {
  13551. this._events = {};
  13552. return this;
  13553. }
  13554. names = name ? [name] : _.keys(this._events);
  13555. for (i = 0, l = names.length; i < l; i++) {
  13556. name = names[i];
  13557. if (events = this._events[name]) {
  13558. this._events[name] = retain = [];
  13559. if (callback || context) {
  13560. for (j = 0, k = events.length; j < k; j++) {
  13561. ev = events[j];
  13562. if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
  13563. (context && context !== ev.context)) {
  13564. retain.push(ev);
  13565. }
  13566. }
  13567. }
  13568. if (!retain.length) delete this._events[name];
  13569. }
  13570. }
  13571. return this;
  13572. },
  13573. // Trigger one or many events, firing all bound callbacks. Callbacks are
  13574. // passed the same arguments as `trigger` is, apart from the event name
  13575. // (unless you're listening on `"all"`, which will cause your callback to
  13576. // receive the true name of the event as the first argument).
  13577. trigger: function(name) {
  13578. if (!this._events) return this;
  13579. var args = slice.call(arguments, 1);
  13580. if (!eventsApi(this, 'trigger', name, args)) return this;
  13581. var events = this._events[name];
  13582. var allEvents = this._events.all;
  13583. if (events) triggerEvents(events, args);
  13584. if (allEvents) triggerEvents(allEvents, arguments);
  13585. return this;
  13586. },
  13587. // Tell this object to stop listening to either specific events ... or
  13588. // to every object it's currently listening to.
  13589. stopListening: function(obj, name, callback) {
  13590. var listeners = this._listeners;
  13591. if (!listeners) return this;
  13592. var deleteListener = !name && !callback;
  13593. if (typeof name === 'object') callback = this;
  13594. if (obj) (listeners = {})[obj._listenerId] = obj;
  13595. for (var id in listeners) {
  13596. listeners[id].off(name, callback, this);
  13597. if (deleteListener) delete this._listeners[id];
  13598. }
  13599. return this;
  13600. }
  13601. };
  13602. // Regular expression used to split event strings.
  13603. var eventSplitter = /\s+/;
  13604. // Implement fancy features of the Events API such as multiple event
  13605. // names `"change blur"` and jQuery-style event maps `{change: action}`
  13606. // in terms of the existing API.
  13607. var eventsApi = function(obj, action, name, rest) {
  13608. if (!name) return true;
  13609. // Handle event maps.
  13610. if (typeof name === 'object') {
  13611. for (var key in name) {
  13612. obj[action].apply(obj, [key, name[key]].concat(rest));
  13613. }
  13614. return false;
  13615. }
  13616. // Handle space separated event names.
  13617. if (eventSplitter.test(name)) {
  13618. var names = name.split(eventSplitter);
  13619. for (var i = 0, l = names.length; i < l; i++) {
  13620. obj[action].apply(obj, [names[i]].concat(rest));
  13621. }
  13622. return false;
  13623. }
  13624. return true;
  13625. };
  13626. // A difficult-to-believe, but optimized internal dispatch function for
  13627. // triggering events. Tries to keep the usual cases speedy (most internal
  13628. // Backbone events have 3 arguments).
  13629. var triggerEvents = function(events, args) {
  13630. var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
  13631. switch (args.length) {
  13632. case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
  13633. case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
  13634. case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
  13635. case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
  13636. default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
  13637. }
  13638. };
  13639. var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
  13640. // Inversion-of-control versions of `on` and `once`. Tell *this* object to
  13641. // listen to an event in another object ... keeping track of what it's
  13642. // listening to.
  13643. _.each(listenMethods, function(implementation, method) {
  13644. Events[method] = function(obj, name, callback) {
  13645. var listeners = this._listeners || (this._listeners = {});
  13646. var id = obj._listenerId || (obj._listenerId = _.uniqueId('l'));
  13647. listeners[id] = obj;
  13648. if (typeof name === 'object') callback = this;
  13649. obj[implementation](name, callback, this);
  13650. return this;
  13651. };
  13652. });
  13653. // Aliases for backwards compatibility.
  13654. Events.bind = Events.on;
  13655. Events.unbind = Events.off;
  13656. // Allow the `Backbone` object to serve as a global event bus, for folks who
  13657. // want global "pubsub" in a convenient place.
  13658. _.extend(Backbone, Events);
  13659. // Backbone.Model
  13660. // --------------
  13661. // Backbone **Models** are the basic data object in the framework --
  13662. // frequently representing a row in a table in a database on your server.
  13663. // A discrete chunk of data and a bunch of useful, related methods for
  13664. // performing computations and transformations on that data.
  13665. // Create a new model with the specified attributes. A client id (`cid`)
  13666. // is automatically generated and assigned for you.
  13667. var Model = Backbone.Model = function(attributes, options) {
  13668. var defaults;
  13669. var attrs = attributes || {};
  13670. options || (options = {});
  13671. this.cid = _.uniqueId('c');
  13672. this.attributes = {};
  13673. _.extend(this, _.pick(options, modelOptions));
  13674. if (options.parse) attrs = this.parse(attrs, options) || {};
  13675. if (defaults = _.result(this, 'defaults')) {
  13676. attrs = _.defaults({}, attrs, defaults);
  13677. }
  13678. this.set(attrs, options);
  13679. this.changed = {};
  13680. this.initialize.apply(this, arguments);
  13681. };
  13682. // A list of options to be attached directly to the model, if provided.
  13683. var modelOptions = ['url', 'urlRoot', 'collection'];
  13684. // Attach all inheritable methods to the Model prototype.
  13685. _.extend(Model.prototype, Events, {
  13686. // A hash of attributes whose current and previous value differ.
  13687. changed: null,
  13688. // The value returned during the last failed validation.
  13689. validationError: null,
  13690. // The default name for the JSON `id` attribute is `"id"`. MongoDB and
  13691. // CouchDB users may want to set this to `"_id"`.
  13692. idAttribute: 'id',
  13693. // Initialize is an empty function by default. Override it with your own
  13694. // initialization logic.
  13695. initialize: function(){},
  13696. // Return a copy of the model's `attributes` object.
  13697. toJSON: function(options) {
  13698. return _.clone(this.attributes);
  13699. },
  13700. // Proxy `Backbone.sync` by default -- but override this if you need
  13701. // custom syncing semantics for *this* particular model.
  13702. sync: function() {
  13703. return Backbone.sync.apply(this, arguments);
  13704. },
  13705. // Get the value of an attribute.
  13706. get: function(attr) {
  13707. return this.attributes[attr];
  13708. },
  13709. // Get the HTML-escaped value of an attribute.
  13710. escape: function(attr) {
  13711. return _.escape(this.get(attr));
  13712. },
  13713. // Returns `true` if the attribute contains a value that is not null
  13714. // or undefined.
  13715. has: function(attr) {
  13716. return this.get(attr) != null;
  13717. },
  13718. // Set a hash of model attributes on the object, firing `"change"`. This is
  13719. // the core primitive operation of a model, updating the data and notifying
  13720. // anyone who needs to know about the change in state. The heart of the beast.
  13721. set: function(key, val, options) {
  13722. var attr, attrs, unset, changes, silent, changing, prev, current;
  13723. if (key == null) return this;
  13724. // Handle both `"key", value` and `{key: value}` -style arguments.
  13725. if (typeof key === 'object') {
  13726. attrs = key;
  13727. options = val;
  13728. } else {
  13729. (attrs = {})[key] = val;
  13730. }
  13731. options || (options = {});
  13732. // Run validation.
  13733. if (!this._validate(attrs, options)) return false;
  13734. // Extract attributes and options.
  13735. unset = options.unset;
  13736. silent = options.silent;
  13737. changes = [];
  13738. changing = this._changing;
  13739. this._changing = true;
  13740. if (!changing) {
  13741. this._previousAttributes = _.clone(this.attributes);
  13742. this.changed = {};
  13743. }
  13744. current = this.attributes, prev = this._previousAttributes;
  13745. // Check for changes of `id`.
  13746. if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
  13747. // For each `set` attribute, update or delete the current value.
  13748. for (attr in attrs) {
  13749. val = attrs[attr];
  13750. if (!_.isEqual(current[attr], val)) changes.push(attr);
  13751. if (!_.isEqual(prev[attr], val)) {
  13752. this.changed[attr] = val;
  13753. } else {
  13754. delete this.changed[attr];
  13755. }
  13756. unset ? delete current[attr] : current[attr] = val;
  13757. }
  13758. // Trigger all relevant attribute changes.
  13759. if (!silent) {
  13760. if (changes.length) this._pending = true;
  13761. for (var i = 0, l = changes.length; i < l; i++) {
  13762. this.trigger('change:' + changes[i], this, current[changes[i]], options);
  13763. }
  13764. }
  13765. // You might be wondering why there's a `while` loop here. Changes can
  13766. // be recursively nested within `"change"` events.
  13767. if (changing) return this;
  13768. if (!silent) {
  13769. while (this._pending) {
  13770. this._pending = false;
  13771. this.trigger('change', this, options);
  13772. }
  13773. }
  13774. this._pending = false;
  13775. this._changing = false;
  13776. return this;
  13777. },
  13778. // Remove an attribute from the model, firing `"change"`. `unset` is a noop
  13779. // if the attribute doesn't exist.
  13780. unset: function(attr, options) {
  13781. return this.set(attr, void 0, _.extend({}, options, {unset: true}));
  13782. },
  13783. // Clear all attributes on the model, firing `"change"`.
  13784. clear: function(options) {
  13785. var attrs = {};
  13786. for (var key in this.attributes) attrs[key] = void 0;
  13787. return this.set(attrs, _.extend({}, options, {unset: true}));
  13788. },
  13789. // Determine if the model has changed since the last `"change"` event.
  13790. // If you specify an attribute name, determine if that attribute has changed.
  13791. hasChanged: function(attr) {
  13792. if (attr == null) return !_.isEmpty(this.changed);
  13793. return _.has(this.changed, attr);
  13794. },
  13795. // Return an object containing all the attributes that have changed, or
  13796. // false if there are no changed attributes. Useful for determining what
  13797. // parts of a view need to be updated and/or what attributes need to be
  13798. // persisted to the server. Unset attributes will be set to undefined.
  13799. // You can also pass an attributes object to diff against the model,
  13800. // determining if there *would be* a change.
  13801. changedAttributes: function(diff) {
  13802. if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
  13803. var val, changed = false;
  13804. var old = this._changing ? this._previousAttributes : this.attributes;
  13805. for (var attr in diff) {
  13806. if (_.isEqual(old[attr], (val = diff[attr]))) continue;
  13807. (changed || (changed = {}))[attr] = val;
  13808. }
  13809. return changed;
  13810. },
  13811. // Get the previous value of an attribute, recorded at the time the last
  13812. // `"change"` event was fired.
  13813. previous: function(attr) {
  13814. if (attr == null || !this._previousAttributes) return null;
  13815. return this._previousAttributes[attr];
  13816. },
  13817. // Get all of the attributes of the model at the time of the previous
  13818. // `"change"` event.
  13819. previousAttributes: function() {
  13820. return _.clone(this._previousAttributes);
  13821. },
  13822. // Fetch the model from the server. If the server's representation of the
  13823. // model differs from its current attributes, they will be overridden,
  13824. // triggering a `"change"` event.
  13825. fetch: function(options) {
  13826. options = options ? _.clone(options) : {};
  13827. if (options.parse === void 0) options.parse = true;
  13828. var model = this;
  13829. var success = options.success;
  13830. options.success = function(resp) {
  13831. if (!model.set(model.parse(resp, options), options)) return false;
  13832. if (success) success(model, resp, options);
  13833. model.trigger('sync', model, resp, options);
  13834. };
  13835. wrapError(this, options);
  13836. return this.sync('read', this, options);
  13837. },
  13838. // Set a hash of model attributes, and sync the model to the server.
  13839. // If the server returns an attributes hash that differs, the model's
  13840. // state will be `set` again.
  13841. save: function(key, val, options) {
  13842. var attrs, method, xhr, attributes = this.attributes;
  13843. // Handle both `"key", value` and `{key: value}` -style arguments.
  13844. if (key == null || typeof key === 'object') {
  13845. attrs = key;
  13846. options = val;
  13847. } else {
  13848. (attrs = {})[key] = val;
  13849. }
  13850. // If we're not waiting and attributes exist, save acts as `set(attr).save(null, opts)`.
  13851. if (attrs && (!options || !options.wait) && !this.set(attrs, options)) return false;
  13852. options = _.extend({validate: true}, options);
  13853. // Do not persist invalid models.
  13854. if (!this._validate(attrs, options)) return false;
  13855. // Set temporary attributes if `{wait: true}`.
  13856. if (attrs && options.wait) {
  13857. this.attributes = _.extend({}, attributes, attrs);
  13858. }
  13859. // After a successful server-side save, the client is (optionally)
  13860. // updated with the server-side state.
  13861. if (options.parse === void 0) options.parse = true;
  13862. var model = this;
  13863. var success = options.success;
  13864. options.success = function(resp) {
  13865. // Ensure attributes are restored during synchronous saves.
  13866. model.attributes = attributes;
  13867. var serverAttrs = model.parse(resp, options);
  13868. if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
  13869. if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
  13870. return false;
  13871. }
  13872. if (success) success(model, resp, options);
  13873. model.trigger('sync', model, resp, options);
  13874. };
  13875. wrapError(this, options);
  13876. method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
  13877. if (method === 'patch') options.attrs = attrs;
  13878. xhr = this.sync(method, this, options);
  13879. // Restore attributes.
  13880. if (attrs && options.wait) this.attributes = attributes;
  13881. return xhr;
  13882. },
  13883. // Destroy this model on the server if it was already persisted.
  13884. // Optimistically removes the model from its collection, if it has one.
  13885. // If `wait: true` is passed, waits for the server to respond before removal.
  13886. destroy: function(options) {
  13887. options = options ? _.clone(options) : {};
  13888. var model = this;
  13889. var success = options.success;
  13890. var destroy = function() {
  13891. model.trigger('destroy', model, model.collection, options);
  13892. };
  13893. options.success = function(resp) {
  13894. if (options.wait || model.isNew()) destroy();
  13895. if (success) success(model, resp, options);
  13896. if (!model.isNew()) model.trigger('sync', model, resp, options);
  13897. };
  13898. if (this.isNew()) {
  13899. options.success();
  13900. return false;
  13901. }
  13902. wrapError(this, options);
  13903. var xhr = this.sync('delete', this, options);
  13904. if (!options.wait) destroy();
  13905. return xhr;
  13906. },
  13907. // Default URL for the model's representation on the server -- if you're
  13908. // using Backbone's restful methods, override this to change the endpoint
  13909. // that will be called.
  13910. url: function() {
  13911. var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
  13912. if (this.isNew()) return base;
  13913. return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
  13914. },
  13915. // **parse** converts a response into the hash of attributes to be `set` on
  13916. // the model. The default implementation is just to pass the response along.
  13917. parse: function(resp, options) {
  13918. return resp;
  13919. },
  13920. // Create a new model with identical attributes to this one.
  13921. clone: function() {
  13922. return new this.constructor(this.attributes);
  13923. },
  13924. // A model is new if it has never been saved to the server, and lacks an id.
  13925. isNew: function() {
  13926. return this.id == null;
  13927. },
  13928. // Check if the model is currently in a valid state.
  13929. isValid: function(options) {
  13930. return this._validate({}, _.extend(options || {}, { validate: true }));
  13931. },
  13932. // Run validation against the next complete set of model attributes,
  13933. // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
  13934. _validate: function(attrs, options) {
  13935. if (!options.validate || !this.validate) return true;
  13936. attrs = _.extend({}, this.attributes, attrs);
  13937. var error = this.validationError = this.validate(attrs, options) || null;
  13938. if (!error) return true;
  13939. this.trigger('invalid', this, error, _.extend(options || {}, {validationError: error}));
  13940. return false;
  13941. }
  13942. });
  13943. // Underscore methods that we want to implement on the Model.
  13944. var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
  13945. // Mix in each Underscore method as a proxy to `Model#attributes`.
  13946. _.each(modelMethods, function(method) {
  13947. Model.prototype[method] = function() {
  13948. var args = slice.call(arguments);
  13949. args.unshift(this.attributes);
  13950. return _[method].apply(_, args);
  13951. };
  13952. });
  13953. // Backbone.Collection
  13954. // -------------------
  13955. // If models tend to represent a single row of data, a Backbone Collection is
  13956. // more analagous to a table full of data ... or a small slice or page of that
  13957. // table, or a collection of rows that belong together for a particular reason
  13958. // -- all of the messages in this particular folder, all of the documents
  13959. // belonging to this particular author, and so on. Collections maintain
  13960. // indexes of their models, both in order, and for lookup by `id`.
  13961. // Create a new **Collection**, perhaps to contain a specific type of `model`.
  13962. // If a `comparator` is specified, the Collection will maintain
  13963. // its models in sort order, as they're added and removed.
  13964. var Collection = Backbone.Collection = function(models, options) {
  13965. options || (options = {});
  13966. if (options.url) this.url = options.url;
  13967. if (options.model) this.model = options.model;
  13968. if (options.comparator !== void 0) this.comparator = options.comparator;
  13969. this._reset();
  13970. this.initialize.apply(this, arguments);
  13971. if (models) this.reset(models, _.extend({silent: true}, options));
  13972. };
  13973. // Default options for `Collection#set`.
  13974. var setOptions = {add: true, remove: true, merge: true};
  13975. var addOptions = {add: true, merge: false, remove: false};
  13976. // Define the Collection's inheritable methods.
  13977. _.extend(Collection.prototype, Events, {
  13978. // The default model for a collection is just a **Backbone.Model**.
  13979. // This should be overridden in most cases.
  13980. model: Model,
  13981. // Initialize is an empty function by default. Override it with your own
  13982. // initialization logic.
  13983. initialize: function(){},
  13984. // The JSON representation of a Collection is an array of the
  13985. // models' attributes.
  13986. toJSON: function(options) {
  13987. return this.map(function(model){ return model.toJSON(options); });
  13988. },
  13989. // Proxy `Backbone.sync` by default.
  13990. sync: function() {
  13991. return Backbone.sync.apply(this, arguments);
  13992. },
  13993. // Add a model, or list of models to the set.
  13994. add: function(models, options) {
  13995. return this.set(models, _.defaults(options || {}, addOptions));
  13996. },
  13997. // Remove a model, or a list of models from the set.
  13998. remove: function(models, options) {
  13999. models = _.isArray(models) ? models.slice() : [models];
  14000. options || (options = {});
  14001. var i, l, index, model;
  14002. for (i = 0, l = models.length; i < l; i++) {
  14003. model = this.get(models[i]);
  14004. if (!model) continue;
  14005. delete this._byId[model.id];
  14006. delete this._byId[model.cid];
  14007. index = this.indexOf(model);
  14008. this.models.splice(index, 1);
  14009. this.length--;
  14010. if (!options.silent) {
  14011. options.index = index;
  14012. model.trigger('remove', model, this, options);
  14013. }
  14014. this._removeReference(model);
  14015. }
  14016. return this;
  14017. },
  14018. // Update a collection by `set`-ing a new list of models, adding new ones,
  14019. // removing models that are no longer present, and merging models that
  14020. // already exist in the collection, as necessary. Similar to **Model#set**,
  14021. // the core operation for updating the data contained by the collection.
  14022. set: function(models, options) {
  14023. options = _.defaults(options || {}, setOptions);
  14024. if (options.parse) models = this.parse(models, options);
  14025. if (!_.isArray(models)) models = models ? [models] : [];
  14026. var i, l, model, attrs, existing, sort;
  14027. var at = options.at;
  14028. var sortable = this.comparator && (at == null) && options.sort !== false;
  14029. var sortAttr = _.isString(this.comparator) ? this.comparator : null;
  14030. var toAdd = [], toRemove = [], modelMap = {};
  14031. // Turn bare objects into model references, and prevent invalid models
  14032. // from being added.
  14033. for (i = 0, l = models.length; i < l; i++) {
  14034. if (!(model = this._prepareModel(models[i], options))) continue;
  14035. // If a duplicate is found, prevent it from being added and
  14036. // optionally merge it into the existing model.
  14037. if (existing = this.get(model)) {
  14038. if (options.remove) modelMap[existing.cid] = true;
  14039. if (options.merge) {
  14040. existing.set(model.attributes, options);
  14041. if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
  14042. }
  14043. // This is a new model, push it to the `toAdd` list.
  14044. } else if (options.add) {
  14045. toAdd.push(model);
  14046. // Listen to added models' events, and index models for lookup by
  14047. // `id` and by `cid`.
  14048. model.on('all', this._onModelEvent, this);
  14049. this._byId[model.cid] = model;
  14050. if (model.id != null) this._byId[model.id] = model;
  14051. }
  14052. }
  14053. // Remove nonexistent models if appropriate.
  14054. if (options.remove) {
  14055. for (i = 0, l = this.length; i < l; ++i) {
  14056. if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
  14057. }
  14058. if (toRemove.length) this.remove(toRemove, options);
  14059. }
  14060. // See if sorting is needed, update `length` and splice in new models.
  14061. if (toAdd.length) {
  14062. if (sortable) sort = true;
  14063. this.length += toAdd.length;
  14064. if (at != null) {
  14065. splice.apply(this.models, [at, 0].concat(toAdd));
  14066. } else {
  14067. push.apply(this.models, toAdd);
  14068. }
  14069. }
  14070. // Silently sort the collection if appropriate.
  14071. if (sort) this.sort({silent: true});
  14072. if (options.silent) return this;
  14073. // Trigger `add` events.
  14074. for (i = 0, l = toAdd.length; i < l; i++) {
  14075. (model = toAdd[i]).trigger('add', model, this, options);
  14076. }
  14077. // Trigger `sort` if the collection was sorted.
  14078. if (sort) this.trigger('sort', this, options);
  14079. return this;
  14080. },
  14081. // When you have more items than you want to add or remove individually,
  14082. // you can reset the entire set with a new list of models, without firing
  14083. // any granular `add` or `remove` events. Fires `reset` when finished.
  14084. // Useful for bulk operations and optimizations.
  14085. reset: function(models, options) {
  14086. options || (options = {});
  14087. for (var i = 0, l = this.models.length; i < l; i++) {
  14088. this._removeReference(this.models[i]);
  14089. }
  14090. options.previousModels = this.models;
  14091. this._reset();
  14092. this.add(models, _.extend({silent: true}, options));
  14093. if (!options.silent) this.trigger('reset', this, options);
  14094. return this;
  14095. },
  14096. // Add a model to the end of the collection.
  14097. push: function(model, options) {
  14098. model = this._prepareModel(model, options);
  14099. this.add(model, _.extend({at: this.length}, options));
  14100. return model;
  14101. },
  14102. // Remove a model from the end of the collection.
  14103. pop: function(options) {
  14104. var model = this.at(this.length - 1);
  14105. this.remove(model, options);
  14106. return model;
  14107. },
  14108. // Add a model to the beginning of the collection.
  14109. unshift: function(model, options) {
  14110. model = this._prepareModel(model, options);
  14111. this.add(model, _.extend({at: 0}, options));
  14112. return model;
  14113. },
  14114. // Remove a model from the beginning of the collection.
  14115. shift: function(options) {
  14116. var model = this.at(0);
  14117. this.remove(model, options);
  14118. return model;
  14119. },
  14120. // Slice out a sub-array of models from the collection.
  14121. slice: function(begin, end) {
  14122. return this.models.slice(begin, end);
  14123. },
  14124. // Get a model from the set by id.
  14125. get: function(obj) {
  14126. if (obj == null) return void 0;
  14127. return this._byId[obj.id != null ? obj.id : obj.cid || obj];
  14128. },
  14129. // Get the model at the given index.
  14130. at: function(index) {
  14131. return this.models[index];
  14132. },
  14133. // Return models with matching attributes. Useful for simple cases of
  14134. // `filter`.
  14135. where: function(attrs, first) {
  14136. if (_.isEmpty(attrs)) return first ? void 0 : [];
  14137. return this[first ? 'find' : 'filter'](function(model) {
  14138. for (var key in attrs) {
  14139. if (attrs[key] !== model.get(key)) return false;
  14140. }
  14141. return true;
  14142. });
  14143. },
  14144. // Return the first model with matching attributes. Useful for simple cases
  14145. // of `find`.
  14146. findWhere: function(attrs) {
  14147. return this.where(attrs, true);
  14148. },
  14149. // Force the collection to re-sort itself. You don't need to call this under
  14150. // normal circumstances, as the set will maintain sort order as each item
  14151. // is added.
  14152. sort: function(options) {
  14153. if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
  14154. options || (options = {});
  14155. // Run sort based on type of `comparator`.
  14156. if (_.isString(this.comparator) || this.comparator.length === 1) {
  14157. this.models = this.sortBy(this.comparator, this);
  14158. } else {
  14159. this.models.sort(_.bind(this.comparator, this));
  14160. }
  14161. if (!options.silent) this.trigger('sort', this, options);
  14162. return this;
  14163. },
  14164. // Figure out the smallest index at which a model should be inserted so as
  14165. // to maintain order.
  14166. sortedIndex: function(model, value, context) {
  14167. value || (value = this.comparator);
  14168. var iterator = _.isFunction(value) ? value : function(model) {
  14169. return model.get(value);
  14170. };
  14171. return _.sortedIndex(this.models, model, iterator, context);
  14172. },
  14173. // Pluck an attribute from each model in the collection.
  14174. pluck: function(attr) {
  14175. return _.invoke(this.models, 'get', attr);
  14176. },
  14177. // Fetch the default set of models for this collection, resetting the
  14178. // collection when they arrive. If `reset: true` is passed, the response
  14179. // data will be passed through the `reset` method instead of `set`.
  14180. fetch: function(options) {
  14181. options = options ? _.clone(options) : {};
  14182. if (options.parse === void 0) options.parse = true;
  14183. var success = options.success;
  14184. var collection = this;
  14185. options.success = function(resp) {
  14186. var method = options.reset ? 'reset' : 'set';
  14187. collection[method](resp, options);
  14188. if (success) success(collection, resp, options);
  14189. collection.trigger('sync', collection, resp, options);
  14190. };
  14191. wrapError(this, options);
  14192. return this.sync('read', this, options);
  14193. },
  14194. // Create a new instance of a model in this collection. Add the model to the
  14195. // collection immediately, unless `wait: true` is passed, in which case we
  14196. // wait for the server to agree.
  14197. create: function(model, options) {
  14198. options = options ? _.clone(options) : {};
  14199. if (!(model = this._prepareModel(model, options))) return false;
  14200. if (!options.wait) this.add(model, options);
  14201. var collection = this;
  14202. var success = options.success;
  14203. options.success = function(resp) {
  14204. if (options.wait) collection.add(model, options);
  14205. if (success) success(model, resp, options);
  14206. };
  14207. model.save(null, options);
  14208. return model;
  14209. },
  14210. // **parse** converts a response into a list of models to be added to the
  14211. // collection. The default implementation is just to pass it through.
  14212. parse: function(resp, options) {
  14213. return resp;
  14214. },
  14215. // Create a new collection with an identical list of models as this one.
  14216. clone: function() {
  14217. return new this.constructor(this.models);
  14218. },
  14219. // Private method to reset all internal state. Called when the collection
  14220. // is first initialized or reset.
  14221. _reset: function() {
  14222. this.length = 0;
  14223. this.models = [];
  14224. this._byId = {};
  14225. },
  14226. // Prepare a hash of attributes (or other model) to be added to this
  14227. // collection.
  14228. _prepareModel: function(attrs, options) {
  14229. if (attrs instanceof Model) {
  14230. if (!attrs.collection) attrs.collection = this;
  14231. return attrs;
  14232. }
  14233. options || (options = {});
  14234. options.collection = this;
  14235. var model = new this.model(attrs, options);
  14236. if (!model._validate(attrs, options)) {
  14237. this.trigger('invalid', this, attrs, options);
  14238. return false;
  14239. }
  14240. return model;
  14241. },
  14242. // Internal method to sever a model's ties to a collection.
  14243. _removeReference: function(model) {
  14244. if (this === model.collection) delete model.collection;
  14245. model.off('all', this._onModelEvent, this);
  14246. },
  14247. // Internal method called every time a model in the set fires an event.
  14248. // Sets need to update their indexes when models change ids. All other
  14249. // events simply proxy through. "add" and "remove" events that originate
  14250. // in other collections are ignored.
  14251. _onModelEvent: function(event, model, collection, options) {
  14252. if ((event === 'add' || event === 'remove') && collection !== this) return;
  14253. if (event === 'destroy') this.remove(model, options);
  14254. if (model && event === 'change:' + model.idAttribute) {
  14255. delete this._byId[model.previous(model.idAttribute)];
  14256. if (model.id != null) this._byId[model.id] = model;
  14257. }
  14258. this.trigger.apply(this, arguments);
  14259. }
  14260. });
  14261. // Underscore methods that we want to implement on the Collection.
  14262. // 90% of the core usefulness of Backbone Collections is actually implemented
  14263. // right here:
  14264. var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
  14265. 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
  14266. 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
  14267. 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
  14268. 'tail', 'drop', 'last', 'without', 'indexOf', 'shuffle', 'lastIndexOf',
  14269. 'isEmpty', 'chain'];
  14270. // Mix in each Underscore method as a proxy to `Collection#models`.
  14271. _.each(methods, function(method) {
  14272. Collection.prototype[method] = function() {
  14273. var args = slice.call(arguments);
  14274. args.unshift(this.models);
  14275. return _[method].apply(_, args);
  14276. };
  14277. });
  14278. // Underscore methods that take a property name as an argument.
  14279. var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
  14280. // Use attributes instead of properties.
  14281. _.each(attributeMethods, function(method) {
  14282. Collection.prototype[method] = function(value, context) {
  14283. var iterator = _.isFunction(value) ? value : function(model) {
  14284. return model.get(value);
  14285. };
  14286. return _[method](this.models, iterator, context);
  14287. };
  14288. });
  14289. // Backbone.View
  14290. // -------------
  14291. // Backbone Views are almost more convention than they are actual code. A View
  14292. // is simply a JavaScript object that represents a logical chunk of UI in the
  14293. // DOM. This might be a single item, an entire list, a sidebar or panel, or
  14294. // even the surrounding frame which wraps your whole app. Defining a chunk of
  14295. // UI as a **View** allows you to define your DOM events declaratively, without
  14296. // having to worry about render order ... and makes it easy for the view to
  14297. // react to specific changes in the state of your models.
  14298. // Creating a Backbone.View creates its initial element outside of the DOM,
  14299. // if an existing element is not provided...
  14300. var View = Backbone.View = function(options) {
  14301. this.cid = _.uniqueId('view');
  14302. this._configure(options || {});
  14303. this._ensureElement();
  14304. this.initialize.apply(this, arguments);
  14305. this.delegateEvents();
  14306. };
  14307. // Cached regex to split keys for `delegate`.
  14308. var delegateEventSplitter = /^(\S+)\s*(.*)$/;
  14309. // List of view options to be merged as properties.
  14310. var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
  14311. // Set up all inheritable **Backbone.View** properties and methods.
  14312. _.extend(View.prototype, Events, {
  14313. // The default `tagName` of a View's element is `"div"`.
  14314. tagName: 'div',
  14315. // jQuery delegate for element lookup, scoped to DOM elements within the
  14316. // current view. This should be prefered to global lookups where possible.
  14317. $: function(selector) {
  14318. return this.$el.find(selector);
  14319. },
  14320. // Initialize is an empty function by default. Override it with your own
  14321. // initialization logic.
  14322. initialize: function(){},
  14323. // **render** is the core function that your view should override, in order
  14324. // to populate its element (`this.el`), with the appropriate HTML. The
  14325. // convention is for **render** to always return `this`.
  14326. render: function() {
  14327. return this;
  14328. },
  14329. // Remove this view by taking the element out of the DOM, and removing any
  14330. // applicable Backbone.Events listeners.
  14331. remove: function() {
  14332. this.$el.remove();
  14333. this.stopListening();
  14334. return this;
  14335. },
  14336. // Change the view's element (`this.el` property), including event
  14337. // re-delegation.
  14338. setElement: function(element, delegate) {
  14339. if (this.$el) this.undelegateEvents();
  14340. this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
  14341. this.el = this.$el[0];
  14342. if (delegate !== false) this.delegateEvents();
  14343. return this;
  14344. },
  14345. // Set callbacks, where `this.events` is a hash of
  14346. //
  14347. // *{"event selector": "callback"}*
  14348. //
  14349. // {
  14350. // 'mousedown .title': 'edit',
  14351. // 'click .button': 'save'
  14352. // 'click .open': function(e) { ... }
  14353. // }
  14354. //
  14355. // pairs. Callbacks will be bound to the view, with `this` set properly.
  14356. // Uses event delegation for efficiency.
  14357. // Omitting the selector binds the event to `this.el`.
  14358. // This only works for delegate-able events: not `focus`, `blur`, and
  14359. // not `change`, `submit`, and `reset` in Internet Explorer.
  14360. delegateEvents: function(events) {
  14361. if (!(events || (events = _.result(this, 'events')))) return this;
  14362. this.undelegateEvents();
  14363. for (var key in events) {
  14364. var method = events[key];
  14365. if (!_.isFunction(method)) method = this[events[key]];
  14366. if (!method) continue;
  14367. var match = key.match(delegateEventSplitter);
  14368. var eventName = match[1], selector = match[2];
  14369. method = _.bind(method, this);
  14370. eventName += '.delegateEvents' + this.cid;
  14371. if (selector === '') {
  14372. this.$el.on(eventName, method);
  14373. } else {
  14374. this.$el.on(eventName, selector, method);
  14375. }
  14376. }
  14377. return this;
  14378. },
  14379. // Clears all callbacks previously bound to the view with `delegateEvents`.
  14380. // You usually don't need to use this, but may wish to if you have multiple
  14381. // Backbone views attached to the same DOM element.
  14382. undelegateEvents: function() {
  14383. this.$el.off('.delegateEvents' + this.cid);
  14384. return this;
  14385. },
  14386. // Performs the initial configuration of a View with a set of options.
  14387. // Keys with special meaning *(e.g. model, collection, id, className)* are
  14388. // attached directly to the view. See `viewOptions` for an exhaustive
  14389. // list.
  14390. _configure: function(options) {
  14391. if (this.options) options = _.extend({}, _.result(this, 'options'), options);
  14392. _.extend(this, _.pick(options, viewOptions));
  14393. this.options = options;
  14394. },
  14395. // Ensure that the View has a DOM element to render into.
  14396. // If `this.el` is a string, pass it through `$()`, take the first
  14397. // matching element, and re-assign it to `el`. Otherwise, create
  14398. // an element from the `id`, `className` and `tagName` properties.
  14399. _ensureElement: function() {
  14400. if (!this.el) {
  14401. var attrs = _.extend({}, _.result(this, 'attributes'));
  14402. if (this.id) attrs.id = _.result(this, 'id');
  14403. if (this.className) attrs['class'] = _.result(this, 'className');
  14404. var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
  14405. this.setElement($el, false);
  14406. } else {
  14407. this.setElement(_.result(this, 'el'), false);
  14408. }
  14409. }
  14410. });
  14411. // Backbone.sync
  14412. // -------------
  14413. // Override this function to change the manner in which Backbone persists
  14414. // models to the server. You will be passed the type of request, and the
  14415. // model in question. By default, makes a RESTful Ajax request
  14416. // to the model's `url()`. Some possible customizations could be:
  14417. //
  14418. // * Use `setTimeout` to batch rapid-fire updates into a single request.
  14419. // * Send up the models as XML instead of JSON.
  14420. // * Persist models via WebSockets instead of Ajax.
  14421. //
  14422. // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
  14423. // as `POST`, with a `_method` parameter containing the true HTTP method,
  14424. // as well as all requests with the body as `application/x-www-form-urlencoded`
  14425. // instead of `application/json` with the model in a param named `model`.
  14426. // Useful when interfacing with server-side languages like **PHP** that make
  14427. // it difficult to read the body of `PUT` requests.
  14428. Backbone.sync = function(method, model, options) {
  14429. var type = methodMap[method];
  14430. // Default options, unless specified.
  14431. _.defaults(options || (options = {}), {
  14432. emulateHTTP: Backbone.emulateHTTP,
  14433. emulateJSON: Backbone.emulateJSON
  14434. });
  14435. // Default JSON-request options.
  14436. var params = {type: type, dataType: 'json'};
  14437. // Ensure that we have a URL.
  14438. if (!options.url) {
  14439. params.url = _.result(model, 'url') || urlError();
  14440. }
  14441. // Ensure that we have the appropriate request data.
  14442. if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
  14443. params.contentType = 'application/json';
  14444. params.data = JSON.stringify(options.attrs || model.toJSON(options));
  14445. }
  14446. // For older servers, emulate JSON by encoding the request into an HTML-form.
  14447. if (options.emulateJSON) {
  14448. params.contentType = 'application/x-www-form-urlencoded';
  14449. params.data = params.data ? {model: params.data} : {};
  14450. }
  14451. // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
  14452. // And an `X-HTTP-Method-Override` header.
  14453. if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
  14454. params.type = 'POST';
  14455. if (options.emulateJSON) params.data._method = type;
  14456. var beforeSend = options.beforeSend;
  14457. options.beforeSend = function(xhr) {
  14458. xhr.setRequestHeader('X-HTTP-Method-Override', type);
  14459. if (beforeSend) return beforeSend.apply(this, arguments);
  14460. };
  14461. }
  14462. // Don't process data on a non-GET request.
  14463. if (params.type !== 'GET' && !options.emulateJSON) {
  14464. params.processData = false;
  14465. }
  14466. // If we're sending a `PATCH` request, and we're in an old Internet Explorer
  14467. // that still has ActiveX enabled by default, override jQuery to use that
  14468. // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
  14469. if (params.type === 'PATCH' && window.ActiveXObject &&
  14470. !(window.external && window.external.msActiveXFilteringEnabled)) {
  14471. params.xhr = function() {
  14472. return new ActiveXObject("Microsoft.XMLHTTP");
  14473. };
  14474. }
  14475. // Make the request, allowing the user to override any Ajax options.
  14476. var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
  14477. model.trigger('request', model, xhr, options);
  14478. return xhr;
  14479. };
  14480. // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
  14481. var methodMap = {
  14482. 'create': 'POST',
  14483. 'update': 'PUT',
  14484. 'patch': 'PATCH',
  14485. 'delete': 'DELETE',
  14486. 'read': 'GET'
  14487. };
  14488. // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
  14489. // Override this if you'd like to use a different library.
  14490. Backbone.ajax = function() {
  14491. return Backbone.$.ajax.apply(Backbone.$, arguments);
  14492. };
  14493. // Backbone.Router
  14494. // ---------------
  14495. // Routers map faux-URLs to actions, and fire events when routes are
  14496. // matched. Creating a new one sets its `routes` hash, if not set statically.
  14497. var Router = Backbone.Router = function(options) {
  14498. options || (options = {});
  14499. if (options.routes) this.routes = options.routes;
  14500. this._bindRoutes();
  14501. this.initialize.apply(this, arguments);
  14502. };
  14503. // Cached regular expressions for matching named param parts and splatted
  14504. // parts of route strings.
  14505. var optionalParam = /\((.*?)\)/g;
  14506. var namedParam = /(\(\?)?:\w+/g;
  14507. var splatParam = /\*\w+/g;
  14508. var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
  14509. // Set up all inheritable **Backbone.Router** properties and methods.
  14510. _.extend(Router.prototype, Events, {
  14511. // Initialize is an empty function by default. Override it with your own
  14512. // initialization logic.
  14513. initialize: function(){},
  14514. // Manually bind a single named route to a callback. For example:
  14515. //
  14516. // this.route('search/:query/p:num', 'search', function(query, num) {
  14517. // ...
  14518. // });
  14519. //
  14520. route: function(route, name, callback) {
  14521. if (!_.isRegExp(route)) route = this._routeToRegExp(route);
  14522. if (_.isFunction(name)) {
  14523. callback = name;
  14524. name = '';
  14525. }
  14526. if (!callback) callback = this[name];
  14527. var router = this;
  14528. Backbone.history.route(route, function(fragment) {
  14529. var args = router._extractParameters(route, fragment);
  14530. callback && callback.apply(router, args);
  14531. router.trigger.apply(router, ['route:' + name].concat(args));
  14532. router.trigger('route', name, args);
  14533. Backbone.history.trigger('route', router, name, args);
  14534. });
  14535. return this;
  14536. },
  14537. // Simple proxy to `Backbone.history` to save a fragment into the history.
  14538. navigate: function(fragment, options) {
  14539. Backbone.history.navigate(fragment, options);
  14540. return this;
  14541. },
  14542. // Bind all defined routes to `Backbone.history`. We have to reverse the
  14543. // order of the routes here to support behavior where the most general
  14544. // routes can be defined at the bottom of the route map.
  14545. _bindRoutes: function() {
  14546. if (!this.routes) return;
  14547. this.routes = _.result(this, 'routes');
  14548. var route, routes = _.keys(this.routes);
  14549. while ((route = routes.pop()) != null) {
  14550. this.route(route, this.routes[route]);
  14551. }
  14552. },
  14553. // Convert a route string into a regular expression, suitable for matching
  14554. // against the current location hash.
  14555. _routeToRegExp: function(route) {
  14556. route = route.replace(escapeRegExp, '\\$&')
  14557. .replace(optionalParam, '(?:$1)?')
  14558. .replace(namedParam, function(match, optional){
  14559. return optional ? match : '([^\/]+)';
  14560. })
  14561. .replace(splatParam, '(.*?)');
  14562. return new RegExp('^' + route + '$');
  14563. },
  14564. // Given a route, and a URL fragment that it matches, return the array of
  14565. // extracted decoded parameters. Empty or unmatched parameters will be
  14566. // treated as `null` to normalize cross-browser behavior.
  14567. _extractParameters: function(route, fragment) {
  14568. var params = route.exec(fragment).slice(1);
  14569. return _.map(params, function(param) {
  14570. return param ? decodeURIComponent(param) : null;
  14571. });
  14572. }
  14573. });
  14574. // Backbone.History
  14575. // ----------------
  14576. // Handles cross-browser history management, based on either
  14577. // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
  14578. // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
  14579. // and URL fragments. If the browser supports neither (old IE, natch),
  14580. // falls back to polling.
  14581. var History = Backbone.History = function() {
  14582. this.handlers = [];
  14583. _.bindAll(this, 'checkUrl');
  14584. // Ensure that `History` can be used outside of the browser.
  14585. if (typeof window !== 'undefined') {
  14586. this.location = window.location;
  14587. this.history = window.history;
  14588. }
  14589. };
  14590. // Cached regex for stripping a leading hash/slash and trailing space.
  14591. var routeStripper = /^[#\/]|\s+$/g;
  14592. // Cached regex for stripping leading and trailing slashes.
  14593. var rootStripper = /^\/+|\/+$/g;
  14594. // Cached regex for detecting MSIE.
  14595. var isExplorer = /msie [\w.]+/;
  14596. // Cached regex for removing a trailing slash.
  14597. var trailingSlash = /\/$/;
  14598. // Has the history handling already been started?
  14599. History.started = false;
  14600. // Set up all inheritable **Backbone.History** properties and methods.
  14601. _.extend(History.prototype, Events, {
  14602. // The default interval to poll for hash changes, if necessary, is
  14603. // twenty times a second.
  14604. interval: 50,
  14605. // Gets the true hash value. Cannot use location.hash directly due to bug
  14606. // in Firefox where location.hash will always be decoded.
  14607. getHash: function(window) {
  14608. var match = (window || this).location.href.match(/#(.*)$/);
  14609. return match ? match[1] : '';
  14610. },
  14611. // Get the cross-browser normalized URL fragment, either from the URL,
  14612. // the hash, or the override.
  14613. getFragment: function(fragment, forcePushState) {
  14614. if (fragment == null) {
  14615. if (this._hasPushState || !this._wantsHashChange || forcePushState) {
  14616. fragment = this.location.pathname;
  14617. var root = this.root.replace(trailingSlash, '');
  14618. if (!fragment.indexOf(root)) fragment = fragment.substr(root.length);
  14619. } else {
  14620. fragment = this.getHash();
  14621. }
  14622. }
  14623. return fragment.replace(routeStripper, '');
  14624. },
  14625. // Start the hash change handling, returning `true` if the current URL matches
  14626. // an existing route, and `false` otherwise.
  14627. start: function(options) {
  14628. if (History.started) throw new Error("Backbone.history has already been started");
  14629. History.started = true;
  14630. // Figure out the initial configuration. Do we need an iframe?
  14631. // Is pushState desired ... is it available?
  14632. this.options = _.extend({}, {root: '/'}, this.options, options);
  14633. this.root = this.options.root;
  14634. this._wantsHashChange = this.options.hashChange !== false;
  14635. this._wantsPushState = !!this.options.pushState;
  14636. this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
  14637. var fragment = this.getFragment();
  14638. var docMode = document.documentMode;
  14639. var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
  14640. // Normalize root to always include a leading and trailing slash.
  14641. this.root = ('/' + this.root + '/').replace(rootStripper, '/');
  14642. if (oldIE && this._wantsHashChange) {
  14643. this.iframe = Backbone.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
  14644. this.navigate(fragment);
  14645. }
  14646. // Depending on whether we're using pushState or hashes, and whether
  14647. // 'onhashchange' is supported, determine how we check the URL state.
  14648. if (this._hasPushState) {
  14649. Backbone.$(window).on('popstate', this.checkUrl);
  14650. } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
  14651. Backbone.$(window).on('hashchange', this.checkUrl);
  14652. } else if (this._wantsHashChange) {
  14653. this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
  14654. }
  14655. // Determine if we need to change the base url, for a pushState link
  14656. // opened by a non-pushState browser.
  14657. this.fragment = fragment;
  14658. var loc = this.location;
  14659. var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
  14660. // If we've started off with a route from a `pushState`-enabled browser,
  14661. // but we're currently in a browser that doesn't support it...
  14662. if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
  14663. this.fragment = this.getFragment(null, true);
  14664. this.location.replace(this.root + this.location.search + '#' + this.fragment);
  14665. // Return immediately as browser will do redirect to new url
  14666. return true;
  14667. // Or if we've started out with a hash-based route, but we're currently
  14668. // in a browser where it could be `pushState`-based instead...
  14669. } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
  14670. this.fragment = this.getHash().replace(routeStripper, '');
  14671. this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
  14672. }
  14673. if (!this.options.silent) return this.loadUrl();
  14674. },
  14675. // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
  14676. // but possibly useful for unit testing Routers.
  14677. stop: function() {
  14678. Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
  14679. clearInterval(this._checkUrlInterval);
  14680. History.started = false;
  14681. },
  14682. // Add a route to be tested when the fragment changes. Routes added later
  14683. // may override previous routes.
  14684. route: function(route, callback) {
  14685. this.handlers.unshift({route: route, callback: callback});
  14686. },
  14687. // Checks the current URL to see if it has changed, and if it has,
  14688. // calls `loadUrl`, normalizing across the hidden iframe.
  14689. checkUrl: function(e) {
  14690. var current = this.getFragment();
  14691. if (current === this.fragment && this.iframe) {
  14692. current = this.getFragment(this.getHash(this.iframe));
  14693. }
  14694. if (current === this.fragment) return false;
  14695. if (this.iframe) this.navigate(current);
  14696. this.loadUrl() || this.loadUrl(this.getHash());
  14697. },
  14698. // Attempt to load the current URL fragment. If a route succeeds with a
  14699. // match, returns `true`. If no defined routes matches the fragment,
  14700. // returns `false`.
  14701. loadUrl: function(fragmentOverride) {
  14702. var fragment = this.fragment = this.getFragment(fragmentOverride);
  14703. var matched = _.any(this.handlers, function(handler) {
  14704. if (handler.route.test(fragment)) {
  14705. handler.callback(fragment);
  14706. return true;
  14707. }
  14708. });
  14709. return matched;
  14710. },
  14711. // Save a fragment into the hash history, or replace the URL state if the
  14712. // 'replace' option is passed. You are responsible for properly URL-encoding
  14713. // the fragment in advance.
  14714. //
  14715. // The options object can contain `trigger: true` if you wish to have the
  14716. // route callback be fired (not usually desirable), or `replace: true`, if
  14717. // you wish to modify the current URL without adding an entry to the history.
  14718. navigate: function(fragment, options) {
  14719. if (!History.started) return false;
  14720. if (!options || options === true) options = {trigger: options};
  14721. fragment = this.getFragment(fragment || '');
  14722. if (this.fragment === fragment) return;
  14723. this.fragment = fragment;
  14724. var url = this.root + fragment;
  14725. // If pushState is available, we use it to set the fragment as a real URL.
  14726. if (this._hasPushState) {
  14727. this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
  14728. // If hash changes haven't been explicitly disabled, update the hash
  14729. // fragment to store history.
  14730. } else if (this._wantsHashChange) {
  14731. this._updateHash(this.location, fragment, options.replace);
  14732. if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
  14733. // Opening and closing the iframe tricks IE7 and earlier to push a
  14734. // history entry on hash-tag change. When replace is true, we don't
  14735. // want this.
  14736. if(!options.replace) this.iframe.document.open().close();
  14737. this._updateHash(this.iframe.location, fragment, options.replace);
  14738. }
  14739. // If you've told us that you explicitly don't want fallback hashchange-
  14740. // based history, then `navigate` becomes a page refresh.
  14741. } else {
  14742. return this.location.assign(url);
  14743. }
  14744. if (options.trigger) this.loadUrl(fragment);
  14745. },
  14746. // Update the hash location, either replacing the current entry, or adding
  14747. // a new one to the browser history.
  14748. _updateHash: function(location, fragment, replace) {
  14749. if (replace) {
  14750. var href = location.href.replace(/(javascript:|#).*$/, '');
  14751. location.replace(href + '#' + fragment);
  14752. } else {
  14753. // Some browsers require that `hash` contains a leading #.
  14754. location.hash = '#' + fragment;
  14755. }
  14756. }
  14757. });
  14758. // Create the default Backbone.history.
  14759. Backbone.history = new History;
  14760. // Helpers
  14761. // -------
  14762. // Helper function to correctly set up the prototype chain, for subclasses.
  14763. // Similar to `goog.inherits`, but uses a hash of prototype properties and
  14764. // class properties to be extended.
  14765. var extend = function(protoProps, staticProps) {
  14766. var parent = this;
  14767. var child;
  14768. // The constructor function for the new subclass is either defined by you
  14769. // (the "constructor" property in your `extend` definition), or defaulted
  14770. // by us to simply call the parent's constructor.
  14771. if (protoProps && _.has(protoProps, 'constructor')) {
  14772. child = protoProps.constructor;
  14773. } else {
  14774. child = function(){ return parent.apply(this, arguments); };
  14775. }
  14776. // Add static properties to the constructor function, if supplied.
  14777. _.extend(child, parent, staticProps);
  14778. // Set the prototype chain to inherit from `parent`, without calling
  14779. // `parent`'s constructor function.
  14780. var Surrogate = function(){ this.constructor = child; };
  14781. Surrogate.prototype = parent.prototype;
  14782. child.prototype = new Surrogate;
  14783. // Add prototype properties (instance properties) to the subclass,
  14784. // if supplied.
  14785. if (protoProps) _.extend(child.prototype, protoProps);
  14786. // Set a convenience property in case the parent's prototype is needed
  14787. // later.
  14788. child.__super__ = parent.prototype;
  14789. return child;
  14790. };
  14791. // Set up inheritance for the model, collection, router, view and history.
  14792. Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
  14793. // Throw an error when a URL is needed, and none is supplied.
  14794. var urlError = function() {
  14795. throw new Error('A "url" property or function must be specified');
  14796. };
  14797. // Wrap an optional error callback with a fallback error event.
  14798. var wrapError = function (model, options) {
  14799. var error = options.error;
  14800. options.error = function(resp) {
  14801. if (error) error(model, resp, options);
  14802. model.trigger('error', model, resp, options);
  14803. };
  14804. };
  14805. }).call(this);
  14806. // Vectorizer.
  14807. // -----------
  14808. // A tiny library for making your live easier when dealing with SVG.
  14809. // Copyright © 2012 - 2014 client IO (http://client.io)
  14810. (function(root, factory) {
  14811. if (typeof define === 'function' && define.amd) {
  14812. // AMD. Register as an anonymous module.
  14813. define([], factory);
  14814. } else {
  14815. // Browser globals.
  14816. root.Vectorizer = root.V = factory();
  14817. }
  14818. }(this, function() {
  14819. // Well, if SVG is not supported, this library is useless.
  14820. var SVGsupported = !!(window.SVGAngle || document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'));
  14821. // XML namespaces.
  14822. var ns = {
  14823. xmlns: 'http://www.w3.org/2000/svg',
  14824. xlink: 'http://www.w3.org/1999/xlink'
  14825. };
  14826. // SVG version.
  14827. var SVGversion = '1.1';
  14828. // A function returning a unique identifier for this client session with every call.
  14829. var idCounter = 0;
  14830. function uniqueId() {
  14831. var id = ++idCounter + '';
  14832. return 'v-' + id;
  14833. }
  14834. // Create SVG element.
  14835. // -------------------
  14836. function createElement(el, attrs, children) {
  14837. if (!el) return undefined;
  14838. // If `el` is an object, it is probably a native SVG element. Wrap it to VElement.
  14839. if (typeof el === 'object') {
  14840. return new VElement(el);
  14841. }
  14842. attrs = attrs || {};
  14843. // If `el` is a `'svg'` or `'SVG'` string, create a new SVG canvas.
  14844. if (el.toLowerCase() === 'svg') {
  14845. attrs.xmlns = ns.xmlns;
  14846. attrs['xmlns:xlink'] = ns.xlink;
  14847. attrs.version = SVGversion;
  14848. } else if (el[0] === '<') {
  14849. // Create element from an SVG string.
  14850. // Allows constructs of type: `document.appendChild(Vectorizer('<rect></rect>').node)`.
  14851. var svg = '<svg xmlns="' + ns.xmlns + '" xmlns:xlink="' + ns.xlink + '" version="' + SVGversion + '">' + el + '</svg>';
  14852. var parser = new DOMParser();
  14853. parser.async = false;
  14854. var svgDoc = parser.parseFromString(svg, 'text/xml').documentElement;
  14855. // Note that `createElement()` might also return an array should the SVG string passed as
  14856. // the first argument contain more then one root element.
  14857. if (svgDoc.childNodes.length > 1) {
  14858. // Map child nodes to `VElement`s.
  14859. var ret = [];
  14860. for (var i = 0, len = svgDoc.childNodes.length; i < len; i++) {
  14861. var childNode = svgDoc.childNodes[i];
  14862. ret.push(new VElement(document.importNode(childNode, true)));
  14863. }
  14864. return ret;
  14865. }
  14866. return new VElement(document.importNode(svgDoc.firstChild, true));
  14867. }
  14868. el = document.createElementNS(ns.xmlns, el);
  14869. // Set attributes.
  14870. for (var key in attrs) {
  14871. setAttribute(el, key, attrs[key]);
  14872. }
  14873. // Normalize `children` array.
  14874. if (Object.prototype.toString.call(children) != '[object Array]') children = [children];
  14875. // Append children if they are specified.
  14876. var i = 0, len = (children[0] && children.length) || 0, child;
  14877. for (; i < len; i++) {
  14878. child = children[i];
  14879. el.appendChild(child instanceof VElement ? child.node : child);
  14880. }
  14881. return new VElement(el);
  14882. }
  14883. function setAttribute(el, name, value) {
  14884. if (name.indexOf(':') > -1) {
  14885. // Attribute names can be namespaced. E.g. `image` elements
  14886. // have a `xlink:href` attribute to set the source of the image.
  14887. var combinedKey = name.split(':');
  14888. el.setAttributeNS(ns[combinedKey[0]], combinedKey[1], value);
  14889. } else if (name === 'id') {
  14890. el.id = value;
  14891. } else {
  14892. el.setAttribute(name, value);
  14893. }
  14894. }
  14895. function parseTransformString(transform) {
  14896. var translate,
  14897. rotate,
  14898. scale;
  14899. if (transform) {
  14900. var translateMatch = transform.match(/translate\((.*)\)/);
  14901. if (translateMatch) {
  14902. translate = translateMatch[1].split(',');
  14903. }
  14904. var rotateMatch = transform.match(/rotate\((.*)\)/);
  14905. if (rotateMatch) {
  14906. rotate = rotateMatch[1].split(',');
  14907. }
  14908. var scaleMatch = transform.match(/scale\((.*)\)/);
  14909. if (scaleMatch) {
  14910. scale = scaleMatch[1].split(',');
  14911. }
  14912. }
  14913. var sx = (scale && scale[0]) ? parseFloat(scale[0]) : 1;
  14914. return {
  14915. translate: {
  14916. tx: (translate && translate[0]) ? parseInt(translate[0], 10) : 0,
  14917. ty: (translate && translate[1]) ? parseInt(translate[1], 10) : 0
  14918. },
  14919. rotate: {
  14920. angle: (rotate && rotate[0]) ? parseInt(rotate[0], 10) : 0,
  14921. cx: (rotate && rotate[1]) ? parseInt(rotate[1], 10) : undefined,
  14922. cy: (rotate && rotate[2]) ? parseInt(rotate[2], 10) : undefined
  14923. },
  14924. scale: {
  14925. sx: sx,
  14926. sy: (scale && scale[1]) ? parseFloat(scale[1]) : sx
  14927. }
  14928. };
  14929. }
  14930. // Matrix decomposition.
  14931. // ---------------------
  14932. function deltaTransformPoint(matrix, point) {
  14933. var dx = point.x * matrix.a + point.y * matrix.c + 0;
  14934. var dy = point.x * matrix.b + point.y * matrix.d + 0;
  14935. return { x: dx, y: dy };
  14936. }
  14937. function decomposeMatrix(matrix) {
  14938. // @see https://gist.github.com/2052247
  14939. // calculate delta transform point
  14940. var px = deltaTransformPoint(matrix, { x: 0, y: 1 });
  14941. var py = deltaTransformPoint(matrix, { x: 1, y: 0 });
  14942. // calculate skew
  14943. var skewX = ((180 / Math.PI) * Math.atan2(px.y, px.x) - 90);
  14944. var skewY = ((180 / Math.PI) * Math.atan2(py.y, py.x));
  14945. return {
  14946. translateX: matrix.e,
  14947. translateY: matrix.f,
  14948. scaleX: Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b),
  14949. scaleY: Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d),
  14950. skewX: skewX,
  14951. skewY: skewY,
  14952. rotation: skewX // rotation is the same as skew x
  14953. };
  14954. }
  14955. // VElement.
  14956. // ---------
  14957. function VElement(el) {
  14958. this.node = el;
  14959. if (!this.node.id) {
  14960. this.node.id = uniqueId();
  14961. }
  14962. }
  14963. // VElement public API.
  14964. // --------------------
  14965. VElement.prototype = {
  14966. translate: function(tx, ty) {
  14967. ty = ty || 0;
  14968. var transformAttr = this.attr('transform') || '',
  14969. transform = parseTransformString(transformAttr);
  14970. // Is it a getter?
  14971. if (typeof tx === 'undefined') {
  14972. return transform.translate;
  14973. }
  14974. transformAttr = transformAttr.replace(/translate\([^\)]*\)/g, '').trim();
  14975. var newTx = transform.translate.tx + tx,
  14976. newTy = transform.translate.ty + ty;
  14977. // Note that `translate()` is always the first transformation. This is
  14978. // usually the desired case.
  14979. this.attr('transform', 'translate(' + newTx + ',' + newTy + ') ' + transformAttr);
  14980. return this;
  14981. },
  14982. rotate: function(angle, cx, cy) {
  14983. var transformAttr = this.attr('transform') || '',
  14984. transform = parseTransformString(transformAttr);
  14985. // Is it a getter?
  14986. if (typeof angle === 'undefined') {
  14987. return transform.rotate;
  14988. }
  14989. transformAttr = transformAttr.replace(/rotate\([^\)]*\)/g, '').trim();
  14990. var newAngle = transform.rotate.angle + angle % 360,
  14991. newOrigin = (cx !== undefined && cy !== undefined) ? ',' + cx + ',' + cy : '';
  14992. this.attr('transform', transformAttr + ' rotate(' + newAngle + newOrigin + ')');
  14993. return this;
  14994. },
  14995. // Note that `scale` as the only transformation does not combine with previous values.
  14996. scale: function(sx, sy) {
  14997. sy = (typeof sy === 'undefined') ? sx : sy;
  14998. var transformAttr = this.attr('transform') || '',
  14999. transform = parseTransformString(transformAttr);
  15000. // Is it a getter?
  15001. if (typeof sx === 'undefined') {
  15002. return transform.scale;
  15003. }
  15004. transformAttr = transformAttr.replace(/scale\([^\)]*\)/g, '').trim();
  15005. this.attr('transform', transformAttr + ' scale(' + sx + ',' + sy + ')');
  15006. return this;
  15007. },
  15008. // Get SVGRect that contains coordinates and dimension of the real bounding box,
  15009. // i.e. after transformations are applied.
  15010. // If `target` is specified, bounding box will be computed relatively to `target` element.
  15011. bbox: function(withoutTransformations, target) {
  15012. // If the element is not in the live DOM, it does not have a bounding box defined and
  15013. // so fall back to 'zero' dimension element.
  15014. if (!this.node.ownerSVGElement) return { x: 0, y: 0, width: 0, height: 0 };
  15015. var box;
  15016. try {
  15017. box = this.node.getBBox();
  15018. // Opera returns infinite values in some cases.
  15019. // Note that Infinity | 0 produces 0 as opposed to Infinity || 0.
  15020. // We also have to create new object as the standard says that you can't
  15021. // modify the attributes of a bbox.
  15022. box = { x: box.x | 0, y: box.y | 0, width: box.width | 0, height: box.height | 0};
  15023. } catch (e) {
  15024. // Fallback for IE.
  15025. box = {
  15026. x: this.node.clientLeft,
  15027. y: this.node.clientTop,
  15028. width: this.node.clientWidth,
  15029. height: this.node.clientHeight
  15030. };
  15031. }
  15032. if (withoutTransformations) {
  15033. return box;
  15034. }
  15035. var matrix = this.node.getTransformToElement(target || this.node.ownerSVGElement);
  15036. var corners = [];
  15037. var point = this.node.ownerSVGElement.createSVGPoint();
  15038. point.x = box.x;
  15039. point.y = box.y;
  15040. corners.push(point.matrixTransform(matrix));
  15041. point.x = box.x + box.width;
  15042. point.y = box.y;
  15043. corners.push(point.matrixTransform(matrix));
  15044. point.x = box.x + box.width;
  15045. point.y = box.y + box.height;
  15046. corners.push(point.matrixTransform(matrix));
  15047. point.x = box.x;
  15048. point.y = box.y + box.height;
  15049. corners.push(point.matrixTransform(matrix));
  15050. var minX = corners[0].x;
  15051. var maxX = minX;
  15052. var minY = corners[0].y;
  15053. var maxY = minY;
  15054. for (var i = 1, len = corners.length; i < len; i++) {
  15055. var x = corners[i].x;
  15056. var y = corners[i].y;
  15057. if (x < minX) {
  15058. minX = x;
  15059. } else if (x > maxX) {
  15060. maxX = x;
  15061. }
  15062. if (y < minY) {
  15063. minY = y;
  15064. } else if (y > maxY) {
  15065. maxY = y;
  15066. }
  15067. }
  15068. return {
  15069. x: minX,
  15070. y: minY,
  15071. width: maxX - minX,
  15072. height: maxY - minY
  15073. };
  15074. },
  15075. text: function(content) {
  15076. var lines = content.split('\n'), i = 0,
  15077. tspan;
  15078. // `alignment-baseline` does not work in Firefox.
  15079. // Setting `dominant-baseline` on the `<text>` element doesn't work in IE9.
  15080. // In order to have the 0,0 coordinate of the `<text>` element (or the first `<tspan>`)
  15081. // in the top left corner we translate the `<text>` element by `0.8em`.
  15082. // See `http://www.w3.org/Graphics/SVG/WG/wiki/How_to_determine_dominant_baseline`.
  15083. // See also `http://apike.ca/prog_svg_text_style.html`.
  15084. this.attr('y', '0.8em');
  15085. // An empty text gets rendered into the DOM in webkit-based browsers.
  15086. // In order to unify this behaviour across all browsers
  15087. // we rather hide the text element when it's empty.
  15088. this.attr('display', content ? null : 'none');
  15089. if (lines.length === 1) {
  15090. this.node.textContent = content;
  15091. return this;
  15092. }
  15093. // Easy way to erase all `<tspan>` children;
  15094. this.node.textContent = '';
  15095. for (; i < lines.length; i++) {
  15096. // Shift all the <tspan> but first by one line (`1em`)
  15097. tspan = V('tspan', { dy: (i == 0 ? '0em' : '1em'), x: this.attr('x') || 0});
  15098. tspan.node.textContent = lines[i];
  15099. this.append(tspan);
  15100. }
  15101. return this;
  15102. },
  15103. attr: function(name, value) {
  15104. if (typeof name === 'string' && typeof value === 'undefined') {
  15105. return this.node.getAttribute(name);
  15106. }
  15107. if (typeof name === 'object') {
  15108. for (var attrName in name) {
  15109. if (name.hasOwnProperty(attrName)) {
  15110. setAttribute(this.node, attrName, name[attrName]);
  15111. }
  15112. }
  15113. } else {
  15114. setAttribute(this.node, name, value);
  15115. }
  15116. return this;
  15117. },
  15118. remove: function() {
  15119. if (this.node.parentNode) {
  15120. this.node.parentNode.removeChild(this.node);
  15121. }
  15122. },
  15123. append: function(el) {
  15124. var els = el;
  15125. if (Object.prototype.toString.call(el) !== '[object Array]') {
  15126. els = [el];
  15127. }
  15128. for (var i = 0, len = els.length; i < len; i++) {
  15129. el = els[i];
  15130. this.node.appendChild(el instanceof VElement ? el.node : el);
  15131. }
  15132. return this;
  15133. },
  15134. prepend: function(el) {
  15135. this.node.insertBefore(el instanceof VElement ? el.node : el, this.node.firstChild);
  15136. },
  15137. svg: function() {
  15138. return this.node instanceof window.SVGSVGElement ? this : V(this.node.ownerSVGElement);
  15139. },
  15140. defs: function() {
  15141. var defs = this.svg().node.getElementsByTagName('defs');
  15142. return (defs && defs.length) ? V(defs[0]) : undefined;
  15143. },
  15144. clone: function() {
  15145. var clone = V(this.node.cloneNode(true));
  15146. // Note that clone inherits also ID. Therefore, we need to change it here.
  15147. clone.node.id = uniqueId();
  15148. return clone;
  15149. },
  15150. findOne: function(selector) {
  15151. var found = this.node.querySelector(selector);
  15152. return found ? V(found) : undefined;
  15153. },
  15154. find: function(selector) {
  15155. var nodes = this.node.querySelectorAll(selector);
  15156. // Map DOM elements to `VElement`s.
  15157. for (var i = 0, len = nodes.length; i < len; i++) {
  15158. nodes[i] = V(nodes[i]);
  15159. }
  15160. return nodes;
  15161. },
  15162. // Convert global point into the coordinate space of this element.
  15163. toLocalPoint: function(x, y) {
  15164. var svg = this.svg().node;
  15165. var p = svg.createSVGPoint();
  15166. p.x = x;
  15167. p.y = y;
  15168. try {
  15169. var globalPoint = p.matrixTransform(svg.getScreenCTM().inverse());
  15170. var globalToLocalMatrix = this.node.getTransformToElement(svg).inverse();
  15171. } catch(e) {
  15172. // IE9 throws an exception in odd cases. (`Unexpected call to method or property access`)
  15173. // We have to make do with the original coordianates.
  15174. return p;
  15175. }
  15176. return globalPoint.matrixTransform(globalToLocalMatrix);
  15177. },
  15178. translateCenterToPoint: function(p) {
  15179. var bbox = this.bbox();
  15180. var center = g.rect(bbox).center();
  15181. this.translate(p.x - center.x, p.y - center.y);
  15182. },
  15183. // Efficiently auto-orient an element. This basically implements the orient=auto attribute
  15184. // of markers. The easiest way of understanding on what this does is to imagine the element is an
  15185. // arrowhead. Calling this method on the arrowhead makes it point to the `position` point while
  15186. // being auto-oriented (properly rotated) towards the `reference` point.
  15187. // `target` is the element relative to which the transformations are applied. Usually a viewport.
  15188. translateAndAutoOrient: function(position, reference, target) {
  15189. // Clean-up previously set transformations except the scale. If we didn't clean up the
  15190. // previous transformations then they'd add up with the old ones. Scale is an exception as
  15191. // it doesn't add up, consider: `this.scale(2).scale(2).scale(2)`. The result is that the
  15192. // element is scaled by the factor 2, not 8.
  15193. var s = this.scale();
  15194. this.attr('transform', '');
  15195. this.scale(s.sx, s.sy);
  15196. var svg = this.svg().node;
  15197. var bbox = this.bbox(false, target);
  15198. // 1. Translate to origin.
  15199. var translateToOrigin = svg.createSVGTransform();
  15200. translateToOrigin.setTranslate(-bbox.x - bbox.width/2, -bbox.y - bbox.height/2);
  15201. // 2. Rotate around origin.
  15202. var rotateAroundOrigin = svg.createSVGTransform();
  15203. var angle = g.point(position).changeInAngle(position.x - reference.x, position.y - reference.y, reference);
  15204. rotateAroundOrigin.setRotate(angle, 0, 0);
  15205. // 3. Translate to the `position` + the offset (half my width) towards the `reference` point.
  15206. var translateFinal = svg.createSVGTransform();
  15207. var finalPosition = g.point(position).move(reference, bbox.width/2);
  15208. translateFinal.setTranslate(position.x + (position.x - finalPosition.x), position.y + (position.y - finalPosition.y));
  15209. // 4. Apply transformations.
  15210. var ctm = this.node.getTransformToElement(target);
  15211. var transform = svg.createSVGTransform();
  15212. transform.setMatrix(
  15213. translateFinal.matrix.multiply(
  15214. rotateAroundOrigin.matrix.multiply(
  15215. translateToOrigin.matrix.multiply(
  15216. ctm)))
  15217. );
  15218. // Instead of directly setting the `matrix()` transform on the element, first, decompose
  15219. // the matrix into separate transforms. This allows us to use normal Vectorizer methods
  15220. // as they don't work on matrices. An example of this is to retrieve a scale of an element.
  15221. // this.node.transform.baseVal.initialize(transform);
  15222. var decomposition = decomposeMatrix(transform.matrix);
  15223. this.translate(decomposition.translateX, decomposition.translateY);
  15224. this.rotate(decomposition.rotation);
  15225. // Note that scale has been already applied, hence the following line stays commented. (it's here just for reference).
  15226. //this.scale(decomposition.scaleX, decomposition.scaleY);
  15227. return this;
  15228. },
  15229. animateAlongPath: function(attrs, path) {
  15230. var animateMotion = V('animateMotion', attrs);
  15231. var mpath = V('mpath', { 'xlink:href': '#' + V(path).node.id });
  15232. animateMotion.append(mpath);
  15233. this.append(animateMotion);
  15234. try {
  15235. animateMotion.node.beginElement();
  15236. } catch (e) {
  15237. // Fallback for IE 9.
  15238. // Run the animation programatically if FakeSmile (`http://leunen.me/fakesmile/`) present
  15239. if (document.documentElement.getAttribute('smiling') === 'fake') {
  15240. // Register the animation. (See `https://answers.launchpad.net/smil/+question/203333`)
  15241. var animation = animateMotion.node;
  15242. animation.animators = [];
  15243. var animationID = animation.getAttribute('id');
  15244. if (animationID) id2anim[animationID] = animation;
  15245. var targets = getTargets(animation);
  15246. for (var i = 0, len = targets.length; i < len; i++) {
  15247. var target = targets[i];
  15248. var animator = new Animator(animation, target, i);
  15249. animators.push(animator);
  15250. animation.animators[i] = animator;
  15251. animator.register();
  15252. }
  15253. }
  15254. }
  15255. },
  15256. hasClass: function(className) {
  15257. return new RegExp('(\\s|^)' + className + '(\\s|$)').test(this.node.getAttribute('class'));
  15258. },
  15259. addClass: function(className) {
  15260. if (!this.hasClass(className)) {
  15261. this.node.setAttribute('class', this.node.getAttribute('class') + ' ' + className);
  15262. }
  15263. return this;
  15264. },
  15265. removeClass: function(className) {
  15266. var removedClass = this.node.getAttribute('class').replace(new RegExp('(\\s|^)' + className + '(\\s|$)', 'g'), '$2');
  15267. if (this.hasClass(className)) {
  15268. this.node.setAttribute('class', removedClass);
  15269. }
  15270. return this;
  15271. },
  15272. toggleClass: function(className, toAdd) {
  15273. var toRemove = typeof toAdd === 'undefined' ? this.hasClass(className) : !toAdd;
  15274. if (toRemove) {
  15275. this.removeClass(className);
  15276. } else {
  15277. this.addClass(className);
  15278. }
  15279. return this;
  15280. }
  15281. };
  15282. // Convert a rectangle to SVG path commands. `r` is an object of the form:
  15283. // `{ x: [number], y: [number], width: [number], height: [number], top-ry: [number], top-ry: [number], bottom-rx: [number], bottom-ry: [number] }`,
  15284. // where `x, y, width, height` are the usual rectangle attributes and [top-/bottom-]rx/ry allows for
  15285. // specifying radius of the rectangle for all its sides (as opposed to the built-in SVG rectangle
  15286. // that has only `rx` and `ry` attributes).
  15287. function rectToPath(r) {
  15288. var topRx = r.rx || r['top-rx'] || 0;
  15289. var bottomRx = r.rx || r['bottom-rx'] || 0;
  15290. var topRy = r.ry || r['top-ry'] || 0;
  15291. var bottomRy = r.ry || r['bottom-ry'] || 0;
  15292. return [
  15293. 'M', r.x, r.y + topRy,
  15294. 'v', r.height - topRy - bottomRy,
  15295. 'a', bottomRx, bottomRy, 0, 0, 0, bottomRx, bottomRy,
  15296. 'h', r.width - 2 * bottomRx,
  15297. 'a', bottomRx, bottomRy, 0, 0, 0, bottomRx, -bottomRy,
  15298. 'v', -(r.height - bottomRy - topRy),
  15299. 'a', topRx, topRy, 0, 0, 0, -topRx, -topRy,
  15300. 'h', -(r.width - 2 * topRx),
  15301. 'a', topRx, topRy, 0, 0, 0, -topRx, topRy
  15302. ].join(' ');
  15303. }
  15304. var V = createElement;
  15305. V.decomposeMatrix = decomposeMatrix;
  15306. V.rectToPath = rectToPath;
  15307. var svgDocument = V('svg').node;
  15308. V.createSVGMatrix = function(m) {
  15309. var svgMatrix = svgDocument.createSVGMatrix();
  15310. for (var component in m) {
  15311. svgMatrix[component] = m[component];
  15312. }
  15313. return svgMatrix;
  15314. };
  15315. V.createSVGTransform = function() {
  15316. return svgDocument.createSVGTransform();
  15317. };
  15318. V.createSVGPoint = function(x, y) {
  15319. var p = svgDocument.createSVGPoint();
  15320. p.x = x;
  15321. p.y = y;
  15322. return p;
  15323. };
  15324. return V;
  15325. }));
  15326. // Geometry library.
  15327. // (c) 2011-2013 client IO
  15328. (function(root, factory) {
  15329. if (typeof define === 'function' && define.amd) {
  15330. // AMD. Register as an anonymous module.
  15331. define([], factory);
  15332. } else if (typeof exports === 'object') {
  15333. // Node. Does not work with strict CommonJS, but
  15334. // only CommonJS-like environments that support module.exports,
  15335. // like Node.
  15336. module.exports = factory();
  15337. } else {
  15338. // Browser globals.
  15339. root.g = factory();
  15340. }
  15341. }(this, function() {
  15342. // Declare shorthands to the most used math functions.
  15343. var math = Math;
  15344. var abs = math.abs;
  15345. var cos = math.cos;
  15346. var sin = math.sin;
  15347. var sqrt = math.sqrt;
  15348. var mmin = math.min;
  15349. var mmax = math.max;
  15350. var atan = math.atan;
  15351. var atan2 = math.atan2;
  15352. var acos = math.acos;
  15353. var round = math.round;
  15354. var floor = math.floor;
  15355. var PI = math.PI;
  15356. var random = math.random;
  15357. var toDeg = function(rad) { return (180*rad / PI) % 360; };
  15358. var toRad = function(deg) { return (deg % 360) * PI / 180; };
  15359. var snapToGrid = function(val, gridSize) { return gridSize * Math.round(val/gridSize); };
  15360. var normalizeAngle = function(angle) { return (angle % 360) + (angle < 0 ? 360 : 0); };
  15361. // Point
  15362. // -----
  15363. // Point is the most basic object consisting of x/y coordinate,.
  15364. // Possible instantiations are:
  15365. // * `point(10, 20)`
  15366. // * `new point(10, 20)`
  15367. // * `point('10 20')`
  15368. // * `point(point(10, 20))`
  15369. function point(x, y) {
  15370. if (!(this instanceof point))
  15371. return new point(x, y);
  15372. var xy;
  15373. if (y === undefined && Object(x) !== x) {
  15374. xy = x.split(x.indexOf('@') === -1 ? ' ' : '@');
  15375. this.x = parseInt(xy[0], 10);
  15376. this.y = parseInt(xy[1], 10);
  15377. } else if (Object(x) === x) {
  15378. this.x = x.x;
  15379. this.y = x.y;
  15380. } else {
  15381. this.x = x;
  15382. this.y = y;
  15383. }
  15384. }
  15385. point.prototype = {
  15386. toString: function() {
  15387. return this.x + "@" + this.y;
  15388. },
  15389. // If point lies outside rectangle `r`, return the nearest point on the boundary of rect `r`,
  15390. // otherwise return point itself.
  15391. // (see Squeak Smalltalk, Point>>adhereTo:)
  15392. adhereToRect: function(r) {
  15393. if (r.containsPoint(this)){
  15394. return this;
  15395. }
  15396. this.x = mmin(mmax(this.x, r.x), r.x + r.width);
  15397. this.y = mmin(mmax(this.y, r.y), r.y + r.height);
  15398. return this;
  15399. },
  15400. // Compute the angle between me and `p` and the x axis.
  15401. // (cartesian-to-polar coordinates conversion)
  15402. // Return theta angle in degrees.
  15403. theta: function(p) {
  15404. p = point(p);
  15405. // Invert the y-axis.
  15406. var y = -(p.y - this.y);
  15407. var x = p.x - this.x;
  15408. // Makes sure that the comparison with zero takes rounding errors into account.
  15409. var PRECISION = 10;
  15410. // Note that `atan2` is not defined for `x`, `y` both equal zero.
  15411. var rad = (y.toFixed(PRECISION) == 0 && x.toFixed(PRECISION) == 0) ? 0 : atan2(y, x);
  15412. // Correction for III. and IV. quadrant.
  15413. if (rad < 0) {
  15414. rad = 2*PI + rad;
  15415. }
  15416. return 180*rad / PI;
  15417. },
  15418. // Returns distance between me and point `p`.
  15419. distance: function(p) {
  15420. return line(this, p).length();
  15421. },
  15422. // Returns a manhattan (taxi-cab) distance between me and point `p`.
  15423. manhattanDistance: function(p) {
  15424. return abs(p.x - this.x) + abs(p.y - this.y);
  15425. },
  15426. // Offset me by the specified amount.
  15427. offset: function(dx, dy) {
  15428. this.x += dx || 0;
  15429. this.y += dy || 0;
  15430. return this;
  15431. },
  15432. magnitude: function() {
  15433. return sqrt((this.x*this.x) + (this.y*this.y)) || 0.01;
  15434. },
  15435. update: function(x, y) {
  15436. this.x = x || 0;
  15437. this.y = y || 0;
  15438. return this;
  15439. },
  15440. round: function(decimals) {
  15441. this.x = decimals ? this.x.toFixed(decimals) : round(this.x);
  15442. this.y = decimals ? this.y.toFixed(decimals) : round(this.y);
  15443. return this;
  15444. },
  15445. // Scale the line segment between (0,0) and me to have a length of len.
  15446. normalize: function(len) {
  15447. var s = (len || 1) / this.magnitude();
  15448. this.x = s * this.x;
  15449. this.y = s * this.y;
  15450. return this;
  15451. },
  15452. difference: function(p) {
  15453. return point(this.x - p.x, this.y - p.y);
  15454. },
  15455. // Return the bearing between me and point `p`.
  15456. bearing: function(p) {
  15457. return line(this, p).bearing();
  15458. },
  15459. // Converts rectangular to polar coordinates.
  15460. // An origin can be specified, otherwise it's 0@0.
  15461. toPolar: function(o) {
  15462. o = (o && point(o)) || point(0,0);
  15463. var x = this.x;
  15464. var y = this.y;
  15465. this.x = sqrt((x-o.x)*(x-o.x) + (y-o.y)*(y-o.y)); // r
  15466. this.y = toRad(o.theta(point(x,y)));
  15467. return this;
  15468. },
  15469. // Rotate point by angle around origin o.
  15470. rotate: function(o, angle) {
  15471. angle = (angle + 360) % 360;
  15472. this.toPolar(o);
  15473. this.y += toRad(angle);
  15474. var p = point.fromPolar(this.x, this.y, o);
  15475. this.x = p.x;
  15476. this.y = p.y;
  15477. return this;
  15478. },
  15479. // Move point on line starting from ref ending at me by
  15480. // distance distance.
  15481. move: function(ref, distance) {
  15482. var theta = toRad(point(ref).theta(this));
  15483. return this.offset(cos(theta) * distance, -sin(theta) * distance);
  15484. },
  15485. // Returns change in angle from my previous position (-dx, -dy) to my new position
  15486. // relative to ref point.
  15487. changeInAngle: function(dx, dy, ref) {
  15488. // Revert the translation and measure the change in angle around x-axis.
  15489. return point(this).offset(-dx, -dy).theta(ref) - this.theta(ref);
  15490. },
  15491. equals: function(p) {
  15492. return this.x === p.x && this.y === p.y;
  15493. },
  15494. snapToGrid: function(gx, gy) {
  15495. this.x = snapToGrid(this.x, gx)
  15496. this.y = snapToGrid(this.y, gy || gx)
  15497. return this;
  15498. }
  15499. };
  15500. // Alternative constructor, from polar coordinates.
  15501. // @param {number} r Distance.
  15502. // @param {number} angle Angle in radians.
  15503. // @param {point} [optional] o Origin.
  15504. point.fromPolar = function(r, angle, o) {
  15505. o = (o && point(o)) || point(0,0);
  15506. var x = abs(r * cos(angle));
  15507. var y = abs(r * sin(angle));
  15508. var deg = normalizeAngle(toDeg(angle));
  15509. if (deg < 90) y = -y;
  15510. else if (deg < 180) { x = -x; y = -y; }
  15511. else if (deg < 270) x = -x;
  15512. return point(o.x + x, o.y + y);
  15513. };
  15514. // Create a point with random coordinates that fall into the range `[x1, x2]` and `[y1, y2]`.
  15515. point.random = function(x1, x2, y1, y2) {
  15516. return point(floor(random() * (x2 - x1 + 1) + x1), floor(random() * (y2 - y1 + 1) + y1));
  15517. };
  15518. // Line.
  15519. // -----
  15520. function line(p1, p2) {
  15521. if (!(this instanceof line))
  15522. return new line(p1, p2);
  15523. this.start = point(p1);
  15524. this.end = point(p2);
  15525. }
  15526. line.prototype = {
  15527. toString: function() {
  15528. return this.start.toString() + ' ' + this.end.toString();
  15529. },
  15530. // @return {double} length of the line
  15531. length: function() {
  15532. return sqrt(this.squaredLength());
  15533. },
  15534. // @return {integer} length without sqrt
  15535. // @note for applications where the exact length is not necessary (e.g. compare only)
  15536. squaredLength: function() {
  15537. var x0 = this.start.x;
  15538. var y0 = this.start.y;
  15539. var x1 = this.end.x;
  15540. var y1 = this.end.y;
  15541. return (x0 -= x1)*x0 + (y0 -= y1)*y0;
  15542. },
  15543. // @return {point} my midpoint
  15544. midpoint: function() {
  15545. return point((this.start.x + this.end.x) / 2,
  15546. (this.start.y + this.end.y) / 2);
  15547. },
  15548. // @return {point} Point where I'm intersecting l.
  15549. // @see Squeak Smalltalk, LineSegment>>intersectionWith:
  15550. intersection: function(l) {
  15551. var pt1Dir = point(this.end.x - this.start.x, this.end.y - this.start.y);
  15552. var pt2Dir = point(l.end.x - l.start.x, l.end.y - l.start.y);
  15553. var det = (pt1Dir.x * pt2Dir.y) - (pt1Dir.y * pt2Dir.x);
  15554. var deltaPt = point(l.start.x - this.start.x, l.start.y - this.start.y);
  15555. var alpha = (deltaPt.x * pt2Dir.y) - (deltaPt.y * pt2Dir.x);
  15556. var beta = (deltaPt.x * pt1Dir.y) - (deltaPt.y * pt1Dir.x);
  15557. if (det === 0 ||
  15558. alpha * det < 0 ||
  15559. beta * det < 0) {
  15560. // No intersection found.
  15561. return null;
  15562. }
  15563. if (det > 0){
  15564. if (alpha > det || beta > det){
  15565. return null;
  15566. }
  15567. } else {
  15568. if (alpha < det || beta < det){
  15569. return null;
  15570. }
  15571. }
  15572. return point(this.start.x + (alpha * pt1Dir.x / det),
  15573. this.start.y + (alpha * pt1Dir.y / det));
  15574. },
  15575. // @return the bearing (cardinal direction) of the line. For example N, W, or SE.
  15576. // @returns {String} One of the following bearings : NE, E, SE, S, SW, W, NW, N.
  15577. bearing: function() {
  15578. var lat1 = toRad(this.start.y);
  15579. var lat2 = toRad(this.end.y);
  15580. var lon1 = this.start.x;
  15581. var lon2 = this.end.x;
  15582. var dLon = toRad(lon2 - lon1);
  15583. var y = sin(dLon) * cos(lat2);
  15584. var x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
  15585. var brng = toDeg(atan2(y, x));
  15586. var bearings = ['NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'];
  15587. var index = brng - 22.5;
  15588. if (index < 0)
  15589. index += 360;
  15590. index = parseInt(index / 45);
  15591. return bearings[index];
  15592. }
  15593. };
  15594. // Rectangle.
  15595. // ----------
  15596. function rect(x, y, w, h) {
  15597. if (!(this instanceof rect))
  15598. return new rect(x, y, w, h);
  15599. if (y === undefined) {
  15600. y = x.y;
  15601. w = x.width;
  15602. h = x.height;
  15603. x = x.x;
  15604. }
  15605. this.x = x;
  15606. this.y = y;
  15607. this.width = w;
  15608. this.height = h;
  15609. }
  15610. rect.prototype = {
  15611. toString: function() {
  15612. return this.origin().toString() + ' ' + this.corner().toString();
  15613. },
  15614. origin: function() {
  15615. return point(this.x, this.y);
  15616. },
  15617. corner: function() {
  15618. return point(this.x + this.width, this.y + this.height);
  15619. },
  15620. topRight: function() {
  15621. return point(this.x + this.width, this.y);
  15622. },
  15623. bottomLeft: function() {
  15624. return point(this.x, this.y + this.height);
  15625. },
  15626. center: function() {
  15627. return point(this.x + this.width/2, this.y + this.height/2);
  15628. },
  15629. // @return {boolean} true if rectangles intersect
  15630. intersect: function(r) {
  15631. var myOrigin = this.origin();
  15632. var myCorner = this.corner();
  15633. var rOrigin = r.origin();
  15634. var rCorner = r.corner();
  15635. if (rCorner.x <= myOrigin.x ||
  15636. rCorner.y <= myOrigin.y ||
  15637. rOrigin.x >= myCorner.x ||
  15638. rOrigin.y >= myCorner.y) return false;
  15639. return true;
  15640. },
  15641. // @return {string} (left|right|top|bottom) side which is nearest to point
  15642. // @see Squeak Smalltalk, Rectangle>>sideNearestTo:
  15643. sideNearestToPoint: function(p) {
  15644. p = point(p);
  15645. var distToLeft = p.x - this.x;
  15646. var distToRight = (this.x + this.width) - p.x;
  15647. var distToTop = p.y - this.y;
  15648. var distToBottom = (this.y + this.height) - p.y;
  15649. var closest = distToLeft;
  15650. var side = 'left';
  15651. if (distToRight < closest) {
  15652. closest = distToRight;
  15653. side = 'right';
  15654. }
  15655. if (distToTop < closest) {
  15656. closest = distToTop;
  15657. side = 'top';
  15658. }
  15659. if (distToBottom < closest) {
  15660. closest = distToBottom;
  15661. side = 'bottom';
  15662. }
  15663. return side;
  15664. },
  15665. // @return {bool} true if point p is insight me
  15666. containsPoint: function(p) {
  15667. p = point(p);
  15668. if (p.x >= this.x && p.x <= this.x + this.width &&
  15669. p.y >= this.y && p.y <= this.y + this.height) {
  15670. return true;
  15671. }
  15672. return false;
  15673. },
  15674. // Algorithm ported from java.awt.Rectangle from OpenJDK.
  15675. // @return {bool} true if rectangle `r` is inside me.
  15676. containsRect: function(r) {
  15677. var nr = rect(r).normalize();
  15678. var W = nr.width;
  15679. var H = nr.height;
  15680. var X = nr.x;
  15681. var Y = nr.y;
  15682. var w = this.width;
  15683. var h = this.height;
  15684. if ((w | h | W | H) < 0) {
  15685. // At least one of the dimensions is negative...
  15686. return false;
  15687. }
  15688. // Note: if any dimension is zero, tests below must return false...
  15689. var x = this.x;
  15690. var y = this.y;
  15691. if (X < x || Y < y) {
  15692. return false;
  15693. }
  15694. w += x;
  15695. W += X;
  15696. if (W <= X) {
  15697. // X+W overflowed or W was zero, return false if...
  15698. // either original w or W was zero or
  15699. // x+w did not overflow or
  15700. // the overflowed x+w is smaller than the overflowed X+W
  15701. if (w >= x || W > w) return false;
  15702. } else {
  15703. // X+W did not overflow and W was not zero, return false if...
  15704. // original w was zero or
  15705. // x+w did not overflow and x+w is smaller than X+W
  15706. if (w >= x && W > w) return false;
  15707. }
  15708. h += y;
  15709. H += Y;
  15710. if (H <= Y) {
  15711. if (h >= y || H > h) return false;
  15712. } else {
  15713. if (h >= y && H > h) return false;
  15714. }
  15715. return true;
  15716. },
  15717. // @return {point} a point on my boundary nearest to p
  15718. // @see Squeak Smalltalk, Rectangle>>pointNearestTo:
  15719. pointNearestToPoint: function(p) {
  15720. p = point(p);
  15721. if (this.containsPoint(p)) {
  15722. var side = this.sideNearestToPoint(p);
  15723. switch (side){
  15724. case "right": return point(this.x + this.width, p.y);
  15725. case "left": return point(this.x, p.y);
  15726. case "bottom": return point(p.x, this.y + this.height);
  15727. case "top": return point(p.x, this.y);
  15728. }
  15729. }
  15730. return p.adhereToRect(this);
  15731. },
  15732. // Find point on my boundary where line starting
  15733. // from my center ending in point p intersects me.
  15734. // @param {number} angle If angle is specified, intersection with rotated rectangle is computed.
  15735. intersectionWithLineFromCenterToPoint: function(p, angle) {
  15736. p = point(p);
  15737. var center = point(this.x + this.width/2, this.y + this.height/2);
  15738. var result;
  15739. if (angle) p.rotate(center, angle);
  15740. // (clockwise, starting from the top side)
  15741. var sides = [
  15742. line(this.origin(), this.topRight()),
  15743. line(this.topRight(), this.corner()),
  15744. line(this.corner(), this.bottomLeft()),
  15745. line(this.bottomLeft(), this.origin())
  15746. ];
  15747. var connector = line(center, p);
  15748. for (var i = sides.length - 1; i >= 0; --i){
  15749. var intersection = sides[i].intersection(connector);
  15750. if (intersection !== null){
  15751. result = intersection;
  15752. break;
  15753. }
  15754. }
  15755. if (result && angle) result.rotate(center, -angle);
  15756. return result;
  15757. },
  15758. // Move and expand me.
  15759. // @param r {rectangle} representing deltas
  15760. moveAndExpand: function(r) {
  15761. this.x += r.x;
  15762. this.y += r.y;
  15763. this.width += r.width;
  15764. this.height += r.height;
  15765. return this;
  15766. },
  15767. round: function(decimals) {
  15768. this.x = decimals ? this.x.toFixed(decimals) : round(this.x);
  15769. this.y = decimals ? this.y.toFixed(decimals) : round(this.y);
  15770. this.width = decimals ? this.width.toFixed(decimals) : round(this.width);
  15771. this.height = decimals ? this.height.toFixed(decimals) : round(this.height);
  15772. return this;
  15773. },
  15774. // Normalize the rectangle; i.e., make it so that it has a non-negative width and height.
  15775. // If width < 0 the function swaps the left and right corners,
  15776. // and it swaps the top and bottom corners if height < 0
  15777. // like in http://qt-project.org/doc/qt-4.8/qrectf.html#normalized
  15778. normalize: function() {
  15779. var newx = this.x;
  15780. var newy = this.y;
  15781. var newwidth = this.width;
  15782. var newheight = this.height;
  15783. if (this.width < 0) {
  15784. newx = this.x + this.width;
  15785. newwidth = -this.width;
  15786. }
  15787. if (this.height < 0) {
  15788. newy = this.y + this.height;
  15789. newheight = -this.height;
  15790. }
  15791. this.x = newx;
  15792. this.y = newy;
  15793. this.width = newwidth;
  15794. this.height = newheight;
  15795. return this;
  15796. }
  15797. };
  15798. // Ellipse.
  15799. // --------
  15800. function ellipse(c, a, b) {
  15801. if (!(this instanceof ellipse))
  15802. return new ellipse(c, a, b);
  15803. c = point(c);
  15804. this.x = c.x;
  15805. this.y = c.y;
  15806. this.a = a;
  15807. this.b = b;
  15808. }
  15809. ellipse.prototype = {
  15810. toString: function() {
  15811. return point(this.x, this.y).toString() + ' ' + this.a + ' ' + this.b;
  15812. },
  15813. bbox: function() {
  15814. return rect(this.x - this.a, this.y - this.b, 2*this.a, 2*this.b);
  15815. },
  15816. // Find point on me where line from my center to
  15817. // point p intersects my boundary.
  15818. // @param {number} angle If angle is specified, intersection with rotated ellipse is computed.
  15819. intersectionWithLineFromCenterToPoint: function(p, angle) {
  15820. p = point(p);
  15821. if (angle) p.rotate(point(this.x, this.y), angle);
  15822. var dx = p.x - this.x;
  15823. var dy = p.y - this.y;
  15824. var result;
  15825. if (dx === 0) {
  15826. result = this.bbox().pointNearestToPoint(p);
  15827. if (angle) return result.rotate(point(this.x, this.y), -angle);
  15828. return result;
  15829. }
  15830. var m = dy / dx;
  15831. var mSquared = m * m;
  15832. var aSquared = this.a * this.a;
  15833. var bSquared = this.b * this.b;
  15834. var x = sqrt(1 / ((1 / aSquared) + (mSquared / bSquared)));
  15835. x = dx < 0 ? -x : x;
  15836. var y = m * x;
  15837. result = point(this.x + x, this.y + y);
  15838. if (angle) return result.rotate(point(this.x, this.y), -angle);
  15839. return result;
  15840. }
  15841. };
  15842. // Bezier curve.
  15843. // -------------
  15844. var bezier = {
  15845. // Cubic Bezier curve path through points.
  15846. // Ported from C# implementation by Oleg V. Polikarpotchkin and Peter Lee (http://www.codeproject.com/KB/graphics/BezierSpline.aspx).
  15847. // @param {array} points Array of points through which the smooth line will go.
  15848. // @return {array} SVG Path commands as an array
  15849. curveThroughPoints: function(points) {
  15850. var controlPoints = this.getCurveControlPoints(points);
  15851. var path = ['M', points[0].x, points[0].y];
  15852. for (var i = 0; i < controlPoints[0].length; i++) {
  15853. path.push('C', controlPoints[0][i].x, controlPoints[0][i].y, controlPoints[1][i].x, controlPoints[1][i].y, points[i+1].x, points[i+1].y);
  15854. }
  15855. return path;
  15856. },
  15857. // Get open-ended Bezier Spline Control Points.
  15858. // @param knots Input Knot Bezier spline points (At least two points!).
  15859. // @param firstControlPoints Output First Control points. Array of knots.length - 1 length.
  15860. // @param secondControlPoints Output Second Control points. Array of knots.length - 1 length.
  15861. getCurveControlPoints: function(knots) {
  15862. var firstControlPoints = [];
  15863. var secondControlPoints = [];
  15864. var n = knots.length - 1;
  15865. var i;
  15866. // Special case: Bezier curve should be a straight line.
  15867. if (n == 1) {
  15868. // 3P1 = 2P0 + P3
  15869. firstControlPoints[0] = point((2 * knots[0].x + knots[1].x) / 3,
  15870. (2 * knots[0].y + knots[1].y) / 3);
  15871. // P2 = 2P1 – P0
  15872. secondControlPoints[0] = point(2 * firstControlPoints[0].x - knots[0].x,
  15873. 2 * firstControlPoints[0].y - knots[0].y);
  15874. return [firstControlPoints, secondControlPoints];
  15875. }
  15876. // Calculate first Bezier control points.
  15877. // Right hand side vector.
  15878. var rhs = [];
  15879. // Set right hand side X values.
  15880. for (i = 1; i < n - 1; i++) {
  15881. rhs[i] = 4 * knots[i].x + 2 * knots[i + 1].x;
  15882. }
  15883. rhs[0] = knots[0].x + 2 * knots[1].x;
  15884. rhs[n - 1] = (8 * knots[n - 1].x + knots[n].x) / 2.0;
  15885. // Get first control points X-values.
  15886. var x = this.getFirstControlPoints(rhs);
  15887. // Set right hand side Y values.
  15888. for (i = 1; i < n - 1; ++i) {
  15889. rhs[i] = 4 * knots[i].y + 2 * knots[i + 1].y;
  15890. }
  15891. rhs[0] = knots[0].y + 2 * knots[1].y;
  15892. rhs[n - 1] = (8 * knots[n - 1].y + knots[n].y) / 2.0;
  15893. // Get first control points Y-values.
  15894. var y = this.getFirstControlPoints(rhs);
  15895. // Fill output arrays.
  15896. for (i = 0; i < n; i++) {
  15897. // First control point.
  15898. firstControlPoints.push(point(x[i], y[i]));
  15899. // Second control point.
  15900. if (i < n - 1) {
  15901. secondControlPoints.push(point(2 * knots [i + 1].x - x[i + 1],
  15902. 2 * knots[i + 1].y - y[i + 1]));
  15903. } else {
  15904. secondControlPoints.push(point((knots[n].x + x[n - 1]) / 2,
  15905. (knots[n].y + y[n - 1]) / 2));
  15906. }
  15907. }
  15908. return [firstControlPoints, secondControlPoints];
  15909. },
  15910. // Solves a tridiagonal system for one of coordinates (x or y) of first Bezier control points.
  15911. // @param rhs Right hand side vector.
  15912. // @return Solution vector.
  15913. getFirstControlPoints: function(rhs) {
  15914. var n = rhs.length;
  15915. // `x` is a solution vector.
  15916. var x = [];
  15917. var tmp = [];
  15918. var b = 2.0;
  15919. x[0] = rhs[0] / b;
  15920. // Decomposition and forward substitution.
  15921. for (var i = 1; i < n; i++) {
  15922. tmp[i] = 1 / b;
  15923. b = (i < n - 1 ? 4.0 : 3.5) - tmp[i];
  15924. x[i] = (rhs[i] - x[i - 1]) / b;
  15925. }
  15926. for (i = 1; i < n; i++) {
  15927. // Backsubstitution.
  15928. x[n - i - 1] -= tmp[n - i] * x[n - i];
  15929. }
  15930. return x;
  15931. }
  15932. };
  15933. // Scale.
  15934. var scale = {
  15935. // Return the `value` from the `domain` interval scaled to the `range` interval.
  15936. linear: function(domain, range, value) {
  15937. var domainSpan = domain[1] - domain[0];
  15938. var rangeSpan = range[1] - range[0];
  15939. return (((value - domain[0]) / domainSpan) * rangeSpan + range[0]) || 0;
  15940. }
  15941. };
  15942. return {
  15943. toDeg: toDeg,
  15944. toRad: toRad,
  15945. snapToGrid: snapToGrid,
  15946. normalizeAngle: normalizeAngle,
  15947. point: point,
  15948. line: line,
  15949. rect: rect,
  15950. ellipse: ellipse,
  15951. bezier: bezier,
  15952. scale: scale
  15953. }
  15954. }));
  15955. // JointJS library.
  15956. // (c) 2011-2013 client IO
  15957. if (typeof exports === 'object') {
  15958. var _ = require('lodash');
  15959. }
  15960. // Global namespace.
  15961. var joint = {
  15962. // `joint.dia` namespace.
  15963. dia: {},
  15964. // `joint.ui` namespace.
  15965. ui: {},
  15966. // `joint.layout` namespace.
  15967. layout: {},
  15968. // `joint.shapes` namespace.
  15969. shapes: {},
  15970. // `joint.format` namespace.
  15971. format: {},
  15972. // `joint.connectors` namespace.
  15973. connectors: {},
  15974. // `joint.routers` namespace.
  15975. routers: {},
  15976. util: {
  15977. // Return a simple hash code from a string. See http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/.
  15978. hashCode: function(str) {
  15979. var hash = 0;
  15980. if (str.length == 0) return hash;
  15981. for (var i = 0; i < str.length; i++) {
  15982. var c = str.charCodeAt(i);
  15983. hash = ((hash << 5) - hash) + c;
  15984. hash = hash & hash; // Convert to 32bit integer
  15985. }
  15986. return hash;
  15987. },
  15988. getByPath: function(obj, path, delim) {
  15989. delim = delim || '.';
  15990. var keys = path.split(delim);
  15991. var key;
  15992. while (keys.length) {
  15993. key = keys.shift();
  15994. if (key in obj) {
  15995. obj = obj[key];
  15996. } else {
  15997. return undefined;
  15998. }
  15999. }
  16000. return obj;
  16001. },
  16002. setByPath: function(obj, path, value, delim) {
  16003. delim = delim || '.';
  16004. var keys = path.split(delim);
  16005. var diver = obj;
  16006. var i = 0;
  16007. if (path.indexOf(delim) > -1) {
  16008. for (var len = keys.length; i < len - 1; i++) {
  16009. // diver creates an empty object if there is no nested object under such a key.
  16010. // This means that one can populate an empty nested object with setByPath().
  16011. diver = diver[keys[i]] || (diver[keys[i]] = {});
  16012. }
  16013. diver[keys[len - 1]] = value;
  16014. } else {
  16015. obj[path] = value;
  16016. }
  16017. return obj;
  16018. },
  16019. unsetByPath: function(obj, path, delim) {
  16020. delim = delim || '.';
  16021. // index of the last delimiter
  16022. var i = path.lastIndexOf(delim);
  16023. if (i > -1) {
  16024. // unsetting a nested attribute
  16025. var parent = joint.util.getByPath(obj, path.substr(0, i), delim);
  16026. if (parent) {
  16027. delete parent[path.slice(i + 1)];
  16028. }
  16029. } else {
  16030. // unsetting a primitive attribute
  16031. delete obj[path];
  16032. }
  16033. return obj;
  16034. },
  16035. flattenObject: function(obj, delim, stop) {
  16036. delim = delim || '.';
  16037. var ret = {};
  16038. for (var key in obj) {
  16039. if (!obj.hasOwnProperty(key)) continue;
  16040. var shouldGoDeeper = typeof obj[key] === 'object';
  16041. if (shouldGoDeeper && stop && stop(obj[key])) {
  16042. shouldGoDeeper = false;
  16043. }
  16044. if (shouldGoDeeper) {
  16045. var flatObject = this.flattenObject(obj[key], delim, stop);
  16046. for (var flatKey in flatObject) {
  16047. if (!flatObject.hasOwnProperty(flatKey)) continue;
  16048. ret[key + delim + flatKey] = flatObject[flatKey];
  16049. }
  16050. } else {
  16051. ret[key] = obj[key];
  16052. }
  16053. }
  16054. return ret;
  16055. },
  16056. uuid: function() {
  16057. // credit: http://stackoverflow.com/posts/2117523/revisions
  16058. return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  16059. var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  16060. return v.toString(16);
  16061. });
  16062. },
  16063. // Generate global unique id for obj and store it as a property of the object.
  16064. guid: function(obj) {
  16065. this.guid.id = this.guid.id || 1;
  16066. obj.id = (obj.id === undefined ? 'j_' + this.guid.id++ : obj.id);
  16067. return obj.id;
  16068. },
  16069. // Copy all the properties to the first argument from the following arguments.
  16070. // All the properties will be overwritten by the properties from the following
  16071. // arguments. Inherited properties are ignored.
  16072. mixin: function() {
  16073. var target = arguments[0];
  16074. for (var i = 1, l = arguments.length; i < l; i++) {
  16075. var extension = arguments[i];
  16076. // Only functions and objects can be mixined.
  16077. if ((Object(extension) !== extension) &&
  16078. !_.isFunction(extension) &&
  16079. (extension === null || extension === undefined)) {
  16080. continue;
  16081. }
  16082. _.each(extension, function(copy, key) {
  16083. if (this.mixin.deep && (Object(copy) === copy)) {
  16084. if (!target[key]) {
  16085. target[key] = _.isArray(copy) ? [] : {};
  16086. }
  16087. this.mixin(target[key], copy);
  16088. return;
  16089. }
  16090. if (target[key] !== copy) {
  16091. if (!this.mixin.supplement || !target.hasOwnProperty(key)) {
  16092. target[key] = copy;
  16093. }
  16094. }
  16095. }, this);
  16096. }
  16097. return target;
  16098. },
  16099. // Copy all properties to the first argument from the following
  16100. // arguments only in case if they don't exists in the first argument.
  16101. // All the function propererties in the first argument will get
  16102. // additional property base pointing to the extenders same named
  16103. // property function's call method.
  16104. supplement: function() {
  16105. this.mixin.supplement = true;
  16106. var ret = this.mixin.apply(this, arguments);
  16107. this.mixin.supplement = false;
  16108. return ret;
  16109. },
  16110. // Same as `mixin()` but deep version.
  16111. deepMixin: function() {
  16112. this.mixin.deep = true;
  16113. var ret = this.mixin.apply(this, arguments);
  16114. this.mixin.deep = false;
  16115. return ret;
  16116. },
  16117. // Same as `supplement()` but deep version.
  16118. deepSupplement: function() {
  16119. this.mixin.deep = this.mixin.supplement = true;
  16120. var ret = this.mixin.apply(this, arguments);
  16121. this.mixin.deep = this.mixin.supplement = false;
  16122. return ret;
  16123. },
  16124. normalizeEvent: function(evt) {
  16125. return (evt.originalEvent && evt.originalEvent.changedTouches && evt.originalEvent.changedTouches.length) ? evt.originalEvent.changedTouches[0] : evt;
  16126. },
  16127. nextFrame:(function() {
  16128. var raf;
  16129. var client = typeof window != 'undefined';
  16130. if (client) {
  16131. raf = window.requestAnimationFrame ||
  16132. window.webkitRequestAnimationFrame ||
  16133. window.mozRequestAnimationFrame ||
  16134. window.oRequestAnimationFrame ||
  16135. window.msRequestAnimationFrame;
  16136. }
  16137. if (!raf) {
  16138. var lastTime = 0;
  16139. raf = function(callback) {
  16140. var currTime = new Date().getTime();
  16141. var timeToCall = Math.max(0, 16 - (currTime - lastTime));
  16142. var id = setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
  16143. lastTime = currTime + timeToCall;
  16144. return id;
  16145. };
  16146. }
  16147. return client ? _.bind(raf, window) : raf;
  16148. })(),
  16149. cancelFrame: (function() {
  16150. var caf;
  16151. var client = typeof window != 'undefined';
  16152. if (client) {
  16153. caf = window.cancelAnimationFrame ||
  16154. window.webkitCancelAnimationFrame ||
  16155. window.webkitCancelRequestAnimationFrame ||
  16156. window.msCancelAnimationFrame ||
  16157. window.msCancelRequestAnimationFrame ||
  16158. window.oCancelAnimationFrame ||
  16159. window.oCancelRequestAnimationFrame ||
  16160. window.mozCancelAnimationFrame ||
  16161. window.mozCancelRequestAnimationFrame;
  16162. }
  16163. caf = caf || clearTimeout;
  16164. return client ? _.bind(caf, window) : caf;
  16165. })(),
  16166. breakText: function(text, size, styles, opt) {
  16167. opt = opt || {};
  16168. var width = size.width;
  16169. var height = size.height;
  16170. var svgDocument = opt.svgDocument || V('svg').node;
  16171. var textElement = V('<text><tspan></tspan></text>').attr(styles || {}).node;
  16172. var textSpan = textElement.firstChild;
  16173. var textNode = document.createTextNode('');
  16174. textSpan.appendChild(textNode);
  16175. svgDocument.appendChild(textElement);
  16176. if (!opt.svgDocument) {
  16177. document.body.appendChild(svgDocument);
  16178. }
  16179. var words = text.split(' ');
  16180. var full = [];
  16181. var lines = [];
  16182. var p;
  16183. for (var i = 0, l = 0, len = words.length; i < len; i++) {
  16184. var word = words[i];
  16185. textNode.data = lines[l] ? lines[l] + ' ' + word : word;
  16186. if (textSpan.getComputedTextLength() <= width) {
  16187. // the current line fits
  16188. lines[l] = textNode.data;
  16189. if (p) {
  16190. // We were partitioning. Put rest of the word onto next line
  16191. full[l++] = true;
  16192. // cancel partitioning
  16193. p = 0;
  16194. }
  16195. } else {
  16196. if (!lines[l] || p) {
  16197. var partition = !!p;
  16198. p = word.length - 1;
  16199. if (partition || !p) {
  16200. // word has only one character.
  16201. if (!p) {
  16202. if (!lines[l]) {
  16203. // we won't fit this text within our rect
  16204. lines = [];
  16205. break;
  16206. }
  16207. // partitioning didn't help on the non-empty line
  16208. // try again, but this time start with a new line
  16209. // cancel partitions created
  16210. words.splice(i,2, word + words[i+1]);
  16211. // adjust word length
  16212. len--;
  16213. full[l++] = true;
  16214. i--;
  16215. continue;
  16216. }
  16217. // move last letter to the beginning of the next word
  16218. words[i] = word.substring(0,p);
  16219. words[i+1] = word.substring(p) + words[i+1];
  16220. } else {
  16221. // We initiate partitioning
  16222. // split the long word into two words
  16223. words.splice(i, 1, word.substring(0,p), word.substring(p));
  16224. // adjust words length
  16225. len++;
  16226. if (l && !full[l-1]) {
  16227. // if the previous line is not full, try to fit max part of
  16228. // the current word there
  16229. l--;
  16230. }
  16231. }
  16232. i--;
  16233. continue;
  16234. }
  16235. l++;
  16236. i--;
  16237. }
  16238. // if size.height is defined we have to check whether the height of the entire
  16239. // text exceeds the rect height
  16240. if (typeof height !== 'undefined') {
  16241. // get line height as text height / 0.8 (as text height is approx. 0.8em
  16242. // and line height is 1em. See vectorizer.text())
  16243. var lh = lh || textElement.getBBox().height * 1.25;
  16244. if (lh * lines.length > height) {
  16245. // remove overflowing lines
  16246. lines.splice(Math.floor(height / lh));
  16247. break;
  16248. }
  16249. }
  16250. }
  16251. if (opt.svgDocument) {
  16252. // svg document was provided, remove the text element only
  16253. svgDocument.removeChild(textElement);
  16254. } else {
  16255. // clean svg document
  16256. document.body.removeChild(svgDocument);
  16257. }
  16258. return lines.join('\n');
  16259. },
  16260. timing: {
  16261. linear: function(t) {
  16262. return t;
  16263. },
  16264. quad: function(t) {
  16265. return t * t;
  16266. },
  16267. cubic: function(t) {
  16268. return t * t * t;
  16269. },
  16270. inout: function(t) {
  16271. if (t <= 0) return 0;
  16272. if (t >= 1) return 1;
  16273. var t2 = t * t, t3 = t2 * t;
  16274. return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75);
  16275. },
  16276. exponential: function(t) {
  16277. return Math.pow(2, 10 * (t - 1));
  16278. },
  16279. bounce: function(t) {
  16280. for(var a = 0, b = 1; 1; a += b, b /= 2) {
  16281. if (t >= (7 - 4 * a) / 11) {
  16282. var q = (11 - 6 * a - 11 * t) / 4;
  16283. return -q * q + b * b;
  16284. }
  16285. }
  16286. },
  16287. reverse: function(f) {
  16288. return function(t) {
  16289. return 1 - f(1 - t)
  16290. }
  16291. },
  16292. reflect: function(f) {
  16293. return function(t) {
  16294. return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
  16295. };
  16296. },
  16297. clamp: function(f,n,x) {
  16298. n = n || 0;
  16299. x = x || 1;
  16300. return function(t) {
  16301. var r = f(t);
  16302. return r < n ? n : r > x ? x : r;
  16303. }
  16304. },
  16305. back: function(s) {
  16306. if (!s) s = 1.70158;
  16307. return function(t) {
  16308. return t * t * ((s + 1) * t - s);
  16309. };
  16310. },
  16311. elastic: function(x) {
  16312. if (!x) x = 1.5;
  16313. return function(t) {
  16314. return Math.pow(2, 10 * (t - 1)) * Math.cos(20*Math.PI*x/3*t);
  16315. }
  16316. }
  16317. },
  16318. interpolate: {
  16319. number: function(a, b) {
  16320. var d = b - a;
  16321. return function(t) { return a + d * t; };
  16322. },
  16323. object: function(a, b) {
  16324. var s = _.keys(a);
  16325. return function(t) {
  16326. var i, p, r = {};
  16327. for (i = s.length - 1; i != -1; i--) {
  16328. p = s[i];
  16329. r[p] = a[p] + (b[p] - a[p]) * t;
  16330. }
  16331. return r;
  16332. }
  16333. },
  16334. hexColor: function(a, b) {
  16335. var ca = parseInt(a.slice(1), 16), cb = parseInt(b.slice(1), 16);
  16336. var ra = ca & 0x0000ff, rd = (cb & 0x0000ff) - ra;
  16337. var ga = ca & 0x00ff00, gd = (cb & 0x00ff00) - ga;
  16338. var ba = ca & 0xff0000, bd = (cb & 0xff0000) - ba;
  16339. return function(t) {
  16340. var r = (ra + rd * t) & 0x000000ff;
  16341. var g = (ga + gd * t) & 0x0000ff00;
  16342. var b = (ba + bd * t) & 0x00ff0000;
  16343. return '#' + (1 << 24 | r | g | b ).toString(16).slice(1);
  16344. };
  16345. },
  16346. unit: function(a, b) {
  16347. var r = /(-?[0-9]*.[0-9]*)(px|em|cm|mm|in|pt|pc|%)/;
  16348. var ma = r.exec(a), mb = r.exec(b);
  16349. var p = mb[1].indexOf('.'), f = p > 0 ? mb[1].length - p - 1 : 0;
  16350. var a = +ma[1], d = +mb[1] - a, u = ma[2];
  16351. return function(t) {
  16352. return (a + d * t).toFixed(f) + u;
  16353. }
  16354. }
  16355. },
  16356. // SVG filters.
  16357. filter: {
  16358. // `x` ... horizontal blur
  16359. // `y` ... vertical blur (optional)
  16360. blur: function(args) {
  16361. var x = _.isFinite(args.x) ? args.x : 2;
  16362. return _.template('<filter><feGaussianBlur stdDeviation="${stdDeviation}"/></filter>', {
  16363. stdDeviation: _.isFinite(args.y) ? [x, args.y] : x
  16364. });
  16365. },
  16366. // `dx` ... horizontal shift
  16367. // `dy` ... vertical shift
  16368. // `blur` ... blur
  16369. // `color` ... color
  16370. // `opacity` ... opacity
  16371. dropShadow: function(args) {
  16372. var tpl = 'SVGFEDropShadowElement' in window
  16373. ? '<filter><feDropShadow stdDeviation="${blur}" dx="${dx}" dy="${dy}" flood-color="${color}" flood-opacity="${opacity}"/></filter>'
  16374. : '<filter><feGaussianBlur in="SourceAlpha" stdDeviation="${blur}"/><feOffset dx="${dx}" dy="${dy}" result="offsetblur"/><feFlood flood-color="${color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="${opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge></filter>';
  16375. return _.template(tpl, {
  16376. dx: args.dx || 0,
  16377. dy: args.dy || 0,
  16378. opacity: _.isFinite(args.opacity) ? args.opacity : 1,
  16379. color: args.color || 'black',
  16380. blur: _.isFinite(args.blur) ? args.blur : 4
  16381. });
  16382. },
  16383. // `amount` ... the proportion of the conversion. A value of 1 is completely grayscale. A value of 0 leaves the input unchanged.
  16384. grayscale: function(args) {
  16385. var amount = _.isFinite(args.amount) ? args.amount : 1;
  16386. return _.template('<filter><feColorMatrix type="matrix" values="${a} ${b} ${c} 0 0 ${d} ${e} ${f} 0 0 ${g} ${b} ${h} 0 0 0 0 0 1 0"/></filter>', {
  16387. a: 0.2126 + 0.7874 * (1 - amount),
  16388. b: 0.7152 - 0.7152 * (1 - amount),
  16389. c: 0.0722 - 0.0722 * (1 - amount),
  16390. d: 0.2126 - 0.2126 * (1 - amount),
  16391. e: 0.7152 + 0.2848 * (1 - amount),
  16392. f: 0.0722 - 0.0722 * (1 - amount),
  16393. g: 0.2126 - 0.2126 * (1 - amount),
  16394. h: 0.0722 + 0.9278 * (1 - amount)
  16395. });
  16396. },
  16397. // `amount` ... the proportion of the conversion. A value of 1 is completely sepia. A value of 0 leaves the input unchanged.
  16398. sepia: function(args) {
  16399. var amount = _.isFinite(args.amount) ? args.amount : 1;
  16400. return _.template('<filter><feColorMatrix type="matrix" values="${a} ${b} ${c} 0 0 ${d} ${e} ${f} 0 0 ${g} ${h} ${i} 0 0 0 0 0 1 0"/></filter>', {
  16401. a: 0.393 + 0.607 * (1 - amount),
  16402. b: 0.769 - 0.769 * (1 - amount),
  16403. c: 0.189 - 0.189 * (1 - amount),
  16404. d: 0.349 - 0.349 * (1 - amount),
  16405. e: 0.686 + 0.314 * (1 - amount),
  16406. f: 0.168 - 0.168 * (1 - amount),
  16407. g: 0.272 - 0.272 * (1 - amount),
  16408. h: 0.534 - 0.534 * (1 - amount),
  16409. i: 0.131 + 0.869 * (1 - amount)
  16410. });
  16411. },
  16412. // `amount` ... the proportion of the conversion. A value of 0 is completely un-saturated. A value of 1 leaves the input unchanged.
  16413. saturate: function(args) {
  16414. var amount = _.isFinite(args.amount) ? args.amount : 1;
  16415. return _.template('<filter><feColorMatrix type="saturate" values="${amount}"/></filter>', {
  16416. amount: 1 - amount
  16417. });
  16418. },
  16419. // `angle` ... the number of degrees around the color circle the input samples will be adjusted.
  16420. hueRotate: function(args) {
  16421. return _.template('<filter><feColorMatrix type="hueRotate" values="${angle}"/></filter>', {
  16422. angle: args.angle || 0
  16423. });
  16424. },
  16425. // `amount` ... the proportion of the conversion. A value of 1 is completely inverted. A value of 0 leaves the input unchanged.
  16426. invert: function(args) {
  16427. var amount = _.isFinite(args.amount) ? args.amount : 1;
  16428. return _.template('<filter><feComponentTransfer><feFuncR type="table" tableValues="${amount} ${amount2}"/><feFuncG type="table" tableValues="${amount} ${amount2}"/><feFuncB type="table" tableValues="${amount} ${amount2}"/></feComponentTransfer></filter>', {
  16429. amount: amount,
  16430. amount2: 1 - amount
  16431. });
  16432. },
  16433. // `amount` ... proportion of the conversion. A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
  16434. brightness: function(args) {
  16435. return _.template('<filter><feComponentTransfer><feFuncR type="linear" slope="${amount}"/><feFuncG type="linear" slope="${amount}"/><feFuncB type="linear" slope="${amount}"/></feComponentTransfer></filter>', {
  16436. amount: _.isFinite(args.amount) ? args.amount : 1
  16437. });
  16438. },
  16439. // `amount` ... proportion of the conversion. A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
  16440. contrast: function(args) {
  16441. var amount = _.isFinite(args.amount) ? args.amount : 1;
  16442. return _.template('<filter><feComponentTransfer><feFuncR type="linear" slope="${amount}" intercept="${amount2}"/><feFuncG type="linear" slope="${amount}" intercept="${amount2}"/><feFuncB type="linear" slope="${amount}" intercept="${amount2}"/></feComponentTransfer></filter>', {
  16443. amount: amount,
  16444. amount2: .5 - amount / 2
  16445. });
  16446. }
  16447. },
  16448. format: {
  16449. // Formatting numbers via the Python Format Specification Mini-language.
  16450. // See http://docs.python.org/release/3.1.3/library/string.html#format-specification-mini-language.
  16451. // Heavilly inspired by the D3.js library implementation.
  16452. number: function(specifier, value, locale) {
  16453. locale = locale || {
  16454. currency: ['$', ''],
  16455. decimal: '.',
  16456. thousands: ',',
  16457. grouping: [3]
  16458. };
  16459. // See Python format specification mini-language: http://docs.python.org/release/3.1.3/library/string.html#format-specification-mini-language.
  16460. // [[fill]align][sign][symbol][0][width][,][.precision][type]
  16461. var re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;
  16462. var match = re.exec(specifier);
  16463. var fill = match[1] || ' ';
  16464. var align = match[2] || '>';
  16465. var sign = match[3] || '';
  16466. var symbol = match[4] || '';
  16467. var zfill = match[5];
  16468. var width = +match[6];
  16469. var comma = match[7];
  16470. var precision = match[8];
  16471. var type = match[9];
  16472. var scale = 1;
  16473. var prefix = '';
  16474. var suffix = '';
  16475. var integer = false;
  16476. if (precision) precision = +precision.substring(1);
  16477. if (zfill || fill === '0' && align === '=') {
  16478. zfill = fill = '0';
  16479. align = '=';
  16480. if (comma) width -= Math.floor((width - 1) / 4);
  16481. }
  16482. switch (type) {
  16483. case 'n': comma = true; type = 'g'; break;
  16484. case '%': scale = 100; suffix = '%'; type = 'f'; break;
  16485. case 'p': scale = 100; suffix = '%'; type = 'r'; break;
  16486. case 'b':
  16487. case 'o':
  16488. case 'x':
  16489. case 'X': if (symbol === '#') prefix = '0' + type.toLowerCase();
  16490. case 'c':
  16491. case 'd': integer = true; precision = 0; break;
  16492. case 's': scale = -1; type = 'r'; break;
  16493. }
  16494. if (symbol === '$') {
  16495. prefix = locale.currency[0];
  16496. suffix = locale.currency[1];
  16497. }
  16498. // If no precision is specified for `'r'`, fallback to general notation.
  16499. if (type == 'r' && !precision) type = 'g';
  16500. // Ensure that the requested precision is in the supported range.
  16501. if (precision != null) {
  16502. if (type == 'g') precision = Math.max(1, Math.min(21, precision));
  16503. else if (type == 'e' || type == 'f') precision = Math.max(0, Math.min(20, precision));
  16504. }
  16505. var zcomma = zfill && comma;
  16506. // Return the empty string for floats formatted as ints.
  16507. if (integer && (value % 1)) return '';
  16508. // Convert negative to positive, and record the sign prefix.
  16509. var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, '-') : sign;
  16510. var fullSuffix = suffix;
  16511. // Apply the scale, computing it from the value's exponent for si format.
  16512. // Preserve the existing suffix, if any, such as the currency symbol.
  16513. if (scale < 0) {
  16514. var unit = this.prefix(value, precision);
  16515. value = unit.scale(value);
  16516. fullSuffix = unit.symbol + suffix;
  16517. } else {
  16518. value *= scale;
  16519. }
  16520. // Convert to the desired precision.
  16521. value = this.convert(type, value, precision);
  16522. // Break the value into the integer part (before) and decimal part (after).
  16523. var i = value.lastIndexOf('.');
  16524. var before = i < 0 ? value : value.substring(0, i);
  16525. var after = i < 0 ? '' : locale.decimal + value.substring(i + 1);
  16526. function formatGroup(value) {
  16527. var i = value.length;
  16528. var t = [];
  16529. var j = 0;
  16530. var g = locale.grouping[0];
  16531. while (i > 0 && g > 0) {
  16532. t.push(value.substring(i -= g, i + g));
  16533. g = locale.grouping[j = (j + 1) % locale.grouping.length];
  16534. }
  16535. return t.reverse().join(locale.thousands);
  16536. }
  16537. // If the fill character is not `'0'`, grouping is applied before padding.
  16538. if (!zfill && comma && locale.grouping) {
  16539. before = formatGroup(before);
  16540. }
  16541. var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length);
  16542. var padding = length < width ? new Array(length = width - length + 1).join(fill) : '';
  16543. // If the fill character is `'0'`, grouping is applied after padding.
  16544. if (zcomma) before = formatGroup(padding + before);
  16545. // Apply prefix.
  16546. negative += prefix;
  16547. // Rejoin integer and decimal parts.
  16548. value = before + after;
  16549. return (align === '<' ? negative + value + padding
  16550. : align === '>' ? padding + negative + value
  16551. : align === '^' ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length)
  16552. : negative + (zcomma ? value : padding + value)) + fullSuffix;
  16553. },
  16554. convert: function(type, value, precision) {
  16555. switch (type) {
  16556. case 'b': return value.toString(2);
  16557. case 'c': return String.fromCharCode(value);
  16558. case 'o': return value.toString(8);
  16559. case 'x': return value.toString(16);
  16560. case 'X': return value.toString(16).toUpperCase();
  16561. case 'g': return value.toPrecision(precision);
  16562. case 'e': return value.toExponential(precision);
  16563. case 'f': return value.toFixed(precision);
  16564. case 'r': return (value = this.round(value, this.precision(value, precision))).toFixed(Math.max(0, Math.min(20, this.precision(value * (1 + 1e-15), precision))));
  16565. default: return value + '';
  16566. }
  16567. },
  16568. round: function(value, precision) {
  16569. return precision
  16570. ? Math.round(value * (precision = Math.pow(10, precision))) / precision
  16571. : Math.round(value);
  16572. },
  16573. precision: function(value, precision) {
  16574. return precision - (value ? Math.ceil(Math.log(value) / Math.LN10) : 1);
  16575. },
  16576. prefix: function(value, precision) {
  16577. var prefixes = _.map(['y','z','a','f','p','n','µ','m','','k','M','G','T','P','E','Z','Y'], function(d, i) {
  16578. var k = Math.pow(10, abs(8 - i) * 3);
  16579. return {
  16580. scale: i > 8 ? function(d) { return d / k; } : function(d) { return d * k; },
  16581. symbol: d
  16582. };
  16583. });
  16584. var i = 0;
  16585. if (value) {
  16586. if (value < 0) value *= -1;
  16587. if (precision) value = d3.round(value, this.precision(value, precision));
  16588. i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
  16589. i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3));
  16590. }
  16591. return prefixes[8 + i / 3];
  16592. }
  16593. }
  16594. }
  16595. };
  16596. if (typeof exports === 'object') {
  16597. module.exports = joint;
  16598. }
  16599. // JointJS, the JavaScript diagramming library.
  16600. // (c) 2011-2013 client IO
  16601. if (typeof exports === 'object') {
  16602. var joint = {
  16603. dia: {
  16604. Link: require('./joint.dia.link').Link,
  16605. Element: require('./joint.dia.element').Element
  16606. },
  16607. shapes: require('../plugins/shapes')
  16608. };
  16609. var Backbone = require('backbone');
  16610. var _ = require('lodash');
  16611. var g = require('./geometry');
  16612. }
  16613. joint.dia.GraphCells = Backbone.Collection.extend({
  16614. initialize: function() {
  16615. // Backbone automatically doesn't trigger re-sort if models attributes are changed later when
  16616. // they're already in the collection. Therefore, we're triggering sort manually here.
  16617. this.on('change:z', this.sort, this);
  16618. },
  16619. model: function(attrs, options) {
  16620. if (attrs.type === 'link') {
  16621. return new joint.dia.Link(attrs, options);
  16622. }
  16623. var module = attrs.type.split('.')[0];
  16624. var entity = attrs.type.split('.')[1];
  16625. if (joint.shapes[module] && joint.shapes[module][entity]) {
  16626. return new joint.shapes[module][entity](attrs, options);
  16627. }
  16628. return new joint.dia.Element(attrs, options);
  16629. },
  16630. // `comparator` makes it easy to sort cells based on their `z` index.
  16631. comparator: function(model) {
  16632. return model.get('z') || 0;
  16633. },
  16634. // Get all inbound and outbound links connected to the cell `model`.
  16635. getConnectedLinks: function(model, opt) {
  16636. opt = opt || {};
  16637. if (_.isUndefined(opt.inbound) && _.isUndefined(opt.outbound)) {
  16638. opt.inbound = opt.outbound = true;
  16639. }
  16640. var links = [];
  16641. this.each(function(cell) {
  16642. var source = cell.get('source');
  16643. var target = cell.get('target');
  16644. if (source && source.id === model.id && opt.outbound) {
  16645. links.push(cell);
  16646. }
  16647. if (target && target.id === model.id && opt.inbound) {
  16648. links.push(cell);
  16649. }
  16650. });
  16651. return links;
  16652. }
  16653. });
  16654. joint.dia.Graph = Backbone.Model.extend({
  16655. initialize: function() {
  16656. this.set('cells', new joint.dia.GraphCells);
  16657. // Make all the events fired in the `cells` collection available.
  16658. // to the outside world.
  16659. this.get('cells').on('all', this.trigger, this);
  16660. this.get('cells').on('remove', this.removeCell, this);
  16661. },
  16662. toJSON: function() {
  16663. // Backbone does not recursively call `toJSON()` on attributes that are themselves models/collections.
  16664. // It just clones the attributes. Therefore, we must call `toJSON()` on the cells collection explicitely.
  16665. var json = Backbone.Model.prototype.toJSON.apply(this, arguments);
  16666. json.cells = this.get('cells').toJSON();
  16667. return json;
  16668. },
  16669. fromJSON: function(json) {
  16670. if (!json.cells) {
  16671. throw new Error('Graph JSON must contain cells array.');
  16672. }
  16673. var attrs = json;
  16674. // Cells are the only attribute that is being set differently, using `cells.add()`.
  16675. var cells = json.cells;
  16676. delete attrs.cells;
  16677. this.set(attrs);
  16678. this.resetCells(cells);
  16679. },
  16680. clear: function() {
  16681. this.trigger('batch:start');
  16682. this.get('cells').remove(this.get('cells').models);
  16683. this.trigger('batch:stop');
  16684. },
  16685. _prepareCell: function(cell) {
  16686. if (cell instanceof Backbone.Model && _.isUndefined(cell.get('z'))) {
  16687. cell.set('z', this.maxZIndex() + 1, { silent: true });
  16688. } else if (_.isUndefined(cell.z)) {
  16689. cell.z = this.maxZIndex() + 1;
  16690. }
  16691. return cell;
  16692. },
  16693. maxZIndex: function() {
  16694. var lastCell = this.get('cells').last();
  16695. return lastCell ? (lastCell.get('z') || 0) : 0;
  16696. },
  16697. addCell: function(cell, options) {
  16698. if (_.isArray(cell)) {
  16699. return this.addCells(cell, options);
  16700. }
  16701. this.get('cells').add(this._prepareCell(cell), options || {});
  16702. return this;
  16703. },
  16704. addCells: function(cells, options) {
  16705. _.each(cells, function(cell) { this.addCell(cell, options); }, this);
  16706. return this;
  16707. },
  16708. // When adding a lot of cells, it is much more efficient to
  16709. // reset the entire cells collection in one go.
  16710. // Useful for bulk operations and optimizations.
  16711. resetCells: function(cells) {
  16712. this.get('cells').reset(_.map(cells, this._prepareCell, this));
  16713. return this;
  16714. },
  16715. removeCell: function(cell, collection, options) {
  16716. // Applications might provide a `disconnectLinks` option set to `true` in order to
  16717. // disconnect links when a cell is removed rather then removing them. The default
  16718. // is to remove all the associated links.
  16719. if (options && options.disconnectLinks) {
  16720. this.disconnectLinks(cell);
  16721. } else {
  16722. this.removeLinks(cell);
  16723. }
  16724. // Silently remove the cell from the cells collection. Silently, because
  16725. // `joint.dia.Cell.prototype.remove` already triggers the `remove` event which is
  16726. // then propagated to the graph model. If we didn't remove the cell silently, two `remove` events
  16727. // would be triggered on the graph model.
  16728. this.get('cells').remove(cell, { silent: true });
  16729. },
  16730. // Get a cell by `id`.
  16731. getCell: function(id) {
  16732. return this.get('cells').get(id);
  16733. },
  16734. getElements: function() {
  16735. return this.get('cells').filter(function(cell) {
  16736. return cell instanceof joint.dia.Element;
  16737. });
  16738. },
  16739. getLinks: function() {
  16740. return this.get('cells').filter(function(cell) {
  16741. return cell instanceof joint.dia.Link;
  16742. });
  16743. },
  16744. // Get all inbound and outbound links connected to the cell `model`.
  16745. getConnectedLinks: function(model, opt) {
  16746. return this.get('cells').getConnectedLinks(model, opt);
  16747. },
  16748. getNeighbors: function(el) {
  16749. var links = this.getConnectedLinks(el);
  16750. var neighbors = [];
  16751. var cells = this.get('cells');
  16752. _.each(links, function(link) {
  16753. var source = link.get('source');
  16754. var target = link.get('target');
  16755. // Discard if it is a point.
  16756. if (!source.x) {
  16757. var sourceElement = cells.get(source.id);
  16758. if (sourceElement !== el) {
  16759. neighbors.push(sourceElement);
  16760. }
  16761. }
  16762. if (!target.x) {
  16763. var targetElement = cells.get(target.id);
  16764. if (targetElement !== el) {
  16765. neighbors.push(targetElement);
  16766. }
  16767. }
  16768. });
  16769. return neighbors;
  16770. },
  16771. // Disconnect links connected to the cell `model`.
  16772. disconnectLinks: function(model) {
  16773. _.each(this.getConnectedLinks(model), function(link) {
  16774. link.set(link.get('source').id === model.id ? 'source' : 'target', g.point(0, 0));
  16775. });
  16776. },
  16777. // Remove links connected to the cell `model` completely.
  16778. removeLinks: function(model) {
  16779. _.invoke(this.getConnectedLinks(model), 'remove');
  16780. },
  16781. // Find all views at given point
  16782. findModelsFromPoint: function(p) {
  16783. return _.filter(this.getElements(), function(el) {
  16784. return el.getBBox().containsPoint(p);
  16785. });
  16786. },
  16787. // Find all views in given area
  16788. findModelsInArea: function(r) {
  16789. return _.filter(this.getElements(), function(el) {
  16790. return el.getBBox().intersect(r);
  16791. });
  16792. }
  16793. });
  16794. if (typeof exports === 'object') {
  16795. module.exports.Graph = joint.dia.Graph;
  16796. }
  16797. // JointJS.
  16798. // (c) 2011-2013 client IO
  16799. if (typeof exports === 'object') {
  16800. var joint = {
  16801. util: require('./core').util,
  16802. dia: {
  16803. Link: require('./joint.dia.link').Link
  16804. }
  16805. };
  16806. var Backbone = require('backbone');
  16807. var _ = require('lodash');
  16808. }
  16809. // joint.dia.Cell base model.
  16810. // --------------------------
  16811. joint.dia.Cell = Backbone.Model.extend({
  16812. // This is the same as Backbone.Model with the only difference that is uses _.merge
  16813. // instead of just _.extend. The reason is that we want to mixin attributes set in upper classes.
  16814. constructor: function(attributes, options) {
  16815. var defaults;
  16816. var attrs = attributes || {};
  16817. this.cid = _.uniqueId('c');
  16818. this.attributes = {};
  16819. if (options && options.collection) this.collection = options.collection;
  16820. if (options && options.parse) attrs = this.parse(attrs, options) || {};
  16821. if (defaults = _.result(this, 'defaults')) {
  16822. //<custom code>
  16823. // Replaced the call to _.defaults with _.merge.
  16824. attrs = _.merge({}, defaults, attrs);
  16825. //</custom code>
  16826. }
  16827. this.set(attrs, options);
  16828. this.changed = {};
  16829. this.initialize.apply(this, arguments);
  16830. },
  16831. toJSON: function() {
  16832. var defaultAttrs = this.constructor.prototype.defaults.attrs || {};
  16833. var attrs = this.attributes.attrs;
  16834. var finalAttrs = {};
  16835. // Loop through all the attributes and
  16836. // omit the default attributes as they are implicitly reconstructable by the cell 'type'.
  16837. _.each(attrs, function(attr, selector) {
  16838. var defaultAttr = defaultAttrs[selector];
  16839. _.each(attr, function(value, name) {
  16840. // attr is mainly flat though it might have one more level (consider the `style` attribute).
  16841. // Check if the `value` is object and if yes, go one level deep.
  16842. if (_.isObject(value) && !_.isArray(value)) {
  16843. _.each(value, function(value2, name2) {
  16844. if (!defaultAttr || !defaultAttr[name] || !_.isEqual(defaultAttr[name][name2], value2)) {
  16845. finalAttrs[selector] = finalAttrs[selector] || {};
  16846. (finalAttrs[selector][name] || (finalAttrs[selector][name] = {}))[name2] = value2;
  16847. }
  16848. });
  16849. } else if (!defaultAttr || !_.isEqual(defaultAttr[name], value)) {
  16850. // `value` is not an object, default attribute for such a selector does not exist
  16851. // or it is different than the attribute value set on the model.
  16852. finalAttrs[selector] = finalAttrs[selector] || {};
  16853. finalAttrs[selector][name] = value;
  16854. }
  16855. });
  16856. });
  16857. var attributes = _.cloneDeep(_.omit(this.attributes, 'attrs'));
  16858. //var attributes = JSON.parse(JSON.stringify(_.omit(this.attributes, 'attrs')));
  16859. attributes.attrs = finalAttrs;
  16860. return attributes;
  16861. },
  16862. initialize: function(options) {
  16863. if (!options || !options.id) {
  16864. this.set('id', joint.util.uuid(), { silent: true });
  16865. }
  16866. this._transitionIds = {};
  16867. // Collect ports defined in `attrs` and keep collecting whenever `attrs` object changes.
  16868. this.processPorts();
  16869. this.on('change:attrs', this.processPorts, this);
  16870. },
  16871. processPorts: function() {
  16872. // Whenever `attrs` changes, we extract ports from the `attrs` object and store it
  16873. // in a more accessible way. Also, if any port got removed and there were links that had `target`/`source`
  16874. // set to that port, we remove those links as well (to follow the same behaviour as
  16875. // with a removed element).
  16876. var previousPorts = this.ports;
  16877. // Collect ports from the `attrs` object.
  16878. var ports = {};
  16879. _.each(this.get('attrs'), function(attrs, selector) {
  16880. if (attrs && attrs.port) {
  16881. // `port` can either be directly an `id` or an object containing an `id` (and potentially other data).
  16882. if (!_.isUndefined(attrs.port.id)) {
  16883. ports[attrs.port.id] = attrs.port;
  16884. } else {
  16885. ports[attrs.port] = { id: attrs.port };
  16886. }
  16887. }
  16888. });
  16889. // Collect ports that have been removed (compared to the previous ports) - if any.
  16890. // Use hash table for quick lookup.
  16891. var removedPorts = {};
  16892. _.each(previousPorts, function(port, id) {
  16893. if (!ports[id]) removedPorts[id] = true;
  16894. });
  16895. // Remove all the incoming/outgoing links that have source/target port set to any of the removed ports.
  16896. if (this.collection && !_.isEmpty(removedPorts)) {
  16897. var inboundLinks = this.collection.getConnectedLinks(this, { inbound: true });
  16898. _.each(inboundLinks, function(link) {
  16899. if (removedPorts[link.get('target').port]) link.remove();
  16900. });
  16901. var outboundLinks = this.collection.getConnectedLinks(this, { outbound: true });
  16902. _.each(outboundLinks, function(link) {
  16903. if (removedPorts[link.get('source').port]) link.remove();
  16904. });
  16905. }
  16906. // Update the `ports` object.
  16907. this.ports = ports;
  16908. },
  16909. remove: function(options) {
  16910. var collection = this.collection;
  16911. if (collection) {
  16912. collection.trigger('batch:start');
  16913. }
  16914. // First, unembed this cell from its parent cell if there is one.
  16915. var parentCellId = this.get('parent');
  16916. if (parentCellId) {
  16917. var parentCell = this.collection && this.collection.get(parentCellId);
  16918. parentCell.unembed(this);
  16919. }
  16920. _.invoke(this.getEmbeddedCells(), 'remove', options);
  16921. this.trigger('remove', this, this.collection, options);
  16922. if (collection) {
  16923. collection.trigger('batch:stop');
  16924. }
  16925. },
  16926. toFront: function() {
  16927. if (this.collection) {
  16928. this.set('z', (this.collection.last().get('z') || 0) + 1);
  16929. }
  16930. },
  16931. toBack: function() {
  16932. if (this.collection) {
  16933. this.set('z', (this.collection.first().get('z') || 0) - 1);
  16934. }
  16935. },
  16936. embed: function(cell) {
  16937. if (this.get('parent') == cell.id) {
  16938. throw new Error('Recursive embedding not allowed.');
  16939. } else {
  16940. this.trigger('batch:start');
  16941. cell.set('parent', this.id);
  16942. this.set('embeds', _.uniq((this.get('embeds') || []).concat([cell.id])));
  16943. this.trigger('batch:stop');
  16944. }
  16945. },
  16946. unembed: function(cell) {
  16947. this.trigger('batch:start');
  16948. var cellId = cell.id;
  16949. cell.unset('parent');
  16950. this.set('embeds', _.without(this.get('embeds'), cellId));
  16951. this.trigger('batch:stop');
  16952. },
  16953. getEmbeddedCells: function() {
  16954. // Cell models can only be retrieved when this element is part of a collection.
  16955. // There is no way this element knows about other cells otherwise.
  16956. // This also means that calling e.g. `translate()` on an element with embeds before
  16957. // adding it to a graph does not translate its embeds.
  16958. if (this.collection) {
  16959. return _.map(this.get('embeds') || [], function(cellId) {
  16960. return this.collection.get(cellId);
  16961. }, this);
  16962. }
  16963. return [];
  16964. },
  16965. clone: function(opt) {
  16966. opt = opt || {};
  16967. var clone = Backbone.Model.prototype.clone.apply(this, arguments);
  16968. // We don't want the clone to have the same ID as the original.
  16969. clone.set('id', joint.util.uuid(), { silent: true });
  16970. clone.set('embeds', '');
  16971. if (!opt.deep) return clone;
  16972. // The rest of the `clone()` method deals with embeds. If `deep` option is set to `true`,
  16973. // the return value is an array of all the embedded clones created.
  16974. var embeds = this.getEmbeddedCells();
  16975. var clones = [clone];
  16976. // This mapping stores cloned links under the `id`s of they originals.
  16977. // This prevents cloning a link more then once. Consider a link 'self loop' for example.
  16978. var linkCloneMapping = {};
  16979. _.each(embeds, function(embed) {
  16980. var embedClones = embed.clone({ deep: true });
  16981. // Embed the first clone returned from `clone({ deep: true })` above. The first
  16982. // cell is always the clone of the cell that called the `clone()` method, i.e. clone of `embed` in this case.
  16983. clone.embed(embedClones[0]);
  16984. _.each(embedClones, function(embedClone) {
  16985. clones.push(embedClone);
  16986. // Skip links. Inbound/outbound links are not relevant for them.
  16987. if (embedClone instanceof joint.dia.Link) {
  16988. return;
  16989. }
  16990. // Collect all inbound links, clone them (if not done already) and set their target to the `embedClone.id`.
  16991. var inboundLinks = this.collection.getConnectedLinks(embed, { inbound: true });
  16992. _.each(inboundLinks, function(link) {
  16993. var linkClone = linkCloneMapping[link.id] || link.clone();
  16994. // Make sure we don't clone a link more then once.
  16995. linkCloneMapping[link.id] = linkClone;
  16996. var target = _.clone(linkClone.get('target'));
  16997. target.id = embedClone.id;
  16998. linkClone.set('target', target);
  16999. });
  17000. // Collect all inbound links, clone them (if not done already) and set their source to the `embedClone.id`.
  17001. var outboundLinks = this.collection.getConnectedLinks(embed, { outbound: true });
  17002. _.each(outboundLinks, function(link) {
  17003. var linkClone = linkCloneMapping[link.id] || link.clone();
  17004. // Make sure we don't clone a link more then once.
  17005. linkCloneMapping[link.id] = linkClone;
  17006. var source = _.clone(linkClone.get('source'));
  17007. source.id = embedClone.id;
  17008. linkClone.set('source', source);
  17009. });
  17010. }, this);
  17011. }, this);
  17012. // Add link clones to the array of all the new clones.
  17013. clones = clones.concat(_.values(linkCloneMapping));
  17014. return clones;
  17015. },
  17016. // A convenient way to set nested attributes.
  17017. attr: function(attrs, value, opt) {
  17018. var currentAttrs = this.get('attrs');
  17019. var delim = '/';
  17020. if (_.isString(attrs)) {
  17021. // Get/set an attribute by a special path syntax that delimits
  17022. // nested objects by the colon character.
  17023. if (typeof value != 'undefined') {
  17024. var attr = {};
  17025. joint.util.setByPath(attr, attrs, value, delim);
  17026. return this.set('attrs', _.merge({}, currentAttrs, attr), opt);
  17027. } else {
  17028. return joint.util.getByPath(currentAttrs, attrs, delim);
  17029. }
  17030. }
  17031. return this.set('attrs', _.merge({}, currentAttrs, attrs), value, opt);
  17032. },
  17033. // A convenient way to unset nested attributes
  17034. removeAttr: function(path, opt) {
  17035. if (_.isArray(path)) {
  17036. _.each(path, function(p) { this.removeAttr(p, opt); }, this);
  17037. return this;
  17038. }
  17039. var attrs = joint.util.unsetByPath(_.merge({}, this.get('attrs')), path, '/');
  17040. return this.set('attrs', attrs, _.extend({ dirty: true }, opt));
  17041. },
  17042. transition: function(path, value, opt, delim) {
  17043. delim = delim || '/';
  17044. var defaults = {
  17045. duration: 100,
  17046. delay: 10,
  17047. timingFunction: joint.util.timing.linear,
  17048. valueFunction: joint.util.interpolate.number
  17049. };
  17050. opt = _.extend(defaults, opt);
  17051. var pathArray = path.split(delim);
  17052. var property = pathArray[0];
  17053. var isPropertyNested = pathArray.length > 1;
  17054. var firstFrameTime = 0;
  17055. var interpolatingFunction;
  17056. var setter = _.bind(function(runtime) {
  17057. var id, progress, propertyValue, status;
  17058. firstFrameTime = firstFrameTime || runtime;
  17059. runtime -= firstFrameTime;
  17060. progress = runtime / opt.duration;
  17061. if (progress < 1) {
  17062. this._transitionIds[path] = id = joint.util.nextFrame(setter);
  17063. } else {
  17064. progress = 1;
  17065. delete this._transitionIds[path];
  17066. }
  17067. propertyValue = interpolatingFunction(opt.timingFunction(progress));
  17068. if (isPropertyNested) {
  17069. var nestedPropertyValue = joint.util.setByPath({}, path, propertyValue, delim)[property];
  17070. propertyValue = _.merge({}, this.get(property), nestedPropertyValue);
  17071. }
  17072. opt.transitionId = id;
  17073. this.set(property, propertyValue, opt);
  17074. if (!id) this.trigger('transition:end', this, path);
  17075. }, this);
  17076. var initiator =_.bind(function(callback) {
  17077. this.stopTransitions(path);
  17078. interpolatingFunction = opt.valueFunction(joint.util.getByPath(this.attributes, path, delim), value);
  17079. this._transitionIds[path] = joint.util.nextFrame(callback);
  17080. this.trigger('transition:start', this, path);
  17081. }, this);
  17082. return _.delay(initiator, opt.delay, setter);
  17083. },
  17084. getTransitions: function() {
  17085. return _.keys(this._transitionIds);
  17086. },
  17087. stopTransitions: function(path, delim) {
  17088. delim = delim || '/';
  17089. var pathArray = path && path.split(delim);
  17090. _(this._transitionIds).keys().filter(pathArray && function(key) {
  17091. return _.isEqual(pathArray, key.split(delim).slice(0, pathArray.length));
  17092. }).each(function(key) {
  17093. joint.util.cancelFrame(this._transitionIds[key]);
  17094. delete this._transitionIds[key];
  17095. this.trigger('transition:end', this, key);
  17096. }, this);
  17097. }
  17098. });
  17099. // joint.dia.CellView base view and controller.
  17100. // --------------------------------------------
  17101. // This is the base view and controller for `joint.dia.ElementView` and `joint.dia.LinkView`.
  17102. joint.dia.CellView = Backbone.View.extend({
  17103. tagName: 'g',
  17104. attributes: function() {
  17105. return { 'model-id': this.model.id }
  17106. },
  17107. initialize: function() {
  17108. _.bindAll(this, 'remove', 'update');
  17109. // Store reference to this to the <g> DOM element so that the view is accessible through the DOM tree.
  17110. this.$el.data('view', this);
  17111. this.listenTo(this.model, 'remove', this.remove);
  17112. this.listenTo(this.model, 'change:attrs', this.onChangeAttrs);
  17113. },
  17114. onChangeAttrs: function(cell, attrs, opt) {
  17115. if (opt.dirty) {
  17116. // dirty flag could be set when a model attribute was removed and it needs to be cleared
  17117. // also from the DOM element. See cell.removeAttr().
  17118. return this.render();
  17119. }
  17120. return this.update();
  17121. },
  17122. _configure: function(options) {
  17123. // Make sure a global unique id is assigned to this view. Store this id also to the properties object.
  17124. // The global unique id makes sure that the same view can be rendered on e.g. different machines and
  17125. // still be associated to the same object among all those clients. This is necessary for real-time
  17126. // collaboration mechanism.
  17127. options.id = options.id || joint.util.guid(this);
  17128. Backbone.View.prototype._configure.apply(this, arguments);
  17129. },
  17130. // Override the Backbone `_ensureElement()` method in order to create a `<g>` node that wraps
  17131. // all the nodes of the Cell view.
  17132. _ensureElement: function() {
  17133. var el;
  17134. if (!this.el) {
  17135. var attrs = _.extend({ id: this.id }, _.result(this, 'attributes'));
  17136. if (this.className) attrs['class'] = _.result(this, 'className');
  17137. el = V(_.result(this, 'tagName'), attrs).node;
  17138. } else {
  17139. el = _.result(this, 'el')
  17140. }
  17141. this.setElement(el, false);
  17142. },
  17143. findBySelector: function(selector) {
  17144. // These are either descendants of `this.$el` of `this.$el` itself.
  17145. // `.` is a special selector used to select the wrapping `<g>` element.
  17146. var $selected = selector === '.' ? this.$el : this.$el.find(selector);
  17147. return $selected;
  17148. },
  17149. notify: function(evt) {
  17150. if (this.paper) {
  17151. var args = Array.prototype.slice.call(arguments, 1);
  17152. // Trigger the event on both the element itself and also on the paper.
  17153. this.trigger.apply(this, [evt].concat(args));
  17154. // Paper event handlers receive the view object as the first argument.
  17155. this.paper.trigger.apply(this.paper, [evt, this].concat(args));
  17156. }
  17157. },
  17158. getStrokeBBox: function(el) {
  17159. // Return a bounding box rectangle that takes into account stroke.
  17160. // Note that this is a naive and ad-hoc implementation that does not
  17161. // works only in certain cases and should be replaced as soon as browsers will
  17162. // start supporting the getStrokeBBox() SVG method.
  17163. // @TODO any better solution is very welcome!
  17164. var isMagnet = !!el;
  17165. el = el || this.el;
  17166. var bbox = V(el).bbox(false, this.paper.viewport);
  17167. var strokeWidth;
  17168. if (isMagnet) {
  17169. strokeWidth = V(el).attr('stroke-width');
  17170. } else {
  17171. strokeWidth = this.model.attr('rect/stroke-width') || this.model.attr('circle/stroke-width') || this.model.attr('ellipse/stroke-width') || this.model.attr('path/stroke-width');
  17172. }
  17173. strokeWidth = parseFloat(strokeWidth) || 0;
  17174. return g.rect(bbox).moveAndExpand({ x: -strokeWidth/2, y: -strokeWidth/2, width: strokeWidth, height: strokeWidth });
  17175. },
  17176. getBBox: function() {
  17177. return V(this.el).bbox();
  17178. },
  17179. highlight: function(el) {
  17180. el = !el ? this.el : this.$(el)[0] || this.el;
  17181. V(el).addClass('highlighted');
  17182. },
  17183. unhighlight: function(el) {
  17184. el = !el ? this.el : this.$(el)[0] || this.el;
  17185. V(el).removeClass('highlighted');
  17186. },
  17187. // Find the closest element that has the `magnet` attribute set to `true`. If there was not such
  17188. // an element found, return the root element of the cell view.
  17189. findMagnet: function(el) {
  17190. var $el = this.$(el);
  17191. if ($el.length === 0 || $el[0] === this.el) {
  17192. // If the overall cell has set `magnet === false`, then return `undefined` to
  17193. // announce there is no magnet found for this cell.
  17194. // This is especially useful to set on cells that have 'ports'. In this case,
  17195. // only the ports have set `magnet === true` and the overall element has `magnet === false`.
  17196. var attrs = this.model.get('attrs') || {};
  17197. if (attrs['.'] && attrs['.']['magnet'] === false) {
  17198. return undefined;
  17199. }
  17200. return this.el;
  17201. }
  17202. if ($el.attr('magnet')) {
  17203. return $el[0];
  17204. }
  17205. return this.findMagnet($el.parent());
  17206. },
  17207. // `selector` is a CSS selector or `'.'`. `filter` must be in the special JointJS filter format:
  17208. // `{ name: <name of the filter>, args: { <arguments>, ... }`.
  17209. // An example is: `{ filter: { name: 'blur', args: { radius: 5 } } }`.
  17210. applyFilter: function(selector, filter) {
  17211. var $selected = this.findBySelector(selector);
  17212. // Generate a hash code from the stringified filter definition. This gives us
  17213. // a unique filter ID for different definitions.
  17214. var filterId = filter.name + this.paper.svg.id + joint.util.hashCode(JSON.stringify(filter));
  17215. // If the filter already exists in the document,
  17216. // we're done and we can just use it (reference it using `url()`).
  17217. // If not, create one.
  17218. if (!this.paper.svg.getElementById(filterId)) {
  17219. var filterSVGString = joint.util.filter[filter.name] && joint.util.filter[filter.name](filter.args || {});
  17220. if (!filterSVGString) {
  17221. throw new Error('Non-existing filter ' + filter.name);
  17222. }
  17223. var filterElement = V(filterSVGString);
  17224. filterElement.attr('filterUnits', 'userSpaceOnUse');
  17225. if (filter.attrs) filterElement.attr(filter.attrs);
  17226. filterElement.node.id = filterId;
  17227. V(this.paper.svg).defs().append(filterElement);
  17228. }
  17229. $selected.each(function() {
  17230. V(this).attr('filter', 'url(#' + filterId + ')');
  17231. });
  17232. },
  17233. // `selector` is a CSS selector or `'.'`. `attr` is either a `'fill'` or `'stroke'`.
  17234. // `gradient` must be in the special JointJS gradient format:
  17235. // `{ type: <linearGradient|radialGradient>, stops: [ { offset: <offset>, color: <color> }, ... ]`.
  17236. // An example is: `{ fill: { type: 'linearGradient', stops: [ { offset: '10%', color: 'green' }, { offset: '50%', color: 'blue' } ] } }`.
  17237. applyGradient: function(selector, attr, gradient) {
  17238. var $selected = this.findBySelector(selector);
  17239. // Generate a hash code from the stringified filter definition. This gives us
  17240. // a unique filter ID for different definitions.
  17241. var gradientId = gradient.type + this.paper.svg.id + joint.util.hashCode(JSON.stringify(gradient));
  17242. // If the gradient already exists in the document,
  17243. // we're done and we can just use it (reference it using `url()`).
  17244. // If not, create one.
  17245. if (!this.paper.svg.getElementById(gradientId)) {
  17246. var gradientSVGString = [
  17247. '<' + gradient.type + '>',
  17248. _.map(gradient.stops, function(stop) {
  17249. return '<stop offset="' + stop.offset + '" stop-color="' + stop.color + '" stop-opacity="' + (_.isFinite(stop.opacity) ? stop.opacity : 1) + '" />'
  17250. }).join(''),
  17251. '</' + gradient.type + '>'
  17252. ].join('');
  17253. var gradientElement = V(gradientSVGString);
  17254. if (gradient.attrs) { gradientElement.attr(gradient.attrs); }
  17255. gradientElement.node.id = gradientId;
  17256. V(this.paper.svg).defs().append(gradientElement);
  17257. }
  17258. $selected.each(function() {
  17259. V(this).attr(attr, 'url(#' + gradientId + ')');
  17260. });
  17261. },
  17262. // Construct a unique selector for the `el` element within this view.
  17263. // `selector` is being collected through the recursive call. No value for `selector` is expected when using this method.
  17264. getSelector: function(el, selector) {
  17265. if (el === this.el) {
  17266. return selector;
  17267. }
  17268. var index = $(el).index();
  17269. selector = el.tagName + ':nth-child(' + (index + 1) + ')' + ' ' + (selector || '');
  17270. return this.getSelector($(el).parent()[0], selector + ' ');
  17271. },
  17272. // Interaction. The controller part.
  17273. // ---------------------------------
  17274. // Interaction is handled by the paper and delegated to the view in interest.
  17275. // `x` & `y` parameters passed to these functions represent the coordinates already snapped to the paper grid.
  17276. // If necessary, real coordinates can be obtained from the `evt` event object.
  17277. // These functions are supposed to be overriden by the views that inherit from `joint.dia.Cell`,
  17278. // i.e. `joint.dia.Element` and `joint.dia.Link`.
  17279. pointerdblclick: function(evt, x, y) {
  17280. this.notify('cell:pointerdblclick', evt, x, y);
  17281. },
  17282. pointerclick: function(evt, x, y) {
  17283. this.notify('cell:pointerclick', evt, x, y);
  17284. },
  17285. pointerdown: function(evt, x, y) {
  17286. if (this.model.collection) {
  17287. this.model.trigger('batch:start');
  17288. this._collection = this.model.collection;
  17289. }
  17290. this.notify('cell:pointerdown', evt, x, y);
  17291. },
  17292. pointermove: function(evt, x, y) {
  17293. this.notify('cell:pointermove', evt, x, y);
  17294. },
  17295. pointerup: function(evt, x, y) {
  17296. this.notify('cell:pointerup', evt, x, y);
  17297. if (this._collection) {
  17298. // we don't want to trigger event on model as model doesn't
  17299. // need to be member of collection anymore (remove)
  17300. this._collection.trigger('batch:stop');
  17301. delete this._collection;
  17302. }
  17303. }
  17304. });
  17305. if (typeof exports === 'object') {
  17306. module.exports.Cell = joint.dia.Cell;
  17307. module.exports.CellView = joint.dia.CellView;
  17308. }
  17309. // JointJS library.
  17310. // (c) 2011-2013 client IO
  17311. if (typeof exports === 'object') {
  17312. var joint = {
  17313. util: require('./core').util,
  17314. dia: {
  17315. Cell: require('./joint.dia.cell').Cell,
  17316. CellView: require('./joint.dia.cell').CellView
  17317. }
  17318. };
  17319. var Backbone = require('backbone');
  17320. var _ = require('lodash');
  17321. }
  17322. // joint.dia.Element base model.
  17323. // -----------------------------
  17324. joint.dia.Element = joint.dia.Cell.extend({
  17325. defaults: {
  17326. position: { x: 0, y: 0 },
  17327. size: { width: 1, height: 1 },
  17328. angle: 0
  17329. },
  17330. position: function(x, y) {
  17331. this.set('position', { x: x, y: y });
  17332. },
  17333. translate: function(tx, ty, opt) {
  17334. ty = ty || 0;
  17335. if (tx === 0 && ty === 0) {
  17336. // Like nothing has happened.
  17337. return this;
  17338. }
  17339. var position = this.get('position') || { x: 0, y: 0 };
  17340. var translatedPosition = { x: position.x + tx || 0, y: position.y + ty || 0 };
  17341. if (opt && opt.transition) {
  17342. if (!_.isObject(opt.transition)) opt.transition = {};
  17343. this.transition('position', translatedPosition, _.extend({}, opt.transition, {
  17344. valueFunction: joint.util.interpolate.object
  17345. }));
  17346. } else {
  17347. this.set('position', translatedPosition, opt);
  17348. // Recursively call `translate()` on all the embeds cells.
  17349. _.invoke(this.getEmbeddedCells(), 'translate', tx, ty, opt);
  17350. }
  17351. return this;
  17352. },
  17353. resize: function(width, height) {
  17354. this.trigger('batch:start');
  17355. this.set('size', { width: width, height: height });
  17356. this.trigger('batch:stop');
  17357. return this;
  17358. },
  17359. rotate: function(angle, absolute) {
  17360. return this.set('angle', absolute ? angle : ((this.get('angle') || 0) + angle) % 360);
  17361. },
  17362. getBBox: function() {
  17363. var position = this.get('position');
  17364. var size = this.get('size');
  17365. return g.rect(position.x, position.y, size.width, size.height);
  17366. }
  17367. });
  17368. // joint.dia.Element base view and controller.
  17369. // -------------------------------------------
  17370. joint.dia.ElementView = joint.dia.CellView.extend({
  17371. className: function() {
  17372. return 'element ' + this.model.get('type').split('.').join(' ');
  17373. },
  17374. initialize: function() {
  17375. _.bindAll(this, 'translate', 'resize', 'rotate');
  17376. joint.dia.CellView.prototype.initialize.apply(this, arguments);
  17377. this.listenTo(this.model, 'change:position', this.translate);
  17378. this.listenTo(this.model, 'change:size', this.resize);
  17379. this.listenTo(this.model, 'change:angle', this.rotate);
  17380. },
  17381. // Default is to process the `attrs` object and set attributes on subelements based on the selectors.
  17382. update: function(cell, renderingOnlyAttrs) {
  17383. var allAttrs = this.model.get('attrs');
  17384. var rotatable = V(this.$('.rotatable')[0]);
  17385. if (rotatable) {
  17386. var rotation = rotatable.attr('transform');
  17387. rotatable.attr('transform', '');
  17388. }
  17389. var relativelyPositioned = [];
  17390. _.each(renderingOnlyAttrs || allAttrs, function(attrs, selector) {
  17391. // Elements that should be updated.
  17392. var $selected = this.findBySelector(selector);
  17393. // No element matched by the `selector` was found. We're done then.
  17394. if ($selected.length === 0) return;
  17395. // Special attributes are treated by JointJS, not by SVG.
  17396. var specialAttributes = ['style', 'text', 'html', 'ref-x', 'ref-y', 'ref-dx', 'ref-dy', 'ref-width', 'ref-height', 'ref', 'x-alignment', 'y-alignment', 'port'];
  17397. // If the `filter` attribute is an object, it is in the special JointJS filter format and so
  17398. // it becomes a special attribute and is treated separately.
  17399. if (_.isObject(attrs.filter)) {
  17400. specialAttributes.push('filter');
  17401. this.applyFilter(selector, attrs.filter);
  17402. }
  17403. // If the `fill` or `stroke` attribute is an object, it is in the special JointJS gradient format and so
  17404. // it becomes a special attribute and is treated separately.
  17405. if (_.isObject(attrs.fill)) {
  17406. specialAttributes.push('fill');
  17407. this.applyGradient(selector, 'fill', attrs.fill);
  17408. }
  17409. if (_.isObject(attrs.stroke)) {
  17410. specialAttributes.push('stroke');
  17411. this.applyGradient(selector, 'stroke', attrs.stroke);
  17412. }
  17413. // Make special case for `text` attribute. So that we can set text content of the `<text>` element
  17414. // via the `attrs` object as well.
  17415. // Note that it's important to set text before applying the rest of the final attributes.
  17416. // Vectorizer `text()` method sets on the element its own attributes and it has to be possible
  17417. // to rewrite them, if needed. (i.e display: 'none')
  17418. if (!_.isUndefined(attrs.text)) {
  17419. $selected.each(function() {
  17420. V(this).text(attrs.text + '');
  17421. });
  17422. }
  17423. // Set regular attributes on the `$selected` subelement. Note that we cannot use the jQuery attr()
  17424. // method as some of the attributes might be namespaced (e.g. xlink:href) which fails with jQuery attr().
  17425. var finalAttributes = _.omit(attrs, specialAttributes);
  17426. $selected.each(function() {
  17427. V(this).attr(finalAttributes);
  17428. });
  17429. // `port` attribute contains the `id` of the port that the underlying magnet represents.
  17430. if (attrs.port) {
  17431. $selected.attr('port', _.isUndefined(attrs.port.id) ? attrs.port : attrs.port.id);
  17432. }
  17433. // `style` attribute is special in the sense that it sets the CSS style of the subelement.
  17434. if (attrs.style) {
  17435. $selected.css(attrs.style);
  17436. }
  17437. if (!_.isUndefined(attrs.html)) {
  17438. $selected.each(function() {
  17439. $(this).html(attrs.html + '');
  17440. });
  17441. }
  17442. // Special `ref-x` and `ref-y` attributes make it possible to set both absolute or
  17443. // relative positioning of subelements.
  17444. if (!_.isUndefined(attrs['ref-x']) ||
  17445. !_.isUndefined(attrs['ref-y']) ||
  17446. !_.isUndefined(attrs['ref-dx']) ||
  17447. !_.isUndefined(attrs['ref-dy']) ||
  17448. !_.isUndefined(attrs['x-alignment']) ||
  17449. !_.isUndefined(attrs['y-alignment']) ||
  17450. !_.isUndefined(attrs['ref-width']) ||
  17451. !_.isUndefined(attrs['ref-height'])
  17452. ) {
  17453. _.each($selected, function(el, index, list) {
  17454. var $el = $(el);
  17455. // copy original list selector to the element
  17456. $el.selector = list.selector;
  17457. relativelyPositioned.push($el);
  17458. });
  17459. }
  17460. }, this);
  17461. // We don't want the sub elements to affect the bounding box of the root element when
  17462. // positioning the sub elements relatively to the bounding box.
  17463. //_.invoke(relativelyPositioned, 'hide');
  17464. //_.invoke(relativelyPositioned, 'show');
  17465. // Note that we're using the bounding box without transformation because we are already inside
  17466. // a transformed coordinate system.
  17467. var bbox = this.el.getBBox();
  17468. renderingOnlyAttrs = renderingOnlyAttrs || {};
  17469. _.each(relativelyPositioned, function($el) {
  17470. // if there was a special attribute affecting the position amongst renderingOnlyAttributes
  17471. // we have to merge it with rest of the element's attributes as they are necessary
  17472. // to update the position relatively (i.e `ref`)
  17473. var renderingOnlyElAttrs = renderingOnlyAttrs[$el.selector];
  17474. var elAttrs = renderingOnlyElAttrs
  17475. ? _.merge({}, allAttrs[$el.selector], renderingOnlyElAttrs)
  17476. : allAttrs[$el.selector];
  17477. this.positionRelative($el, bbox, elAttrs);
  17478. }, this);
  17479. if (rotatable) {
  17480. rotatable.attr('transform', rotation || '');
  17481. }
  17482. },
  17483. positionRelative: function($el, bbox, elAttrs) {
  17484. var ref = elAttrs['ref'];
  17485. var refX = parseFloat(elAttrs['ref-x']);
  17486. var refY = parseFloat(elAttrs['ref-y']);
  17487. var refDx = parseFloat(elAttrs['ref-dx']);
  17488. var refDy = parseFloat(elAttrs['ref-dy']);
  17489. var yAlignment = elAttrs['y-alignment'];
  17490. var xAlignment = elAttrs['x-alignment'];
  17491. var refWidth = parseFloat(elAttrs['ref-width']);
  17492. var refHeight = parseFloat(elAttrs['ref-height']);
  17493. // `ref` is the selector of the reference element. If no `ref` is passed, reference
  17494. // element is the root element.
  17495. var isScalable = _.contains(_.pluck(_.pluck($el.parents('g'), 'className'), 'baseVal'), 'scalable');
  17496. if (ref) {
  17497. // Get the bounding box of the reference element relative to the root `<g>` element.
  17498. bbox = V(this.findBySelector(ref)[0]).bbox(false, this.el);
  17499. }
  17500. var vel = V($el[0]);
  17501. // Remove the previous translate() from the transform attribute and translate the element
  17502. // relative to the root bounding box following the `ref-x` and `ref-y` attributes.
  17503. if (vel.attr('transform')) {
  17504. vel.attr('transform', vel.attr('transform').replace(/translate\([^)]*\)/g, '') || '');
  17505. }
  17506. function isDefined(x) {
  17507. return _.isNumber(x) && !_.isNaN(x);
  17508. }
  17509. // The final translation of the subelement.
  17510. var tx = 0;
  17511. var ty = 0;
  17512. // 'ref-width'/'ref-height' defines the width/height of the subelement relatively to
  17513. // the reference element size
  17514. // val in 0..1 ref-width = 0.75 sets the width to 75% of the ref. el. width
  17515. // val < 0 || val > 1 ref-height = -20 sets the height to the the ref. el. height shorter by 20
  17516. if (isDefined(refWidth)) {
  17517. if (refWidth >= 0 && refWidth <= 1) {
  17518. vel.attr('width', refWidth * bbox.width);
  17519. } else {
  17520. vel.attr('width', Math.max(refWidth + bbox.width, 0));
  17521. }
  17522. }
  17523. if (isDefined(refHeight)) {
  17524. if (refHeight >= 0 && refHeight <= 1) {
  17525. vel.attr('height', refHeight * bbox.height);
  17526. } else {
  17527. vel.attr('height', Math.max(refHeight + bbox.height, 0));
  17528. }
  17529. }
  17530. // `ref-dx` and `ref-dy` define the offset of the subelement relative to the right and/or bottom
  17531. // coordinate of the reference element.
  17532. if (isDefined(refDx)) {
  17533. if (isScalable) {
  17534. // Compensate for the scale grid in case the elemnt is in the scalable group.
  17535. var scale = V(this.$('.scalable')[0]).scale();
  17536. tx = bbox.x + bbox.width + refDx / scale.sx;
  17537. } else {
  17538. tx = bbox.x + bbox.width + refDx;
  17539. }
  17540. }
  17541. if (isDefined(refDy)) {
  17542. if (isScalable) {
  17543. // Compensate for the scale grid in case the elemnt is in the scalable group.
  17544. var scale = V(this.$('.scalable')[0]).scale();
  17545. ty = bbox.y + bbox.height + refDy / scale.sy;
  17546. } else {
  17547. ty = bbox.y + bbox.height + refDy;
  17548. }
  17549. }
  17550. // if `refX` is in [0, 1] then `refX` is a fraction of bounding box width
  17551. // if `refX` is < 0 then `refX`'s absolute values is the right coordinate of the bounding box
  17552. // otherwise, `refX` is the left coordinate of the bounding box
  17553. // Analogical rules apply for `refY`.
  17554. if (isDefined(refX)) {
  17555. if (refX > 0 && refX < 1) {
  17556. tx = bbox.x + bbox.width * refX;
  17557. } else if (isScalable) {
  17558. // Compensate for the scale grid in case the elemnt is in the scalable group.
  17559. var scale = V(this.$('.scalable')[0]).scale();
  17560. tx = bbox.x + refX / scale.sx;
  17561. } else {
  17562. tx = bbox.x + refX;
  17563. }
  17564. }
  17565. if (isDefined(refY)) {
  17566. if (refY > 0 && refY < 1) {
  17567. ty = bbox.y + bbox.height * refY;
  17568. } else if (isScalable) {
  17569. // Compensate for the scale grid in case the elemnt is in the scalable group.
  17570. var scale = V(this.$('.scalable')[0]).scale();
  17571. ty = bbox.y + refY / scale.sy;
  17572. } else {
  17573. ty = bbox.y + refY;
  17574. }
  17575. }
  17576. var velbbox = vel.bbox(false, this.paper.viewport);
  17577. // `y-alignment` when set to `middle` causes centering of the subelement around its new y coordinate.
  17578. if (yAlignment === 'middle') {
  17579. ty -= velbbox.height/2;
  17580. } else if (isDefined(yAlignment)) {
  17581. ty += (yAlignment > -1 && yAlignment < 1) ? velbbox.height * yAlignment : yAlignment;
  17582. }
  17583. // `x-alignment` when set to `middle` causes centering of the subelement around its new x coordinate.
  17584. if (xAlignment === 'middle') {
  17585. tx -= velbbox.width/2;
  17586. } else if (isDefined(xAlignment)) {
  17587. tx += (xAlignment > -1 && xAlignment < 1) ? velbbox.width * xAlignment : xAlignment;
  17588. }
  17589. vel.translate(tx, ty);
  17590. },
  17591. // `prototype.markup` is rendered by default. Set the `markup` attribute on the model if the
  17592. // default markup is not desirable.
  17593. renderMarkup: function() {
  17594. var markup = this.model.markup || this.model.get('markup');
  17595. if (markup) {
  17596. var nodes = V(markup);
  17597. V(this.el).append(nodes);
  17598. } else {
  17599. throw new Error('properties.markup is missing while the default render() implementation is used.');
  17600. }
  17601. },
  17602. render: function() {
  17603. this.$el.empty();
  17604. this.renderMarkup();
  17605. this.update();
  17606. this.resize();
  17607. this.rotate();
  17608. this.translate();
  17609. return this;
  17610. },
  17611. // Scale the whole `<g>` group. Note the difference between `scale()` and `resize()` here.
  17612. // `resize()` doesn't scale the whole `<g>` group but rather adjusts the `box.sx`/`box.sy` only.
  17613. // `update()` is then responsible for scaling only those elements that have the `follow-scale`
  17614. // attribute set to `true`. This is desirable in elements that have e.g. a `<text>` subelement
  17615. // that is not supposed to be scaled together with a surrounding `<rect>` element that IS supposed
  17616. // be be scaled.
  17617. scale: function(sx, sy) {
  17618. // TODO: take into account the origin coordinates `ox` and `oy`.
  17619. V(this.el).scale(sx, sy);
  17620. },
  17621. resize: function() {
  17622. var size = this.model.get('size') || { width: 1, height: 1 };
  17623. var angle = this.model.get('angle') || 0;
  17624. var scalable = V(this.$('.scalable')[0]);
  17625. if (!scalable) {
  17626. // If there is no scalable elements, than there is nothing to resize.
  17627. return;
  17628. }
  17629. var scalableBbox = scalable.bbox(true);
  17630. scalable.attr('transform', 'scale(' + (size.width / scalableBbox.width) + ',' + (size.height / scalableBbox.height) + ')');
  17631. // Now the interesting part. The goal is to be able to store the object geometry via just `x`, `y`, `angle`, `width` and `height`
  17632. // Order of transformations is significant but we want to reconstruct the object always in the order:
  17633. // resize(), rotate(), translate() no matter of how the object was transformed. For that to work,
  17634. // we must adjust the `x` and `y` coordinates of the object whenever we resize it (because the origin of the
  17635. // rotation changes). The new `x` and `y` coordinates are computed by canceling the previous rotation
  17636. // around the center of the resized object (which is a different origin then the origin of the previous rotation)
  17637. // and getting the top-left corner of the resulting object. Then we clean up the rotation back to what it originally was.
  17638. // Cancel the rotation but now around a different origin, which is the center of the scaled object.
  17639. var rotatable = V(this.$('.rotatable')[0]);
  17640. var rotation = rotatable && rotatable.attr('transform');
  17641. if (rotation && rotation !== 'null') {
  17642. rotatable.attr('transform', rotation + ' rotate(' + (-angle) + ',' + (size.width/2) + ',' + (size.height/2) + ')');
  17643. var rotatableBbox = scalable.bbox(false, this.paper.viewport);
  17644. // Store new x, y and perform rotate() again against the new rotation origin.
  17645. this.model.set('position', { x: rotatableBbox.x, y: rotatableBbox.y });
  17646. this.rotate();
  17647. }
  17648. // Update must always be called on non-rotated element. Otherwise, relative positioning
  17649. // would work with wrong (rotated) bounding boxes.
  17650. this.update();
  17651. },
  17652. translate: function(model, changes, opt) {
  17653. var position = this.model.get('position') || { x: 0, y: 0 };
  17654. V(this.el).attr('transform', 'translate(' + position.x + ',' + position.y + ')');
  17655. },
  17656. rotate: function() {
  17657. var rotatable = V(this.$('.rotatable')[0]);
  17658. if (!rotatable) {
  17659. // If there is no rotatable elements, then there is nothing to rotate.
  17660. return;
  17661. }
  17662. var angle = this.model.get('angle') || 0;
  17663. var size = this.model.get('size') || { width: 1, height: 1 };
  17664. var ox = size.width/2;
  17665. var oy = size.height/2;
  17666. rotatable.attr('transform', 'rotate(' + angle + ',' + ox + ',' + oy + ')');
  17667. },
  17668. // Interaction. The controller part.
  17669. // ---------------------------------
  17670. pointerdown: function(evt, x, y) {
  17671. if ( // target is a valid magnet start linking
  17672. evt.target.getAttribute('magnet') &&
  17673. this.paper.options.validateMagnet.call(this.paper, this, evt.target)
  17674. ) {
  17675. this.model.trigger('batch:start');
  17676. var link = this.paper.getDefaultLink(this, evt.target);
  17677. link.set({
  17678. source: {
  17679. id: this.model.id,
  17680. selector: this.getSelector(evt.target),
  17681. port: $(evt.target).attr('port')
  17682. },
  17683. target: { x: x, y: y }
  17684. });
  17685. this.paper.model.addCell(link);
  17686. this._linkView = this.paper.findViewByModel(link);
  17687. this._linkView.startArrowheadMove('target');
  17688. } else {
  17689. this._dx = x;
  17690. this._dy = y;
  17691. joint.dia.CellView.prototype.pointerdown.apply(this, arguments);
  17692. }
  17693. },
  17694. pointermove: function(evt, x, y) {
  17695. if (this._linkView) {
  17696. // let the linkview deal with this event
  17697. this._linkView.pointermove(evt, x, y);
  17698. } else {
  17699. var grid = this.paper.options.gridSize;
  17700. if (this.options.interactive !== false) {
  17701. var position = this.model.get('position');
  17702. // Make sure the new element's position always snaps to the current grid after
  17703. // translate as the previous one could be calculated with a different grid size.
  17704. this.model.translate(
  17705. g.snapToGrid(position.x, grid) - position.x + g.snapToGrid(x - this._dx, grid),
  17706. g.snapToGrid(position.y, grid) - position.y + g.snapToGrid(y - this._dy, grid)
  17707. );
  17708. }
  17709. this._dx = g.snapToGrid(x, grid);
  17710. this._dy = g.snapToGrid(y, grid);
  17711. joint.dia.CellView.prototype.pointermove.apply(this, arguments);
  17712. }
  17713. },
  17714. pointerup: function(evt, x, y) {
  17715. if (this._linkView) {
  17716. // let the linkview deal with this event
  17717. this._linkView.pointerup(evt, x, y);
  17718. delete this._linkView;
  17719. this.model.trigger('batch:stop');
  17720. } else {
  17721. joint.dia.CellView.prototype.pointerup.apply(this, arguments);
  17722. }
  17723. }
  17724. });
  17725. if (typeof exports === 'object') {
  17726. module.exports.Element = joint.dia.Element;
  17727. module.exports.ElementView = joint.dia.ElementView;
  17728. }
  17729. // JointJS diagramming library.
  17730. // (c) 2011-2013 client IO
  17731. if (typeof exports === 'object') {
  17732. var joint = {
  17733. dia: {
  17734. Cell: require('./joint.dia.cell').Cell,
  17735. CellView: require('./joint.dia.cell').CellView
  17736. }
  17737. };
  17738. var Backbone = require('backbone');
  17739. var _ = require('lodash');
  17740. var g = require('./geometry');
  17741. }
  17742. // joint.dia.Link base model.
  17743. // --------------------------
  17744. joint.dia.Link = joint.dia.Cell.extend({
  17745. // The default markup for links.
  17746. markup: [
  17747. '<path class="connection" stroke="black"/>',
  17748. '<path class="marker-source" fill="black" stroke="black" />',
  17749. '<path class="marker-target" fill="black" stroke="black" />',
  17750. '<path class="connection-wrap"/>',
  17751. '<g class="labels"/>',
  17752. '<g class="marker-vertices"/>',
  17753. '<g class="marker-arrowheads"/>',
  17754. '<g class="link-tools"/>'
  17755. ].join(''),
  17756. labelMarkup: [
  17757. '<g class="label">',
  17758. '<rect />',
  17759. '<text />',
  17760. '</g>'
  17761. ].join(''),
  17762. toolMarkup: [
  17763. '<g class="link-tool">',
  17764. '<g class="tool-remove" event="remove">',
  17765. '<circle r="11" />',
  17766. '<path transform="scale(.8) translate(-16, -16)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z"/>',
  17767. '<title>Remove link.</title>',
  17768. '</g>',
  17769. '<g class="tool-options" event="link:options">',
  17770. '<circle r="11" transform="translate(25)"/>',
  17771. '<path fill="white" transform="scale(.55) translate(29, -16)" d="M31.229,17.736c0.064-0.571,0.104-1.148,0.104-1.736s-0.04-1.166-0.104-1.737l-4.377-1.557c-0.218-0.716-0.504-1.401-0.851-2.05l1.993-4.192c-0.725-0.91-1.549-1.734-2.458-2.459l-4.193,1.994c-0.647-0.347-1.334-0.632-2.049-0.849l-1.558-4.378C17.165,0.708,16.588,0.667,16,0.667s-1.166,0.041-1.737,0.105L12.707,5.15c-0.716,0.217-1.401,0.502-2.05,0.849L6.464,4.005C5.554,4.73,4.73,5.554,4.005,6.464l1.994,4.192c-0.347,0.648-0.632,1.334-0.849,2.05l-4.378,1.557C0.708,14.834,0.667,15.412,0.667,16s0.041,1.165,0.105,1.736l4.378,1.558c0.217,0.715,0.502,1.401,0.849,2.049l-1.994,4.193c0.725,0.909,1.549,1.733,2.459,2.458l4.192-1.993c0.648,0.347,1.334,0.633,2.05,0.851l1.557,4.377c0.571,0.064,1.148,0.104,1.737,0.104c0.588,0,1.165-0.04,1.736-0.104l1.558-4.377c0.715-0.218,1.399-0.504,2.049-0.851l4.193,1.993c0.909-0.725,1.733-1.549,2.458-2.458l-1.993-4.193c0.347-0.647,0.633-1.334,0.851-2.049L31.229,17.736zM16,20.871c-2.69,0-4.872-2.182-4.872-4.871c0-2.69,2.182-4.872,4.872-4.872c2.689,0,4.871,2.182,4.871,4.872C20.871,18.689,18.689,20.871,16,20.871z"/>',
  17772. '<title>Link options.</title>',
  17773. '</g>',
  17774. '</g>'
  17775. ].join(''),
  17776. // The default markup for showing/removing vertices. These elements are the children of the .marker-vertices element (see `this.markup`).
  17777. // Only .marker-vertex and .marker-vertex-remove element have special meaning. The former is used for
  17778. // dragging vertices (changin their position). The latter is used for removing vertices.
  17779. vertexMarkup: [
  17780. '<g class="marker-vertex-group" transform="translate(<%= x %>, <%= y %>)">',
  17781. '<circle class="marker-vertex" idx="<%= idx %>" r="10" />',
  17782. '<path class="marker-vertex-remove-area" idx="<%= idx %>" d="M16,5.333c-7.732,0-14,4.701-14,10.5c0,1.982,0.741,3.833,2.016,5.414L2,25.667l5.613-1.441c2.339,1.317,5.237,2.107,8.387,2.107c7.732,0,14-4.701,14-10.5C30,10.034,23.732,5.333,16,5.333z" transform="translate(5, -33)"/>',
  17783. '<path class="marker-vertex-remove" idx="<%= idx %>" transform="scale(.8) translate(9.5, -37)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z">',
  17784. '<title>Remove vertex.</title>',
  17785. '</path>',
  17786. '</g>'
  17787. ].join(''),
  17788. arrowheadMarkup: [
  17789. '<g class="marker-arrowhead-group marker-arrowhead-group-<%= end %>">',
  17790. '<path class="marker-arrowhead" end="<%= end %>" d="M 26 0 L 0 13 L 26 26 z" />',
  17791. '</g>'
  17792. ].join(''),
  17793. defaults: {
  17794. type: 'link'
  17795. },
  17796. disconnect: function() {
  17797. return this.set({ source: g.point(0, 0), target: g.point(0, 0) });
  17798. },
  17799. // A convenient way to set labels. Currently set values will be mixined with `value` if used as a setter.
  17800. label: function(idx, value) {
  17801. idx = idx || 0;
  17802. var labels = this.get('labels') || [];
  17803. // Is it a getter?
  17804. if (arguments.length === 0 || arguments.length === 1) {
  17805. return labels[idx];
  17806. }
  17807. var newValue = _.merge({}, labels[idx], value);
  17808. var newLabels = labels.slice();
  17809. newLabels[idx] = newValue;
  17810. return this.set({ labels: newLabels });
  17811. }
  17812. });
  17813. // joint.dia.Link base view and controller.
  17814. // ----------------------------------------
  17815. joint.dia.LinkView = joint.dia.CellView.extend({
  17816. className: function() {
  17817. return _.unique(this.model.get('type').split('.').concat('link')).join(' ');
  17818. },
  17819. options: {
  17820. shortLinkLength: 100
  17821. },
  17822. initialize: function() {
  17823. joint.dia.CellView.prototype.initialize.apply(this, arguments);
  17824. // create methods in prototype, so they can be accessed from any instance and
  17825. // don't need to be create over and over
  17826. if (typeof this.constructor.prototype.watchSource !== 'function') {
  17827. this.constructor.prototype.watchSource = this._createWatcher('source');
  17828. this.constructor.prototype.watchTarget = this._createWatcher('target');
  17829. }
  17830. // `_.labelCache` is a mapping of indexes of labels in the `this.get('labels')` array to
  17831. // `<g class="label">` nodes wrapped by Vectorizer. This allows for quick access to the
  17832. // nodes in `updateLabelPosition()` in order to update the label positions.
  17833. this._labelCache = {};
  17834. // keeps markers bboxes and positions again for quicker access
  17835. this._markerCache = {};
  17836. // bind events
  17837. this.startListening();
  17838. },
  17839. startListening: function() {
  17840. this.listenTo(this.model, 'change:markup', this.render);
  17841. this.listenTo(this.model, 'change:smooth change:manhattan change:router change:connector', this.update);
  17842. this.listenTo(this.model, 'change:toolMarkup', function() {
  17843. this.renderTools().updateToolsPosition();
  17844. });
  17845. this.listenTo(this.model, 'change:labels change:labelMarkup', function() {
  17846. this.renderLabels().updateLabelPositions();
  17847. });
  17848. this.listenTo(this.model, 'change:vertices change:vertexMarkup', function() {
  17849. this.renderVertexMarkers().update();
  17850. });
  17851. this.listenTo(this.model, 'change:source', function(cell, source) {
  17852. this.watchSource(cell, source).update();
  17853. });
  17854. this.listenTo(this.model, 'change:target', function(cell, target) {
  17855. this.watchTarget(cell, target).update();
  17856. });
  17857. },
  17858. // Rendering
  17859. //----------
  17860. render: function() {
  17861. this.$el.empty();
  17862. // A special markup can be given in the `properties.markup` property. This might be handy
  17863. // if e.g. arrowhead markers should be `<image>` elements or any other element than `<path>`s.
  17864. // `.connection`, `.connection-wrap`, `.marker-source` and `.marker-target` selectors
  17865. // of elements with special meaning though. Therefore, those classes should be preserved in any
  17866. // special markup passed in `properties.markup`.
  17867. var children = V(this.model.get('markup') || this.model.markup);
  17868. // custom markup may contain only one children
  17869. if (!_.isArray(children)) children = [children];
  17870. // Cache all children elements for quicker access.
  17871. this._V = {}; // vectorized markup;
  17872. _.each(children, function(child) {
  17873. var c = child.attr('class');
  17874. c && (this._V[$.camelCase(c)] = child);
  17875. }, this);
  17876. // Only the connection path is mandatory
  17877. if (!this._V.connection) throw new Error('link: no connection path in the markup');
  17878. // partial rendering
  17879. this.renderTools();
  17880. this.renderVertexMarkers();
  17881. this.renderArrowheadMarkers();
  17882. V(this.el).append(children);
  17883. // rendering labels has to be run after the link is appended to DOM tree. (otherwise <Text> bbox
  17884. // returns zero values)
  17885. this.renderLabels();
  17886. // start watching the ends of the link for changes
  17887. this.watchSource(this.model, this.model.get('source'))
  17888. .watchTarget(this.model, this.model.get('target'))
  17889. .update();
  17890. return this;
  17891. },
  17892. renderLabels: function() {
  17893. if (!this._V.labels) return this;
  17894. this._labelCache = {};
  17895. var $labels = $(this._V.labels.node).empty();
  17896. var labels = this.model.get('labels') || [];
  17897. if (!labels.length) return this;
  17898. var labelTemplate = _.template(this.model.get('labelMarkup') || this.model.labelMarkup);
  17899. // This is a prepared instance of a vectorized SVGDOM node for the label element resulting from
  17900. // compilation of the labelTemplate. The purpose is that all labels will just `clone()` this
  17901. // node to create a duplicate.
  17902. var labelNodeInstance = V(labelTemplate());
  17903. _.each(labels, function(label, idx) {
  17904. var labelNode = labelNodeInstance.clone().node;
  17905. // Cache label nodes so that the `updateLabels()` can just update the label node positions.
  17906. this._labelCache[idx] = V(labelNode);
  17907. var $text = $(labelNode).find('text');
  17908. var $rect = $(labelNode).find('rect');
  17909. // Text attributes with the default `text-anchor` and font-size set.
  17910. var textAttributes = _.extend({ 'text-anchor': 'middle', 'font-size': 14 }, joint.util.getByPath(label, 'attrs/text', '/'));
  17911. $text.attr(_.omit(textAttributes, 'text'));
  17912. if (!_.isUndefined(textAttributes.text)) {
  17913. V($text[0]).text(textAttributes.text + '');
  17914. }
  17915. // Note that we first need to append the `<text>` element to the DOM in order to
  17916. // get its bounding box.
  17917. $labels.append(labelNode);
  17918. // `y-alignment` - center the text element around its y coordinate.
  17919. var textBbox = V($text[0]).bbox(true, $labels[0]);
  17920. V($text[0]).translate(0, -textBbox.height/2);
  17921. // Add default values.
  17922. var rectAttributes = _.extend({
  17923. fill: 'white',
  17924. rx: 3,
  17925. ry: 3
  17926. }, joint.util.getByPath(label, 'attrs/rect', '/'));
  17927. $rect.attr(_.extend(rectAttributes, {
  17928. x: textBbox.x,
  17929. y: textBbox.y - textBbox.height/2, // Take into account the y-alignment translation.
  17930. width: textBbox.width,
  17931. height: textBbox.height
  17932. }));
  17933. }, this);
  17934. return this;
  17935. },
  17936. renderTools: function() {
  17937. if (!this._V.linkTools) return this;
  17938. // Tools are a group of clickable elements that manipulate the whole link.
  17939. // A good example of this is the remove tool that removes the whole link.
  17940. // Tools appear after hovering the link close to the `source` element/point of the link
  17941. // but are offset a bit so that they don't cover the `marker-arrowhead`.
  17942. var $tools = $(this._V.linkTools.node).empty();
  17943. var toolTemplate = _.template(this.model.get('toolMarkup') || this.model.toolMarkup);
  17944. var tool = V(toolTemplate());
  17945. $tools.append(tool.node);
  17946. // Cache the tool node so that the `updateToolsPosition()` can update the tool position quickly.
  17947. this._toolCache = tool;
  17948. return this;
  17949. },
  17950. renderVertexMarkers: function() {
  17951. if (!this._V.markerVertices) return this;
  17952. var $markerVertices = $(this._V.markerVertices.node).empty();
  17953. // A special markup can be given in the `properties.vertexMarkup` property. This might be handy
  17954. // if default styling (elements) are not desired. This makes it possible to use any
  17955. // SVG elements for .marker-vertex and .marker-vertex-remove tools.
  17956. var markupTemplate = _.template(this.model.get('vertexMarkup') || this.model.vertexMarkup);
  17957. _.each(this.model.get('vertices'), function(vertex, idx) {
  17958. $markerVertices.append(V(markupTemplate(_.extend({ idx: idx }, vertex))).node);
  17959. });
  17960. return this;
  17961. },
  17962. renderArrowheadMarkers: function() {
  17963. // Custom markups might not have arrowhead markers. Therefore, jump of this function immediately if that's the case.
  17964. if (!this._V.markerArrowheads) return this;
  17965. var $markerArrowheads = $(this._V.markerArrowheads.node);
  17966. $markerArrowheads.empty();
  17967. // A special markup can be given in the `properties.vertexMarkup` property. This might be handy
  17968. // if default styling (elements) are not desired. This makes it possible to use any
  17969. // SVG elements for .marker-vertex and .marker-vertex-remove tools.
  17970. var markupTemplate = _.template(this.model.get('arrowheadMarkup') || this.model.arrowheadMarkup);
  17971. this._V.sourceArrowhead = V(markupTemplate({ end: 'source' }));
  17972. this._V.targetArrowhead = V(markupTemplate({ end: 'target' }));
  17973. $markerArrowheads.append(this._V.sourceArrowhead.node, this._V.targetArrowhead.node);
  17974. return this;
  17975. },
  17976. // Updating
  17977. //---------
  17978. // Default is to process the `attrs` object and set attributes on subelements based on the selectors.
  17979. update: function() {
  17980. // Update attributes.
  17981. _.each(this.model.get('attrs'), function(attrs, selector) {
  17982. // If the `filter` attribute is an object, it is in the special JointJS filter format and so
  17983. // it becomes a special attribute and is treated separately.
  17984. if (_.isObject(attrs.filter)) {
  17985. this.findBySelector(selector).attr(_.omit(attrs, 'filter'));
  17986. this.applyFilter(selector, attrs.filter);
  17987. } else {
  17988. this.findBySelector(selector).attr(attrs);
  17989. }
  17990. }, this);
  17991. // Path finding
  17992. var vertices = this.route = this.findRoute(this.model.get('vertices') || []);
  17993. // finds all the connection points taking new vertices into account
  17994. this._findConnectionPoints(vertices);
  17995. var pathData = this.getPathData(vertices);
  17996. // The markup needs to contain a `.connection`
  17997. this._V.connection.attr('d', pathData);
  17998. this._V.connectionWrap && this._V.connectionWrap.attr('d', pathData);
  17999. this._translateAndAutoOrientArrows(this._V.markerSource, this._V.markerTarget);
  18000. //partials updates
  18001. this.updateLabelPositions();
  18002. this.updateToolsPosition();
  18003. this.updateArrowheadMarkers();
  18004. delete this.options.perpendicular;
  18005. return this;
  18006. },
  18007. _findConnectionPoints: function(vertices) {
  18008. // cache source and target points
  18009. var sourcePoint, targetPoint, sourceMarkerPoint, targetMarkerPoint;
  18010. var firstVertex = _.first(vertices);
  18011. sourcePoint = this.getConnectionPoint(
  18012. 'source', this.model.get('source'), firstVertex || this.model.get('target')
  18013. ).round();
  18014. var lastVertex = _.last(vertices);
  18015. targetPoint = this.getConnectionPoint(
  18016. 'target', this.model.get('target'), lastVertex || sourcePoint
  18017. ).round();
  18018. // Move the source point by the width of the marker taking into account
  18019. // its scale around x-axis. Note that scale is the only transform that
  18020. // makes sense to be set in `.marker-source` attributes object
  18021. // as all other transforms (translate/rotate) will be replaced
  18022. // by the `translateAndAutoOrient()` function.
  18023. var cache = this._markerCache;
  18024. if (this._V.markerSource) {
  18025. cache.sourceBBox = cache.sourceBBox || this._V.markerSource.bbox(true);
  18026. sourceMarkerPoint = g.point(sourcePoint).move(
  18027. firstVertex || targetPoint,
  18028. cache.sourceBBox.width * this._V.markerSource.scale().sx * -1
  18029. ).round();
  18030. }
  18031. if (this._V.markerTarget) {
  18032. cache.targetBBox = cache.targetBBox || this._V.markerTarget.bbox(true);
  18033. targetMarkerPoint = g.point(targetPoint).move(
  18034. lastVertex || sourcePoint,
  18035. cache.targetBBox.width * this._V.markerTarget.scale().sx * -1
  18036. ).round();
  18037. }
  18038. // if there was no markup for the marker, use the connection point.
  18039. cache.sourcePoint = sourceMarkerPoint || sourcePoint;
  18040. cache.targetPoint = targetMarkerPoint || targetPoint;
  18041. // make connection points public
  18042. this.sourcePoint = sourcePoint;
  18043. this.targetPoint = targetPoint;
  18044. },
  18045. updateLabelPositions: function() {
  18046. if (!this._V.labels) return this;
  18047. // This method assumes all the label nodes are stored in the `this._labelCache` hash table
  18048. // by their indexes in the `this.get('labels')` array. This is done in the `renderLabels()` method.
  18049. var labels = this.model.get('labels') || [];
  18050. if (!labels.length) return this;
  18051. var connectionElement = this._V.connection.node;
  18052. var connectionLength = connectionElement.getTotalLength();
  18053. _.each(labels, function(label, idx) {
  18054. var position = label.position;
  18055. position = (position > connectionLength) ? connectionLength : position; // sanity check
  18056. position = (position < 0) ? connectionLength + position : position;
  18057. position = position > 1 ? position : connectionLength * position;
  18058. var labelCoordinates = connectionElement.getPointAtLength(position);
  18059. this._labelCache[idx].attr('transform', 'translate(' + labelCoordinates.x + ', ' + labelCoordinates.y + ')');
  18060. }, this);
  18061. return this;
  18062. },
  18063. updateToolsPosition: function() {
  18064. if (!this._V.linkTools) return this;
  18065. // Move the tools a bit to the target position but don't cover the `sourceArrowhead` marker.
  18066. // Note that the offset is hardcoded here. The offset should be always
  18067. // more than the `this.$('.marker-arrowhead[end="source"]')[0].bbox().width` but looking
  18068. // this up all the time would be slow.
  18069. var scale = '';
  18070. var offset = 40;
  18071. // If the link is too short, make the tools half the size and the offset twice as low.
  18072. if (this.getConnectionLength() < this.options.shortLinkLength) {
  18073. scale = 'scale(.5)';
  18074. offset /= 2;
  18075. }
  18076. var toolPosition = this.getPointAtLength(offset);
  18077. this._toolCache.attr('transform', 'translate(' + toolPosition.x + ', ' + toolPosition.y + ') ' + scale);
  18078. return this;
  18079. },
  18080. updateArrowheadMarkers: function() {
  18081. if (!this._V.markerArrowheads) return this;
  18082. // getting bbox of an element with `display="none"` in IE9 ends up with access violation
  18083. if ($.css(this._V.markerArrowheads.node, 'display') === 'none') return this;
  18084. var sx = this.getConnectionLength() < this.options.shortLinkLength ? .5 : 1;
  18085. this._V.sourceArrowhead.scale(sx);
  18086. this._V.targetArrowhead.scale(sx);
  18087. this._translateAndAutoOrientArrows(this._V.sourceArrowhead, this._V.targetArrowhead);
  18088. return this;
  18089. },
  18090. // Returns a function observing changes on an end of the link. If a change happens and new end is a new model,
  18091. // it stops listening on the previous one and starts listening to the new one.
  18092. _createWatcher: function(endType) {
  18093. function watchEnd(link, end) {
  18094. end = end || {};
  18095. var previousEnd = link.previous(endType) || {};
  18096. // Pick updateMethod this._sourceBboxUpdate or this._targetBboxUpdate.
  18097. var updateEndFunction = this['_' + endType + 'BBoxUpdate'];
  18098. if (this._isModel(previousEnd)) {
  18099. this.stopListening(this.paper.getModelById(previousEnd.id), 'change', updateEndFunction);
  18100. }
  18101. if (this._isModel(end)) {
  18102. // If the observed model changes, it caches a new bbox and do the link update.
  18103. this.listenTo(this.paper.getModelById(end.id), 'change', updateEndFunction);
  18104. }
  18105. _.bind(updateEndFunction, this)({ cacheOnly: true });
  18106. return this;
  18107. }
  18108. return watchEnd;
  18109. },
  18110. // It's important to keep both methods (sourceBboxUpdate and targetBboxUpdate) as unique methods
  18111. // because of loop links. We have to be able to determine, which method we want to stop listen to.
  18112. // ListenTo(model, event, handler) as model and event will be identical.
  18113. _sourceBBoxUpdate: function(update) {
  18114. // keep track which end had been changed very last
  18115. this.lastEndChange = 'source';
  18116. update = update || {};
  18117. var end = this.model.get('source');
  18118. if (this._isModel(end)) {
  18119. var selector = this._makeSelector(end);
  18120. var view = this.paper.findViewByModel(end.id);
  18121. var magnetElement = this.paper.viewport.querySelector(selector);
  18122. this.sourceBBox = view.getStrokeBBox(magnetElement);
  18123. } else {
  18124. // the link end is a point ~ rect 1x1
  18125. this.sourceBBox = g.rect(end.x, end.y, 1, 1);
  18126. }
  18127. if (!update.cacheOnly) this.update();
  18128. },
  18129. _targetBBoxUpdate: function(update) {
  18130. // keep track which end had been changed very last
  18131. this.lastEndChange = 'target';
  18132. update = update || {};
  18133. var end = this.model.get('target');
  18134. if (this._isModel(end)) {
  18135. var selector = this._makeSelector(end);
  18136. var view = this.paper.findViewByModel(end.id);
  18137. var magnetElement = this.paper.viewport.querySelector(selector);
  18138. this.targetBBox = view.getStrokeBBox(magnetElement);
  18139. } else {
  18140. // the link end is a point ~ rect 1x1
  18141. this.targetBBox = g.rect(end.x, end.y, 1, 1);
  18142. }
  18143. if (!update.cacheOnly) this.update();
  18144. },
  18145. _translateAndAutoOrientArrows: function(sourceArrow, targetArrow) {
  18146. // Make the markers "point" to their sticky points being auto-oriented towards
  18147. // `targetPosition`/`sourcePosition`. And do so only if there is a markup for them.
  18148. if (sourceArrow) {
  18149. sourceArrow.translateAndAutoOrient(
  18150. this.sourcePoint,
  18151. _.first(this.route) || this.targetPoint,
  18152. this.paper.viewport
  18153. );
  18154. }
  18155. if (targetArrow) {
  18156. targetArrow.translateAndAutoOrient(
  18157. this.targetPoint,
  18158. _.last(this.route) || this.sourcePoint,
  18159. this.paper.viewport
  18160. );
  18161. }
  18162. },
  18163. removeVertex: function(idx) {
  18164. var vertices = _.clone(this.model.get('vertices'));
  18165. if (vertices && vertices.length) {
  18166. vertices.splice(idx, 1);
  18167. this.model.set('vertices', vertices);
  18168. }
  18169. return this;
  18170. },
  18171. // This method ads a new vertex to the `vertices` array of `.connection`. This method
  18172. // uses a heuristic to find the index at which the new `vertex` should be placed at assuming
  18173. // the new vertex is somewhere on the path.
  18174. addVertex: function(vertex) {
  18175. this.model.set('attrs', this.model.get('attrs') || {});
  18176. var attrs = this.model.get('attrs');
  18177. // As it is very hard to find a correct index of the newly created vertex,
  18178. // a little heuristics is taking place here.
  18179. // The heuristics checks if length of the newly created
  18180. // path is lot more than length of the old path. If this is the case,
  18181. // new vertex was probably put into a wrong index.
  18182. // Try to put it into another index and repeat the heuristics again.
  18183. var vertices = (this.model.get('vertices') || []).slice();
  18184. // Store the original vertices for a later revert if needed.
  18185. var originalVertices = vertices.slice();
  18186. // A `<path>` element used to compute the length of the path during heuristics.
  18187. var path = this._V.connection.node.cloneNode(false);
  18188. // Length of the original path.
  18189. var originalPathLength = path.getTotalLength();
  18190. // Current path length.
  18191. var pathLength;
  18192. // Tolerance determines the highest possible difference between the length
  18193. // of the old and new path. The number has been chosen heuristically.
  18194. var pathLengthTolerance = 20;
  18195. // Total number of vertices including source and target points.
  18196. var idx = vertices.length + 1;
  18197. // Loop through all possible indexes and check if the difference between
  18198. // path lengths changes significantly. If not, the found index is
  18199. // most probably the right one.
  18200. while (idx--) {
  18201. vertices.splice(idx, 0, vertex);
  18202. V(path).attr('d', this.getPathData(this.findRoute(vertices)));
  18203. pathLength = path.getTotalLength();
  18204. // Check if the path lengths changed significantly.
  18205. if (pathLength - originalPathLength > pathLengthTolerance) {
  18206. // Revert vertices to the original array. The path length has changed too much
  18207. // so that the index was not found yet.
  18208. vertices = originalVertices.slice();
  18209. } else {
  18210. break;
  18211. }
  18212. }
  18213. this.model.set('vertices', vertices);
  18214. // In manhattan routing, if there are no vertices, the path length changes significantly
  18215. // with the first vertex added. Shall we check vertices.length === 0? at beginning of addVertex()
  18216. // in order to avoid the temporary path construction and other operations?
  18217. return Math.max(idx, 0);
  18218. },
  18219. findRoute: function(oldVertices) {
  18220. var router = this.model.get('router');
  18221. if (!router) {
  18222. if (this.model.get('manhattan')) {
  18223. // backwards compability
  18224. router = { name: 'orthogonal' };
  18225. } else {
  18226. return oldVertices;
  18227. }
  18228. }
  18229. var fn = joint.routers[router.name];
  18230. if (!_.isFunction(fn)) {
  18231. throw 'unknown router: ' + router.name;
  18232. }
  18233. var newVertices = fn.call(this, oldVertices || [], router.args || {}, this);
  18234. return newVertices;
  18235. },
  18236. // Return the `d` attribute value of the `<path>` element representing the link
  18237. // between `source` and `target`.
  18238. getPathData: function(vertices) {
  18239. var connector = this.model.get('connector');
  18240. if (!connector) {
  18241. // backwards compability
  18242. connector = this.model.get('smooth') ? { name: 'smooth' } : { name: 'normal' };
  18243. }
  18244. if (!_.isFunction(joint.connectors[connector.name])) {
  18245. throw 'unknown connector: ' + connector.name;
  18246. }
  18247. var pathData = joint.connectors[connector.name].call(
  18248. this,
  18249. this._markerCache.sourcePoint, // Note that the value is translated by the size
  18250. this._markerCache.targetPoint, // of the marker. (We'r not using this.sourcePoint)
  18251. vertices || (this.model.get('vertices') || {}),
  18252. connector.args || {}, // options
  18253. this
  18254. );
  18255. return pathData;
  18256. },
  18257. // Find a point that is the start of the connection.
  18258. // If `selectorOrPoint` is a point, then we're done and that point is the start of the connection.
  18259. // If the `selectorOrPoint` is an element however, we need to know a reference point (or element)
  18260. // that the link leads to in order to determine the start of the connection on the original element.
  18261. getConnectionPoint: function(end, selectorOrPoint, referenceSelectorOrPoint) {
  18262. var spot;
  18263. if (this._isPoint(selectorOrPoint)) {
  18264. // If the source is a point, we don't need a reference point to find the sticky point of connection.
  18265. spot = g.point(selectorOrPoint);
  18266. } else {
  18267. // If the source is an element, we need to find a point on the element boundary that is closest
  18268. // to the reference point (or reference element).
  18269. // Get the bounding box of the spot relative to the paper viewport. This is necessary
  18270. // in order to follow paper viewport transformations (scale/rotate).
  18271. // `_sourceBbox` (`_targetBbox`) comes from `_sourceBboxUpdate` (`_sourceBboxUpdate`)
  18272. // method, it exists since first render and are automatically updated
  18273. var spotBbox = end === 'source' ? this.sourceBBox : this.targetBBox;
  18274. var reference;
  18275. if (this._isPoint(referenceSelectorOrPoint)) {
  18276. // Reference was passed as a point, therefore, we're ready to find the sticky point of connection on the source element.
  18277. reference = g.point(referenceSelectorOrPoint);
  18278. } else {
  18279. // Reference was passed as an element, therefore we need to find a point on the reference
  18280. // element boundary closest to the source element.
  18281. // Get the bounding box of the spot relative to the paper viewport. This is necessary
  18282. // in order to follow paper viewport transformations (scale/rotate).
  18283. var referenceBbox = end === 'source' ? this.targetBBox : this.sourceBBox;
  18284. reference = g.rect(referenceBbox).intersectionWithLineFromCenterToPoint(g.rect(spotBbox).center());
  18285. reference = reference || g.rect(referenceBbox).center();
  18286. }
  18287. // If `perpendicularLinks` flag is set on the paper and there are vertices
  18288. // on the link, then try to find a connection point that makes the link perpendicular
  18289. // even though the link won't point to the center of the targeted object.
  18290. if (this.paper.options.perpendicularLinks || this.options.perpendicular) {
  18291. var horizontalLineRect = g.rect(0, reference.y, this.paper.options.width, 1);
  18292. var verticalLineRect = g.rect(reference.x, 0, 1, this.paper.options.height);
  18293. var nearestSide;
  18294. if (horizontalLineRect.intersect(g.rect(spotBbox))) {
  18295. nearestSide = g.rect(spotBbox).sideNearestToPoint(reference);
  18296. switch (nearestSide) {
  18297. case 'left':
  18298. spot = g.point(spotBbox.x, reference.y);
  18299. break;
  18300. case 'right':
  18301. spot = g.point(spotBbox.x + spotBbox.width, reference.y);
  18302. break;
  18303. default:
  18304. spot = g.rect(spotBbox).center();
  18305. break;
  18306. }
  18307. } else if (verticalLineRect.intersect(g.rect(spotBbox))) {
  18308. nearestSide = g.rect(spotBbox).sideNearestToPoint(reference);
  18309. switch (nearestSide) {
  18310. case 'top':
  18311. spot = g.point(reference.x, spotBbox.y);
  18312. break;
  18313. case 'bottom':
  18314. spot = g.point(reference.x, spotBbox.y + spotBbox.height);
  18315. break;
  18316. default:
  18317. spot = g.rect(spotBbox).center();
  18318. break;
  18319. }
  18320. } else {
  18321. // If there is no intersection horizontally or vertically with the object bounding box,
  18322. // then we fall back to the regular situation finding straight line (not perpendicular)
  18323. // between the object and the reference point.
  18324. spot = g.rect(spotBbox).intersectionWithLineFromCenterToPoint(reference);
  18325. spot = spot || g.rect(spotBbox).center();
  18326. }
  18327. } else {
  18328. spot = g.rect(spotBbox).intersectionWithLineFromCenterToPoint(reference);
  18329. spot = spot || g.rect(spotBbox).center();
  18330. }
  18331. }
  18332. return spot;
  18333. },
  18334. _isModel: function(end) {
  18335. return end && end.id;
  18336. },
  18337. _isPoint: function(end) {
  18338. return !this._isModel(end);
  18339. },
  18340. _makeSelector: function(end) {
  18341. var selector = '[model-id="' + end.id + '"]';
  18342. // `port` has a higher precendence over `selector`. This is because the selector to the magnet
  18343. // might change while the name of the port can stay the same.
  18344. if (end.port) {
  18345. selector += ' [port="' + end.port + '"]';
  18346. } else if (end.selector) {
  18347. selector += ' ' + end.selector;
  18348. }
  18349. return selector;
  18350. },
  18351. // Public API
  18352. // ----------
  18353. getConnectionLength: function() {
  18354. return this._V.connection.node.getTotalLength();
  18355. },
  18356. getPointAtLength: function(length) {
  18357. return this._V.connection.node.getPointAtLength(length);
  18358. },
  18359. // Interaction. The controller part.
  18360. // ---------------------------------
  18361. _beforeArrowheadMove: function() {
  18362. this.model.trigger('batch:start');
  18363. this._z = this.model.get('z');
  18364. this.model.set('z', Number.MAX_VALUE);
  18365. // Let the pointer propagate throught the link view elements so that
  18366. // the `evt.target` is another element under the pointer, not the link itself.
  18367. this.el.style.pointerEvents = 'none';
  18368. },
  18369. _afterArrowheadMove: function() {
  18370. if (this._z) {
  18371. this.model.set('z', this._z);
  18372. delete this._z;
  18373. }
  18374. // Put `pointer-events` back to its original value. See `startArrowheadMove()` for explanation.
  18375. // Value `auto` doesn't work in IE9. We force to use `visiblePainted` instead.
  18376. // See `https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events`.
  18377. this.el.style.pointerEvents = 'visiblePainted';
  18378. this.model.trigger('batch:stop');
  18379. },
  18380. _createValidateConnectionArgs: function(arrowhead) {
  18381. // It makes sure the arguments for validateConnection have the following form:
  18382. // (source view, source magnet, target view, target magnet and link view)
  18383. var args = [];
  18384. args[4] = arrowhead;
  18385. args[5] = this;
  18386. var oppositeArrowhead, i = 0, j = 0;
  18387. if (arrowhead === 'source') {
  18388. i = 2;
  18389. oppositeArrowhead = 'target';
  18390. } else {
  18391. j = 2;
  18392. oppositeArrowhead = 'source';
  18393. }
  18394. var end = this.model.get(oppositeArrowhead);
  18395. if (end.id) {
  18396. args[i] = this.paper.findViewByModel(end.id);
  18397. args[i+1] = end.selector && args[i].el.querySelector(end.selector);
  18398. }
  18399. function validateConnectionArgs(cellView, magnet) {
  18400. args[j] = cellView;
  18401. args[j+1] = cellView.el === magnet ? undefined : magnet;
  18402. return args;
  18403. }
  18404. return validateConnectionArgs;
  18405. },
  18406. startArrowheadMove: function(end) {
  18407. // Allow to delegate events from an another view to this linkView in order to trigger arrowhead
  18408. // move without need to click on the actual arrowhead dom element.
  18409. this._action = 'arrowhead-move';
  18410. this._arrowhead = end;
  18411. this._beforeArrowheadMove();
  18412. this._validateConnectionArgs = this._createValidateConnectionArgs(this._arrowhead);
  18413. },
  18414. pointerdown: function(evt, x, y) {
  18415. joint.dia.CellView.prototype.pointerdown.apply(this, arguments);
  18416. this._dx = x;
  18417. this._dy = y;
  18418. if (this.options.interactive === false) return;
  18419. var className = evt.target.getAttribute('class');
  18420. switch (className) {
  18421. case 'marker-vertex':
  18422. this._action = 'vertex-move';
  18423. this._vertexIdx = evt.target.getAttribute('idx');
  18424. break;
  18425. case 'marker-vertex-remove':
  18426. case 'marker-vertex-remove-area':
  18427. this.removeVertex(evt.target.getAttribute('idx'));
  18428. break;
  18429. case 'marker-arrowhead':
  18430. this.startArrowheadMove(evt.target.getAttribute('end'));
  18431. break;
  18432. default:
  18433. var targetParentEvent = evt.target.parentNode.getAttribute('event');
  18434. if (targetParentEvent) {
  18435. // `remove` event is built-in. Other custom events are triggered on the paper.
  18436. if (targetParentEvent === 'remove') {
  18437. this.model.remove();
  18438. } else {
  18439. this.paper.trigger(targetParentEvent, evt, this, x, y);
  18440. }
  18441. } else {
  18442. // Store the index at which the new vertex has just been placed.
  18443. // We'll be update the very same vertex position in `pointermove()`.
  18444. this._vertexIdx = this.addVertex({ x: x, y: y });
  18445. this._action = 'vertex-move';
  18446. }
  18447. }
  18448. },
  18449. pointermove: function(evt, x, y) {
  18450. joint.dia.CellView.prototype.pointermove.apply(this, arguments);
  18451. switch (this._action) {
  18452. case 'vertex-move':
  18453. var vertices = _.clone(this.model.get('vertices'));
  18454. vertices[this._vertexIdx] = { x: x, y: y };
  18455. this.model.set('vertices', vertices);
  18456. break;
  18457. case 'arrowhead-move':
  18458. if (this.paper.options.snapLinks) {
  18459. // checking view in close area of the pointer
  18460. var r = this.paper.options.snapLinks.radius || 50;
  18461. var viewsInArea = this.paper.findViewsInArea({ x: x - r, y: y - r, width: 2 * r, height: 2 * r });
  18462. this._closestView && this._closestView.unhighlight(this._closestEnd.selector);
  18463. this._closestView = this._closestEnd = null;
  18464. var pointer = g.point(x,y);
  18465. var distance, minDistance = Number.MAX_VALUE;
  18466. _.each(viewsInArea, function(view) {
  18467. // skip connecting to the element in case '.': { magnet: false } attribute present
  18468. if (view.el.getAttribute('magnet') !== 'false') {
  18469. // find distance from the center of the model to pointer coordinates
  18470. distance = view.model.getBBox().center().distance(pointer);
  18471. // the connection is looked up in a circle area by `distance < r`
  18472. if (distance < r && distance < minDistance) {
  18473. if (this.paper.options.validateConnection.apply(
  18474. this.paper, this._validateConnectionArgs(view, null)
  18475. )) {
  18476. minDistance = distance;
  18477. this._closestView = view;
  18478. this._closestEnd = { id: view.model.id };
  18479. }
  18480. }
  18481. }
  18482. view.$('[magnet]').each(_.bind(function(index, magnet) {
  18483. var bbox = V(magnet).bbox(false, this.paper.viewport);
  18484. distance = pointer.distance({
  18485. x: bbox.x + bbox.width / 2,
  18486. y: bbox.y + bbox.height / 2
  18487. });
  18488. if (distance < r && distance < minDistance) {
  18489. if (this.paper.options.validateConnection.apply(
  18490. this.paper, this._validateConnectionArgs(view, magnet)
  18491. )) {
  18492. minDistance = distance;
  18493. this._closestView = view;
  18494. this._closestEnd = {
  18495. id: view.model.id,
  18496. selector: view.getSelector(magnet),
  18497. port: magnet.getAttribute('port')
  18498. };
  18499. }
  18500. }
  18501. }, this));
  18502. }, this);
  18503. this._closestView && this._closestView.highlight(this._closestEnd.selector);
  18504. this.model.set(this._arrowhead, this._closestEnd || { x: x, y: y });
  18505. } else {
  18506. // checking views right under the pointer
  18507. // Touchmove event's target is not reflecting the element under the coordinates as mousemove does.
  18508. // It holds the element when a touchstart triggered.
  18509. var target = (evt.type === 'mousemove')
  18510. ? evt.target
  18511. : document.elementFromPoint(evt.clientX, evt.clientY);
  18512. if (this._targetEvent !== target) {
  18513. // Unhighlight the previous view under pointer if there was one.
  18514. this._magnetUnderPointer && this._viewUnderPointer.unhighlight(this._magnetUnderPointer);
  18515. this._viewUnderPointer = this.paper.findView(target);
  18516. if (this._viewUnderPointer) {
  18517. // If we found a view that is under the pointer, we need to find the closest
  18518. // magnet based on the real target element of the event.
  18519. this._magnetUnderPointer = this._viewUnderPointer.findMagnet(target);
  18520. if (this._magnetUnderPointer && this.paper.options.validateConnection.apply(
  18521. this.paper,
  18522. this._validateConnectionArgs(this._viewUnderPointer, this._magnetUnderPointer)
  18523. )) {
  18524. // If there was no magnet found, do not highlight anything and assume there
  18525. // is no view under pointer we're interested in reconnecting to.
  18526. // This can only happen if the overall element has the attribute `'.': { magnet: false }`.
  18527. this._magnetUnderPointer && this._viewUnderPointer.highlight(this._magnetUnderPointer);
  18528. } else {
  18529. // This type of connection is not valid. Disregard this magnet.
  18530. this._magnetUnderPointer = null;
  18531. }
  18532. } else {
  18533. // Make sure we'll delete previous magnet
  18534. this._magnetUnderPointer = null;
  18535. }
  18536. }
  18537. this._targetEvent = target;
  18538. this.model.set(this._arrowhead, { x: x, y: y });
  18539. }
  18540. break;
  18541. }
  18542. this._dx = x;
  18543. this._dy = y;
  18544. },
  18545. pointerup: function(evt) {
  18546. joint.dia.CellView.prototype.pointerup.apply(this, arguments);
  18547. if (this._action === 'arrowhead-move') {
  18548. if (this.paper.options.snapLinks) {
  18549. this._closestView && this._closestView.unhighlight(this._closestEnd.selector);
  18550. this._closestView = this._closestEnd = null;
  18551. } else {
  18552. if (this._magnetUnderPointer) {
  18553. this._viewUnderPointer.unhighlight(this._magnetUnderPointer);
  18554. // Find a unique `selector` of the element under pointer that is a magnet. If the
  18555. // `this._magnetUnderPointer` is the root element of the `this._viewUnderPointer` itself,
  18556. // the returned `selector` will be `undefined`. That means we can directly pass it to the
  18557. // `source`/`target` attribute of the link model below.
  18558. this.model.set(this._arrowhead, {
  18559. id: this._viewUnderPointer.model.id,
  18560. selector: this._viewUnderPointer.getSelector(this._magnetUnderPointer),
  18561. port: $(this._magnetUnderPointer).attr('port')
  18562. });
  18563. }
  18564. delete this._viewUnderPointer;
  18565. delete this._magnetUnderPointer;
  18566. delete this._staticView;
  18567. delete this._staticMagnet;
  18568. }
  18569. this._afterArrowheadMove();
  18570. }
  18571. delete this._action;
  18572. }
  18573. });
  18574. if (typeof exports === 'object') {
  18575. module.exports.Link = joint.dia.Link;
  18576. module.exports.LinkView = joint.dia.LinkView;
  18577. }
  18578. // JointJS library.
  18579. // (c) 2011-2013 client IO
  18580. joint.dia.Paper = Backbone.View.extend({
  18581. options: {
  18582. width: 800,
  18583. height: 600,
  18584. gridSize: 50,
  18585. perpendicularLinks: false,
  18586. elementView: joint.dia.ElementView,
  18587. linkView: joint.dia.LinkView,
  18588. snapLinks: false, // false, true, { radius: value }
  18589. // Defines what link model is added to the graph after an user clicks on an active magnet.
  18590. // Value could be the Backbone.model or a function returning the Backbone.model
  18591. // defaultLink: function(elementView, magnet) { return condition ? new customLink1() : new customLink2() }
  18592. defaultLink: new joint.dia.Link,
  18593. // Check whether to add a new link to the graph when user clicks on an a magnet.
  18594. validateMagnet: function(cellView, magnet) {
  18595. return magnet.getAttribute('magnet') !== 'passive';
  18596. },
  18597. // Check whether to allow or disallow the link connection while an arrowhead end (source/target)
  18598. // being changed.
  18599. validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
  18600. return (end === 'target' ? cellViewT : cellViewS) instanceof joint.dia.ElementView;
  18601. }
  18602. },
  18603. events: {
  18604. 'mousedown': 'pointerdown',
  18605. 'dblclick': 'mousedblclick',
  18606. 'click': 'mouseclick',
  18607. 'touchstart': 'pointerdown',
  18608. 'mousemove': 'pointermove',
  18609. 'touchmove': 'pointermove'
  18610. },
  18611. initialize: function() {
  18612. _.bindAll(this, 'addCell', 'sortCells', 'resetCells', 'pointerup');
  18613. this.svg = V('svg').node;
  18614. this.viewport = V('g').node;
  18615. // Append `<defs>` element to the SVG document. This is useful for filters and gradients.
  18616. V(this.svg).append(V('defs').node);
  18617. V(this.viewport).attr({ 'class': 'viewport' });
  18618. V(this.svg).append(this.viewport);
  18619. this.$el.append(this.svg);
  18620. this.setDimensions();
  18621. this.listenTo(this.model, 'add', this.addCell);
  18622. this.listenTo(this.model, 'reset', this.resetCells);
  18623. this.listenTo(this.model, 'sort', this.sortCells);
  18624. $(document).on('mouseup touchend', this.pointerup);
  18625. // Hold the value when mouse has been moved: when mouse moved, no click event will be triggered.
  18626. this._mousemoved = false;
  18627. },
  18628. remove: function() {
  18629. $(document).off('mouseup touchend', this.pointerup);
  18630. Backbone.View.prototype.remove.call(this);
  18631. },
  18632. setDimensions: function(width, height) {
  18633. if (width) this.options.width = width;
  18634. if (height) this.options.height = height;
  18635. V(this.svg).attr('width', this.options.width);
  18636. V(this.svg).attr('height', this.options.height);
  18637. this.trigger('resize');
  18638. },
  18639. // Expand/shrink the paper to fit the content. Snap the width/height to the grid
  18640. // defined in `gridWidth`, `gridHeight`. `padding` adds to the resulting width/height of the paper.
  18641. fitToContent: function(gridWidth, gridHeight, padding) {
  18642. gridWidth = gridWidth || 1;
  18643. gridHeight = gridHeight || 1;
  18644. padding = padding || 0;
  18645. // Calculate the paper size to accomodate all the graph's elements.
  18646. var bbox = V(this.viewport).bbox(true, this.svg);
  18647. var calcWidth = Math.ceil((bbox.width + bbox.x) / gridWidth) * gridWidth;
  18648. var calcHeight = Math.ceil((bbox.height + bbox.y) / gridHeight) * gridHeight;
  18649. calcWidth += padding;
  18650. calcHeight += padding;
  18651. // Change the dimensions only if there is a size discrepency
  18652. if (calcWidth != this.options.width || calcHeight != this.options.height) {
  18653. this.setDimensions(calcWidth || this.options.width , calcHeight || this.options.height);
  18654. }
  18655. },
  18656. getContentBBox: function() {
  18657. var crect = this.viewport.getBoundingClientRect();
  18658. // Using Screen CTM was the only way to get the real viewport bounding box working in both
  18659. // Google Chrome and Firefox.
  18660. var ctm = this.viewport.getScreenCTM();
  18661. var bbox = g.rect(Math.abs(crect.left - ctm.e), Math.abs(crect.top - ctm.f), crect.width, crect.height);
  18662. return bbox;
  18663. },
  18664. createViewForModel: function(cell) {
  18665. var view;
  18666. var type = cell.get('type');
  18667. var module = type.split('.')[0];
  18668. var entity = type.split('.')[1];
  18669. // If there is a special view defined for this model, use that one instead of the default `elementView`/`linkView`.
  18670. if (joint.shapes[module] && joint.shapes[module][entity + 'View']) {
  18671. view = new joint.shapes[module][entity + 'View']({ model: cell, interactive: this.options.interactive });
  18672. } else if (cell instanceof joint.dia.Element) {
  18673. view = new this.options.elementView({ model: cell, interactive: this.options.interactive });
  18674. } else {
  18675. view = new this.options.linkView({ model: cell, interactive: this.options.interactive });
  18676. }
  18677. return view;
  18678. },
  18679. addCell: function(cell) {
  18680. var view = this.createViewForModel(cell);
  18681. V(this.viewport).append(view.el);
  18682. view.paper = this;
  18683. view.render();
  18684. // This is the only way to prevent image dragging in Firefox that works.
  18685. // Setting -moz-user-select: none, draggable="false" attribute or user-drag: none didn't help.
  18686. $(view.el).find('image').on('dragstart', function() { return false; });
  18687. },
  18688. resetCells: function(cellsCollection) {
  18689. $(this.viewport).empty();
  18690. var cells = cellsCollection.models.slice();
  18691. // Make sure links are always added AFTER elements.
  18692. // They wouldn't find their sources/targets in the DOM otherwise.
  18693. cells.sort(function(a, b) { return a instanceof joint.dia.Link ? 1 : -1; });
  18694. _.each(cells, this.addCell, this);
  18695. // Sort the cells in the DOM manually as we might have changed the order they
  18696. // were added to the DOM (see above).
  18697. this.sortCells();
  18698. },
  18699. sortCells: function() {
  18700. // Run insertion sort algorithm in order to efficiently sort DOM elements according to their
  18701. // associated model `z` attribute.
  18702. var $cells = $(this.viewport).children('[model-id]');
  18703. var cells = this.model.get('cells');
  18704. this.sortElements($cells, function(a, b) {
  18705. var cellA = cells.get($(a).attr('model-id'));
  18706. var cellB = cells.get($(b).attr('model-id'));
  18707. return (cellA.get('z') || 0) > (cellB.get('z') || 0) ? 1 : -1;
  18708. });
  18709. },
  18710. // Highly inspired by the jquery.sortElements plugin by Padolsey.
  18711. // See http://james.padolsey.com/javascript/sorting-elements-with-jquery/.
  18712. sortElements: function(elements, comparator) {
  18713. var $elements = $(elements);
  18714. var placements = $elements.map(function() {
  18715. var sortElement = this;
  18716. var parentNode = sortElement.parentNode;
  18717. // Since the element itself will change position, we have
  18718. // to have some way of storing it's original position in
  18719. // the DOM. The easiest way is to have a 'flag' node:
  18720. var nextSibling = parentNode.insertBefore(
  18721. document.createTextNode(''),
  18722. sortElement.nextSibling
  18723. );
  18724. return function() {
  18725. if (parentNode === this) {
  18726. throw new Error(
  18727. "You can't sort elements if any one is a descendant of another."
  18728. );
  18729. }
  18730. // Insert before flag:
  18731. parentNode.insertBefore(this, nextSibling);
  18732. // Remove flag:
  18733. parentNode.removeChild(nextSibling);
  18734. };
  18735. });
  18736. return Array.prototype.sort.call($elements, comparator).each(function(i) {
  18737. placements[i].call(this);
  18738. });
  18739. },
  18740. scale: function(sx, sy, ox, oy) {
  18741. if (!ox) {
  18742. ox = 0;
  18743. oy = 0;
  18744. }
  18745. // Remove previous transform so that the new scale is not affected by previous scales, especially
  18746. // the old translate() does not affect the new translate if an origin is specified.
  18747. V(this.viewport).attr('transform', '');
  18748. // TODO: V.scale() doesn't support setting scale origin. #Fix
  18749. if (ox || oy) {
  18750. V(this.viewport).translate(-ox * (sx - 1), -oy * (sy - 1));
  18751. }
  18752. V(this.viewport).scale(sx, sy);
  18753. this.trigger('scale', ox, oy);
  18754. return this;
  18755. },
  18756. rotate: function(deg, ox, oy) {
  18757. // If the origin is not set explicitely, rotate around the center. Note that
  18758. // we must use the plain bounding box (`this.el.getBBox()` instead of the one that gives us
  18759. // the real bounding box (`bbox()`) including transformations).
  18760. if (_.isUndefined(ox)) {
  18761. var bbox = this.viewport.getBBox();
  18762. ox = bbox.width/2;
  18763. oy = bbox.height/2;
  18764. }
  18765. V(this.viewport).rotate(deg, ox, oy);
  18766. },
  18767. // Find the first view climbing up the DOM tree starting at element `el`. Note that `el` can also
  18768. // be a selector or a jQuery object.
  18769. findView: function(el) {
  18770. var $el = this.$(el);
  18771. if ($el.length === 0 || $el[0] === this.el) {
  18772. return undefined;
  18773. }
  18774. if ($el.data('view')) {
  18775. return $el.data('view');
  18776. }
  18777. return this.findView($el.parent());
  18778. },
  18779. // Find a view for a model `cell`. `cell` can also be a string representing a model `id`.
  18780. findViewByModel: function(cell) {
  18781. var id = _.isString(cell) ? cell : cell.id;
  18782. var $view = this.$('[model-id="' + id + '"]');
  18783. if ($view.length) {
  18784. return $view.data('view');
  18785. }
  18786. return undefined;
  18787. },
  18788. // Find all views at given point
  18789. findViewsFromPoint: function(p) {
  18790. p = g.point(p);
  18791. var views = _.map(this.model.getElements(), this.findViewByModel);
  18792. return _.filter(views, function(view) {
  18793. return g.rect(V(view.el).bbox(false, this.viewport)).containsPoint(p);
  18794. }, this);
  18795. },
  18796. // Find all views in given area
  18797. findViewsInArea: function(r) {
  18798. r = g.rect(r);
  18799. var views = _.map(this.model.getElements(), this.findViewByModel);
  18800. return _.filter(views, function(view) {
  18801. return r.intersect(g.rect(V(view.el).bbox(false, this.viewport)));
  18802. }, this);
  18803. },
  18804. getModelById: function(id) {
  18805. return this.model.getCell(id);
  18806. },
  18807. snapToGrid: function(p) {
  18808. // Convert global coordinates to the local ones of the `viewport`. Otherwise,
  18809. // improper transformation would be applied when the viewport gets transformed (scaled/rotated).
  18810. var localPoint = V(this.viewport).toLocalPoint(p.x, p.y);
  18811. return {
  18812. x: g.snapToGrid(localPoint.x, this.options.gridSize),
  18813. y: g.snapToGrid(localPoint.y, this.options.gridSize)
  18814. };
  18815. },
  18816. getDefaultLink: function(cellView, magnet) {
  18817. return _.isFunction(this.options.defaultLink)
  18818. // default link is a function producing link model
  18819. ? this.options.defaultLink.call(this, cellView, magnet)
  18820. // default link is the Backbone model
  18821. : this.options.defaultLink.clone();
  18822. },
  18823. // Interaction.
  18824. // ------------
  18825. mousedblclick: function(evt) {
  18826. evt.preventDefault();
  18827. evt = joint.util.normalizeEvent(evt);
  18828. var view = this.findView(evt.target);
  18829. var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
  18830. if (view) {
  18831. view.pointerdblclick(evt, localPoint.x, localPoint.y);
  18832. } else {
  18833. this.trigger('blank:pointerdblclick', evt, localPoint.x, localPoint.y);
  18834. }
  18835. },
  18836. mouseclick: function(evt) {
  18837. // Trigger event when mouse not moved.
  18838. if (!this._mousemoved) {
  18839. evt.preventDefault();
  18840. evt = joint.util.normalizeEvent(evt);
  18841. var view = this.findView(evt.target);
  18842. var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
  18843. if (view) {
  18844. view.pointerclick(evt, localPoint.x, localPoint.y);
  18845. } else {
  18846. this.trigger('blank:pointerclick', evt, localPoint.x, localPoint.y);
  18847. }
  18848. }
  18849. this._mousemoved = false;
  18850. },
  18851. pointerdown: function(evt) {
  18852. evt.preventDefault();
  18853. evt = joint.util.normalizeEvent(evt);
  18854. var view = this.findView(evt.target);
  18855. var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
  18856. if (view) {
  18857. this.sourceView = view;
  18858. view.pointerdown(evt, localPoint.x, localPoint.y);
  18859. } else {
  18860. this.trigger('blank:pointerdown', evt, localPoint.x, localPoint.y);
  18861. }
  18862. },
  18863. pointermove: function(evt) {
  18864. evt.preventDefault();
  18865. evt = joint.util.normalizeEvent(evt);
  18866. if (this.sourceView) {
  18867. // Mouse moved.
  18868. this._mousemoved = true;
  18869. var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
  18870. this.sourceView.pointermove(evt, localPoint.x, localPoint.y);
  18871. }
  18872. },
  18873. pointerup: function(evt) {
  18874. evt = joint.util.normalizeEvent(evt);
  18875. var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
  18876. if (this.sourceView) {
  18877. this.sourceView.pointerup(evt, localPoint.x, localPoint.y);
  18878. //"delete sourceView" occasionally throws an error in chrome (illegal access exception)
  18879. this.sourceView = null;
  18880. } else {
  18881. this.trigger('blank:pointerup', evt, localPoint.x, localPoint.y);
  18882. }
  18883. }
  18884. });
  18885. // JointJS library.
  18886. // (c) 2011-2013 client IO
  18887. if (typeof exports === 'object') {
  18888. var joint = {
  18889. util: require('../src/core').util,
  18890. shapes: {},
  18891. dia: {
  18892. Element: require('../src/joint.dia.element').Element,
  18893. ElementView: require('../src/joint.dia.element').ElementView
  18894. }
  18895. };
  18896. var _ = require('lodash');
  18897. }
  18898. joint.shapes.basic = {};
  18899. joint.shapes.basic.Generic = joint.dia.Element.extend({
  18900. defaults: joint.util.deepSupplement({
  18901. type: 'basic.Generic',
  18902. attrs: {
  18903. '.': { fill: '#FFFFFF', stroke: 'none' }
  18904. }
  18905. }, joint.dia.Element.prototype.defaults)
  18906. });
  18907. joint.shapes.basic.Rect = joint.shapes.basic.Generic.extend({
  18908. markup: '<g class="rotatable"><g class="scalable"><rect/></g><text/></g>',
  18909. defaults: joint.util.deepSupplement({
  18910. type: 'basic.Rect',
  18911. attrs: {
  18912. 'rect': { fill: '#FFFFFF', stroke: 'black', width: 100, height: 60 },
  18913. 'text': { 'font-size': 14, text: '', 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'y-alignment': 'middle', 'x-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
  18914. }
  18915. }, joint.shapes.basic.Generic.prototype.defaults)
  18916. });
  18917. joint.shapes.basic.Text = joint.shapes.basic.Generic.extend({
  18918. markup: '<g class="rotatable"><g class="scalable"><text/></g></g>',
  18919. defaults: joint.util.deepSupplement({
  18920. type: 'basic.Text',
  18921. attrs: {
  18922. 'text': { 'font-size': 18, fill: 'black' }
  18923. }
  18924. }, joint.shapes.basic.Generic.prototype.defaults)
  18925. });
  18926. joint.shapes.basic.Circle = joint.shapes.basic.Generic.extend({
  18927. markup: '<g class="rotatable"><g class="scalable"><circle/></g><text/></g>',
  18928. defaults: joint.util.deepSupplement({
  18929. type: 'basic.Circle',
  18930. size: { width: 60, height: 60 },
  18931. attrs: {
  18932. 'circle': { fill: '#FFFFFF', stroke: 'black', r: 30, transform: 'translate(30, 30)' },
  18933. 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, ref: 'circle', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
  18934. }
  18935. }, joint.shapes.basic.Generic.prototype.defaults)
  18936. });
  18937. joint.shapes.basic.Image = joint.shapes.basic.Generic.extend({
  18938. markup: '<g class="rotatable"><g class="scalable"><image/></g><text/></g>',
  18939. defaults: joint.util.deepSupplement({
  18940. type: 'basic.Image',
  18941. attrs: {
  18942. 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'image', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
  18943. }
  18944. }, joint.shapes.basic.Generic.prototype.defaults)
  18945. });
  18946. joint.shapes.basic.Path = joint.shapes.basic.Generic.extend({
  18947. markup: '<g class="rotatable"><g class="scalable"><path/></g><text/></g>',
  18948. defaults: joint.util.deepSupplement({
  18949. type: 'basic.Path',
  18950. size: { width: 60, height: 60 },
  18951. attrs: {
  18952. 'path': { fill: '#FFFFFF', stroke: 'black' },
  18953. 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'path', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
  18954. }
  18955. }, joint.shapes.basic.Generic.prototype.defaults)
  18956. });
  18957. // PortsModelInterface is a common interface for shapes that have ports. This interface makes it easy
  18958. // to create new shapes with ports functionality. It is assumed that the new shapes have
  18959. // `inPorts` and `outPorts` array properties. Only these properties should be used to set ports.
  18960. // In other words, using this interface, it is no longer recommended to set ports directly through the
  18961. // `attrs` object.
  18962. // Usage:
  18963. // joint.shapes.custom.MyElementWithPorts = joint.shapes.basic.Path.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
  18964. // getPortAttrs: function(portName, index, total, selector, type) {
  18965. // var attrs = {};
  18966. // var portClass = 'port' + index;
  18967. // var portSelector = selector + '>.' + portClass;
  18968. // var portTextSelector = portSelector + '>text';
  18969. // var portCircleSelector = portSelector + '>circle';
  18970. //
  18971. // attrs[portTextSelector] = { text: portName };
  18972. // attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type) , type: type } };
  18973. // attrs[portSelector] = { ref: 'rect', 'ref-y': (index + 0.5) * (1 / total) };
  18974. //
  18975. // if (selector === '.outPorts') { attrs[portSelector]['ref-dx'] = 0; }
  18976. //
  18977. // return attrs;
  18978. // }
  18979. //}));
  18980. joint.shapes.basic.PortsModelInterface = {
  18981. initialize: function() {
  18982. this.updatePortsAttrs();
  18983. this.on('change:inPorts change:outPorts', this.updatePortsAttrs, this);
  18984. // Call the `initialize()` of the parent.
  18985. this.constructor.__super__.constructor.__super__.initialize.apply(this, arguments);
  18986. },
  18987. updatePortsAttrs: function(eventName) {
  18988. // Delete previously set attributes for ports.
  18989. var currAttrs = this.get('attrs');
  18990. _.each(this._portSelectors, function(selector) {
  18991. if (currAttrs[selector]) delete currAttrs[selector];
  18992. });
  18993. // This holds keys to the `attrs` object for all the port specific attribute that
  18994. // we set in this method. This is necessary in order to remove previously set
  18995. // attributes for previous ports.
  18996. this._portSelectors = [];
  18997. var attrs = {};
  18998. _.each(this.get('inPorts'), function(portName, index, ports) {
  18999. var portAttributes = this.getPortAttrs(portName, index, ports.length, '.inPorts', 'in');
  19000. this._portSelectors = this._portSelectors.concat(_.keys(portAttributes));
  19001. _.extend(attrs, portAttributes);
  19002. }, this);
  19003. _.each(this.get('outPorts'), function(portName, index, ports) {
  19004. var portAttributes = this.getPortAttrs(portName, index, ports.length, '.outPorts', 'out');
  19005. this._portSelectors = this._portSelectors.concat(_.keys(portAttributes));
  19006. _.extend(attrs, portAttributes);
  19007. }, this);
  19008. // Silently set `attrs` on the cell so that noone knows the attrs have changed. This makes sure
  19009. // that, for example, command manager does not register `change:attrs` command but only
  19010. // the important `change:inPorts`/`change:outPorts` command.
  19011. this.attr(attrs, { silent: true });
  19012. // Manually call the `processPorts()` method that is normally called on `change:attrs` (that we just made silent).
  19013. this.processPorts();
  19014. // Let the outside world (mainly the `ModelView`) know that we're done configuring the `attrs` object.
  19015. this.trigger('process:ports');
  19016. },
  19017. getPortSelector: function(name) {
  19018. var selector = '.inPorts';
  19019. var index = this.get('inPorts').indexOf(name);
  19020. if (index < 0) {
  19021. selector = '.outPorts';
  19022. index = this.get('outPorts').indexOf(name);
  19023. if (index < 0) throw new Error("getPortSelector(): Port doesn't exist.");
  19024. }
  19025. return selector + '>g:nth-child(' + (index + 1) + ')>circle';
  19026. }
  19027. };
  19028. joint.shapes.basic.PortsViewInterface = {
  19029. initialize: function() {
  19030. // `Model` emits the `process:ports` whenever it's done configuring the `attrs` object for ports.
  19031. this.listenTo(this.model, 'process:ports', this.update);
  19032. joint.dia.ElementView.prototype.initialize.apply(this, arguments);
  19033. },
  19034. update: function() {
  19035. // First render ports so that `attrs` can be applied to those newly created DOM elements
  19036. // in `ElementView.prototype.update()`.
  19037. this.renderPorts();
  19038. joint.dia.ElementView.prototype.update.apply(this, arguments);
  19039. },
  19040. renderPorts: function() {
  19041. var $inPorts = this.$('.inPorts').empty();
  19042. var $outPorts = this.$('.outPorts').empty();
  19043. var portTemplate = _.template(this.model.portMarkup);
  19044. _.each(_.filter(this.model.ports, function(p) { return p.type === 'in' }), function(port, index) {
  19045. $inPorts.append(V(portTemplate({ id: index, port: port })).node);
  19046. });
  19047. _.each(_.filter(this.model.ports, function(p) { return p.type === 'out' }), function(port, index) {
  19048. $outPorts.append(V(portTemplate({ id: index, port: port })).node);
  19049. });
  19050. }
  19051. };
  19052. joint.shapes.basic.TextBlock = joint.shapes.basic.Generic.extend({
  19053. markup: ['<g class="rotatable"><g class="scalable"><rect/></g><switch>',
  19054. // if foreignObject supported
  19055. '<foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" class="fobj">',
  19056. '<body xmlns="http://www.w3.org/1999/xhtml"><div/></body>',
  19057. '</foreignObject>',
  19058. // else foreignObject is not supported (fallback for IE)
  19059. '<text class="content"/>',
  19060. '</switch></g>'].join(''),
  19061. defaults: joint.util.deepSupplement({
  19062. type: 'basic.TextBlock',
  19063. // see joint.css for more element styles
  19064. attrs: {
  19065. rect: {
  19066. fill: '#ffffff',
  19067. stroke: '#000000',
  19068. width: 80,
  19069. height: 100
  19070. },
  19071. text: {
  19072. fill: '#000000',
  19073. 'font-size': 14,
  19074. 'font-family': 'Arial, helvetica, sans-serif'
  19075. },
  19076. '.content': {
  19077. text: '',
  19078. ref: 'rect',
  19079. 'ref-x': .5,
  19080. 'ref-y': .5,
  19081. 'y-alignment': 'middle',
  19082. 'x-alignment': 'middle'
  19083. }
  19084. },
  19085. content: ''
  19086. }, joint.shapes.basic.Generic.prototype.defaults),
  19087. initialize: function() {
  19088. if (typeof SVGForeignObjectElement !== 'undefined') {
  19089. // foreignObject supported
  19090. this.setForeignObjectSize(this, this.get('size'));
  19091. this.setDivContent(this, this.get('content'));
  19092. this.listenTo(this, 'change:size', this.setForeignObjectSize);
  19093. this.listenTo(this, 'change:content', this.setDivContent);
  19094. }
  19095. joint.shapes.basic.Generic.prototype.initialize.apply(this, arguments);
  19096. },
  19097. setForeignObjectSize: function(cell, size) {
  19098. // Selector `foreignObject' doesn't work accross all browsers, we'r using class selector instead.
  19099. // We have to clone size as we don't want attributes.div.style to be same object as attributes.size.
  19100. cell.attr({
  19101. '.fobj': _.clone(size),
  19102. div: { style: _.clone(size) }
  19103. });
  19104. },
  19105. setDivContent: function(cell, content) {
  19106. // Append the content to div as html.
  19107. cell.attr({ div : {
  19108. html: content
  19109. }});
  19110. }
  19111. });
  19112. // TextBlockView implements the fallback for IE when no foreignObject exists and
  19113. // the text needs to be manually broken.
  19114. joint.shapes.basic.TextBlockView = joint.dia.ElementView.extend({
  19115. initialize: function() {
  19116. joint.dia.ElementView.prototype.initialize.apply(this, arguments);
  19117. if (typeof SVGForeignObjectElement === 'undefined') {
  19118. this.noSVGForeignObjectElement = true;
  19119. this.listenTo(this.model, 'change:content', function(cell) {
  19120. // avoiding pass of extra paramters
  19121. this.updateContent(cell);
  19122. });
  19123. }
  19124. },
  19125. update: function(cell, renderingOnlyAttrs) {
  19126. if (this.noSVGForeignObjectElement) {
  19127. var model = this.model;
  19128. // Update everything but the content first.
  19129. var noTextAttrs = _.omit(renderingOnlyAttrs || model.get('attrs'), '.content');
  19130. joint.dia.ElementView.prototype.update.call(this, model, noTextAttrs);
  19131. if (!renderingOnlyAttrs || _.has(renderingOnlyAttrs, '.content')) {
  19132. // Update the content itself.
  19133. this.updateContent(model, renderingOnlyAttrs);
  19134. }
  19135. } else {
  19136. joint.dia.ElementView.prototype.update.call(this, model, renderingOnlyAttrs);
  19137. }
  19138. },
  19139. updateContent: function(cell, renderingOnlyAttrs) {
  19140. // Create copy of the text attributes
  19141. var textAttrs = _.merge({}, (renderingOnlyAttrs || cell.get('attrs'))['.content']);
  19142. delete textAttrs.text;
  19143. // Break the content to fit the element size taking into account the attributes
  19144. // set on the model.
  19145. var text = joint.util.breakText(cell.get('content'), cell.get('size'), textAttrs, {
  19146. // measuring sandbox svg document
  19147. svgDocument: this.paper.svg
  19148. });
  19149. // Create a new attrs with same structure as the model attrs { text: { *textAttributes* }}
  19150. var attrs = joint.util.setByPath({}, '.content', textAttrs,'/');
  19151. // Replace text attribute with the one we just processed.
  19152. attrs['.content'].text = text;
  19153. // Update the view using renderingOnlyAttributes parameter.
  19154. joint.dia.ElementView.prototype.update.call(this, cell, attrs);
  19155. }
  19156. });
  19157. if (typeof exports === 'object') {
  19158. module.exports = joint.shapes.basic;
  19159. }
  19160. joint.routers.orthogonal = function() {
  19161. var sourceBBox, targetBBox;
  19162. // Return the direction that one would have to take traveling from `p1` to `p2`.
  19163. // This function assumes the line between `p1` and `p2` is orthogonal.
  19164. function direction(p1, p2) {
  19165. if (p1.y < p2.y && p1.x === p2.x) {
  19166. return 'down';
  19167. } else if (p1.y > p2.y && p1.x === p2.x) {
  19168. return 'up';
  19169. } else if (p1.x < p2.x && p1.y === p2.y) {
  19170. return 'right';
  19171. }
  19172. return 'left';
  19173. }
  19174. function bestDirection(p1, p2, preferredDirection) {
  19175. var directions;
  19176. // This branching determines possible directions that one can take to travel
  19177. // from `p1` to `p2`.
  19178. if (p1.x < p2.x) {
  19179. if (p1.y > p2.y) { directions = ['up', 'right']; }
  19180. else if (p1.y < p2.y) { directions = ['down', 'right']; }
  19181. else { directions = ['right']; }
  19182. } else if (p1.x > p2.x) {
  19183. if (p1.y > p2.y) { directions = ['up', 'left']; }
  19184. else if (p1.y < p2.y) { directions = ['down', 'left']; }
  19185. else { directions = ['left']; }
  19186. } else {
  19187. if (p1.y > p2.y) { directions = ['up']; }
  19188. else { directions = ['down']; }
  19189. }
  19190. if (_.contains(directions, preferredDirection)) {
  19191. return preferredDirection;
  19192. }
  19193. var direction = _.first(directions);
  19194. // Should the direction be the exact opposite of the preferred direction,
  19195. // try another one if such direction exists.
  19196. switch (preferredDirection) {
  19197. case 'down': if (direction === 'up') return _.last(directions); break;
  19198. case 'up': if (direction === 'down') return _.last(directions); break;
  19199. case 'left': if (direction === 'right') return _.last(directions); break;
  19200. case 'right': if (direction === 'left') return _.last(directions); break;
  19201. }
  19202. return direction;
  19203. };
  19204. // Find a vertex in between the vertices `p1` and `p2` so that the route between those vertices
  19205. // is orthogonal. Prefer going the direction determined by `preferredDirection`.
  19206. function findMiddleVertex(p1, p2, preferredDirection) {
  19207. var direction = bestDirection(p1, p2, preferredDirection);
  19208. if (direction === 'down' || direction === 'up') {
  19209. return { x: p1.x, y: p2.y, d: direction };
  19210. }
  19211. return { x: p2.x, y: p1.y, d: direction };
  19212. }
  19213. // Return points that one needs to draw a connection through in order to have a orthogonal link
  19214. // routing from source to target going through `vertices`.
  19215. function findOrthogonalRoute(vertices) {
  19216. vertices = (vertices || []).slice();
  19217. var orthogonalVertices = [];
  19218. var sourceCenter = sourceBBox.center();
  19219. var targetCenter = targetBBox.center();
  19220. if (!vertices.length) {
  19221. if (Math.abs(sourceCenter.x - targetCenter.x) < (sourceBBox.width / 2) ||
  19222. Math.abs(sourceCenter.y - targetCenter.y) < (sourceBBox.height / 2)
  19223. ) {
  19224. vertices = [{
  19225. x: Math.min(sourceCenter.x, targetCenter.x) +
  19226. Math.abs(sourceCenter.x - targetCenter.x) / 2,
  19227. y: Math.min(sourceCenter.y, targetCenter.y) +
  19228. Math.abs(sourceCenter.y - targetCenter.y) / 2
  19229. }];
  19230. }
  19231. }
  19232. vertices.unshift(sourceCenter);
  19233. vertices.push(targetCenter);
  19234. var orthogonalVertex;
  19235. var lastOrthogonalVertex;
  19236. var vertex;
  19237. var nextVertex;
  19238. // For all the pairs of link model vertices...
  19239. for (var i = 0; i < vertices.length - 1; i++) {
  19240. vertex = vertices[i];
  19241. nextVertex = vertices[i + 1];
  19242. lastOrthogonalVertex = _.last(orthogonalVertices);
  19243. if (i > 0) {
  19244. // Push all the link vertices to the orthogonal route.
  19245. orthogonalVertex = vertex;
  19246. // Determine a direction between the last vertex and the new one.
  19247. // Therefore, each vertex contains the `d` property describing the direction that one
  19248. // would have to take to travel to that vertex.
  19249. orthogonalVertex.d = lastOrthogonalVertex
  19250. ? direction(lastOrthogonalVertex, vertex)
  19251. : 'top';
  19252. orthogonalVertices.push(orthogonalVertex);
  19253. lastOrthogonalVertex = orthogonalVertex;
  19254. }
  19255. // Make sure that we don't create a vertex that would go the opposite direction then
  19256. // that of the previous one.
  19257. // Othwerwise, a 'spike' segment would be created which is not desirable.
  19258. // Find a dummy vertex to keep the link orthogonal. Preferably, take the same direction
  19259. // as the previous one.
  19260. var d = lastOrthogonalVertex && lastOrthogonalVertex.d;
  19261. orthogonalVertex = findMiddleVertex(vertex, nextVertex, d);
  19262. // Do not add a new vertex that is the same as one of the vertices already added.
  19263. if (!g.point(orthogonalVertex).equals(g.point(vertex)) &&
  19264. !g.point(orthogonalVertex).equals(g.point(nextVertex))) {
  19265. orthogonalVertices.push(orthogonalVertex);
  19266. }
  19267. }
  19268. return orthogonalVertices;
  19269. };
  19270. return function(vertices) {
  19271. sourceBBox = this.sourceBBox;
  19272. targetBBox = this.targetBBox;
  19273. return findOrthogonalRoute(vertices);
  19274. };
  19275. }();
  19276. joint.routers.manhattan = (function() {
  19277. 'use strict';
  19278. var config = {
  19279. // size of the step to find a route
  19280. step: 10,
  19281. // use of the perpendicular linkView option to connect center of element with first vertex
  19282. perpendicular: true,
  19283. // tells how to divide the paper when creating the elements map
  19284. mapGridSize: 100,
  19285. // should be source or target not to be consider as an obstacle
  19286. excludeEnds: [], // 'source', 'target'
  19287. // should be any element with a certain type not to be consider as an obstacle
  19288. excludeTypes: ['basic.Text'],
  19289. // if number of route finding loops exceed the maximum, stops searching and returns
  19290. // fallback route
  19291. maximumLoops: 500,
  19292. // possible starting directions from an element
  19293. startDirections: ['left','right','top','bottom'],
  19294. // possible ending directions to an element
  19295. endDirections: ['left','right','top','bottom'],
  19296. // specify directions above
  19297. directionMap: {
  19298. right: { x: 1, y: 0 },
  19299. bottom: { x: 0, y: 1 },
  19300. left: { x: -1, y: 0 },
  19301. top: { x: 0, y: -1 }
  19302. },
  19303. // maximum change of the direction
  19304. maxAllowedDirectionChange: 1,
  19305. // padding applied on the element bounding boxes
  19306. paddingBox: function() {
  19307. var step = this.step;
  19308. return {
  19309. x: -step,
  19310. y: -step,
  19311. width: 2*step,
  19312. height: 2*step
  19313. }
  19314. },
  19315. // an array of directions to find next points on the route
  19316. directions: function() {
  19317. var step = this.step;
  19318. return [
  19319. { offsetX: step , offsetY: 0 , cost: step },
  19320. { offsetX: 0 , offsetY: step , cost: step },
  19321. { offsetX: -step , offsetY: 0 , cost: step },
  19322. { offsetX: 0 , offsetY: -step , cost: step }
  19323. ];
  19324. },
  19325. // a penalty received for direction change
  19326. penalties: function() {
  19327. return [0, this.step / 2, this.step];
  19328. },
  19329. // heurestic method to determine the distance between two points
  19330. estimateCost: function(from, to) {
  19331. return from.manhattanDistance(to);
  19332. },
  19333. // a simple route used in situations, when main routing method fails
  19334. // (exceed loops, inaccessible).
  19335. fallbackRoute: function(from, to, opts) {
  19336. // Find an orthogonal route ignoring obstacles.
  19337. var prevDirIndexes = opts.prevDirIndexes || {};
  19338. var point = (prevDirIndexes[from] || 0) % 2
  19339. ? g.point(from.x, to.y)
  19340. : g.point(to.x, from.y);
  19341. return [point, to];
  19342. },
  19343. // if a function is provided, it's used to route the link while dragging an end
  19344. // i.e. function(from, to, opts) { return []; }
  19345. draggingRoute: null
  19346. };
  19347. // reconstructs a route by concating points with their parents
  19348. function reconstructRoute(parents, point) {
  19349. var route = [];
  19350. var prevDiff = { x: 0, y: 0 };
  19351. var current = point;
  19352. var parent;
  19353. while ((parent = parents[current])) {
  19354. var diff = parent.difference(current);
  19355. if (!diff.equals(prevDiff)) {
  19356. route.unshift(current);
  19357. prevDiff = diff;
  19358. }
  19359. current = parent;
  19360. }
  19361. route.unshift(current);
  19362. return route;
  19363. };
  19364. // find points around the rectangle taking given directions in the account
  19365. function getRectPoints(bbox, directionList, opts) {
  19366. var step = opts.step;
  19367. var center = bbox.center();
  19368. var startPoints = _.chain(opts.directionMap).pick(directionList).map(function(direction) {
  19369. var x = direction.x * bbox.width / 2;
  19370. var y = direction.y * bbox.height / 2;
  19371. var point = g.point(center).offset(x,y).snapToGrid(step);
  19372. if (bbox.containsPoint(point)) {
  19373. point.offset(direction.x * step, direction.y * step);
  19374. }
  19375. return point;
  19376. }).value();
  19377. return startPoints;
  19378. };
  19379. // returns a direction index from start point to end point
  19380. function getDirection(start, end, dirLen) {
  19381. var dirAngle = 360 / dirLen;
  19382. var q = Math.floor(start.theta(end) / dirAngle);
  19383. return dirLen - q;
  19384. }
  19385. // finds the route between to points/rectangles implementing A* alghoritm
  19386. function findRoute(start, end, map, opt) {
  19387. var startDirections = opt.reversed ? opt.endDirections : opt.startDirections;
  19388. var endDirections = opt.reversed ? opt.startDirections : opt.endDirections;
  19389. // set of points we start pathfinding from
  19390. var startSet = start instanceof g.rect
  19391. ? getRectPoints(start, startDirections, opt)
  19392. : [start];
  19393. // set of points we want the pathfinding to finish at
  19394. var endSet = end instanceof g.rect
  19395. ? getRectPoints(end, endDirections, opt)
  19396. : [end];
  19397. var startCenter = startSet.length > 1 ? start.center() : startSet[0];
  19398. var endCenter = endSet.length > 1 ? end.center() : endSet[0];
  19399. // take into account only accessible end points
  19400. var endPoints = _.filter(endSet, function(point) {
  19401. var mapKey = g.point(point).snapToGrid(opt.mapGridSize).toString();
  19402. var accesible = _.every(map[mapKey], function(obstacle) {
  19403. return !obstacle.containsPoint(point);
  19404. });
  19405. return accesible;
  19406. });
  19407. if (endPoints.length) {
  19408. var step = opt.step;
  19409. var penalties = opt.penalties;
  19410. // choose the end point with the shortest estimated path cost
  19411. var endPoint = _.chain(endPoints).invoke('snapToGrid', step).min(function(point) {
  19412. return opt.estimateCost(startCenter, point);
  19413. }).value();
  19414. var parents = {};
  19415. var costFromStart = {};
  19416. var totalCost = {};
  19417. // directions
  19418. var dirs = opt.directions;
  19419. var dirLen = dirs.length;
  19420. var dirHalfLen = dirLen / 2;
  19421. var dirIndexes = opt.previousDirIndexes || {};
  19422. // The set of point already evaluated.
  19423. var closeHash = {}; // keeps only information whether a point was evaluated'
  19424. // The set of tentative points to be evaluated, initially containing the start points
  19425. var openHash = {}; // keeps only information whether a point is to be evaluated'
  19426. var openSet = _.chain(startSet).invoke('snapToGrid', step).each(function(point) {
  19427. var key = point.toString();
  19428. costFromStart[key] = 0; // Cost from start along best known path.
  19429. totalCost[key] = opt.estimateCost(point, endPoint);
  19430. dirIndexes[key] = dirIndexes[key] || getDirection(startCenter, point, dirLen);
  19431. openHash[key] = true;
  19432. }).map(function(point) {
  19433. return point.toString();
  19434. }).sortBy(function(pointKey) {
  19435. return totalCost[pointKey];
  19436. }).value();
  19437. var loopCounter = opt.maximumLoops;
  19438. var maxAllowedDirectionChange = opt.maxAllowedDirectionChange;
  19439. // main route finding loop
  19440. while (openSet.length && loopCounter--) {
  19441. var currentKey = openSet[0];
  19442. var currentPoint = g.point(currentKey);
  19443. if (endPoint.equals(currentPoint)) {
  19444. opt.previousDirIndexes = _.pick(dirIndexes, currentKey);
  19445. return reconstructRoute(parents, currentPoint);
  19446. }
  19447. // remove current from the open list
  19448. openSet.splice(0, 1);
  19449. openHash[neighborKey] = null;
  19450. // add current to the close list
  19451. closeHash[neighborKey] = true;
  19452. var currentDirIndex = dirIndexes[currentKey];
  19453. var currentDist = costFromStart[currentKey];
  19454. for (var dirIndex = 0; dirIndex < dirLen; dirIndex++) {
  19455. var dirChange = Math.abs(dirIndex - currentDirIndex);
  19456. if (dirChange > dirHalfLen) {
  19457. dirChange = dirLen - dirChange;
  19458. }
  19459. // if the direction changed rapidly don't use this point
  19460. if (dirChange > maxAllowedDirectionChange) {
  19461. continue;
  19462. }
  19463. var dir = dirs[dirIndex];
  19464. var neighborPoint = g.point(currentPoint).offset(dir.offsetX, dir.offsetY);
  19465. var neighborKey = neighborPoint.toString();
  19466. if (closeHash[neighborKey]) {
  19467. continue;
  19468. }
  19469. // is point accesible - no obstacle in the way
  19470. var mapKey = g.point(neighborPoint).snapToGrid(opt.mapGridSize).toString();
  19471. var isAccesible = _.every(map[mapKey], function(obstacle) {
  19472. return !obstacle.containsPoint(neighborPoint);
  19473. });
  19474. if (!isAccesible) {
  19475. continue;
  19476. }
  19477. var inOpenSet = _.has(openHash, neighborKey);
  19478. var costToNeighbor = currentDist + dir.cost;
  19479. if (!inOpenSet || costToNeighbor < costFromStart[neighborKey]) {
  19480. parents[neighborKey] = currentPoint;
  19481. dirIndexes[neighborKey] = dirIndex;
  19482. costFromStart[neighborKey] = costToNeighbor;
  19483. totalCost[neighborKey] = costToNeighbor +
  19484. opt.estimateCost(neighborPoint, endPoint) +
  19485. penalties[dirChange];
  19486. if (!inOpenSet) {
  19487. var openIndex = _.sortedIndex(openSet, neighborKey, function(openKey) {
  19488. return totalCost[openKey];
  19489. });
  19490. openSet.splice(openIndex, 0, neighborKey);
  19491. openHash[neighborKey] = true;
  19492. }
  19493. };
  19494. };
  19495. }
  19496. }
  19497. // no route found ('to' point wasn't either accessible or finding route took
  19498. // way to much calculations)
  19499. return opt.fallbackRoute(startCenter, endCenter, opt);
  19500. };
  19501. // initiation of the route finding
  19502. function router(oldVertices, opt) {
  19503. // resolve some of the options
  19504. opt.directions = _.result(opt, 'directions');
  19505. opt.penalties = _.result(opt, 'penalties');
  19506. opt.paddingBox = _.result(opt, 'paddingBox');
  19507. // enable/disable linkView perpendicular option
  19508. this.options.perpendicular = !!opt.perpendicular;
  19509. // As route changes its shape rapidly when we start finding route from different point
  19510. // it's necessary to start from the element that was not interacted with
  19511. // (the position was changed) at very last.
  19512. var reverseRouting = opt.reversed = (this.lastEndChange === 'source');
  19513. var sourceBBox = reverseRouting ? g.rect(this.targetBBox) : g.rect(this.sourceBBox);
  19514. var targetBBox = reverseRouting ? g.rect(this.sourceBBox) : g.rect(this.targetBBox);
  19515. // expand boxes by specific padding
  19516. sourceBBox.moveAndExpand(opt.paddingBox);
  19517. targetBBox.moveAndExpand(opt.paddingBox);
  19518. // building an elements map
  19519. var link = this.model;
  19520. var graph = this.paper.model;
  19521. // source or target element could be excluded from set of obstacles
  19522. var excludedEnds = _.chain(opt.excludeEnds)
  19523. .map(link.get, link)
  19524. .pluck('id')
  19525. .map(graph.getCell, graph).value();
  19526. var mapGridSize = opt.mapGridSize;
  19527. // builds a map of all elements for quicker obstacle queries (i.e. is a point contained
  19528. // in any obstacle?) (a simplified grid search)
  19529. // The paper is divided to smaller cells, where each of them holds an information which
  19530. // elements belong to it. When we query whether a point is in an obstacle we don't need
  19531. // to go through all obstacles, we check only those in a particular cell.
  19532. var map = _.chain(graph.getElements())
  19533. // remove source and target element if required
  19534. .difference(excludedEnds)
  19535. // remove all elements whose type is listed in excludedTypes array
  19536. .reject(function(element) {
  19537. return _.contains(opt.excludeTypes, element.get('type'));
  19538. })
  19539. // change elements (models) to their bounding boxes
  19540. .invoke('getBBox')
  19541. // expand their boxes by specific padding
  19542. .invoke('moveAndExpand', opt.paddingBox)
  19543. // build the map
  19544. .foldl(function(res, bbox) {
  19545. var origin = bbox.origin().snapToGrid(mapGridSize);
  19546. var corner = bbox.corner().snapToGrid(mapGridSize);
  19547. for (var x = origin.x; x <= corner.x; x += mapGridSize) {
  19548. for (var y = origin.y; y <= corner.y; y += mapGridSize) {
  19549. var gridKey = x + '@' + y;
  19550. res[gridKey] = res[gridKey] || [];
  19551. res[gridKey].push(bbox);
  19552. }
  19553. }
  19554. return res;
  19555. }, {}).value();
  19556. // pathfinding
  19557. var newVertices = [];
  19558. var points = _.map(oldVertices, g.point);
  19559. var tailPoint = sourceBBox.center();
  19560. // find a route by concating all partial routes (routes need to go through the vertices)
  19561. // startElement -> vertex[1] -> ... -> vertex[n] -> endElement
  19562. for (var i = 0, len = points.length; i <= len; i++) {
  19563. var partialRoute = null;
  19564. var from = to || sourceBBox;
  19565. var to = points[i];
  19566. if (!to) {
  19567. to = targetBBox;
  19568. // 'to' is not a vertex. If the target is a point (i.e. it's not an element), we
  19569. // might use dragging route instead of main routing method if that is enabled.
  19570. var endingAtPoint = !this.model.get('source').id || !this.model.get('target').id;
  19571. if (endingAtPoint && _.isFunction(opt.draggingRoute)) {
  19572. // Make sure we passing points only (not rects).
  19573. var dragFrom = from instanceof g.rect ? from.center() : from;
  19574. partialRoute = opt.draggingRoute(dragFrom, to.origin(), opt);
  19575. }
  19576. }
  19577. // if partial route has not been calculated yet use the main routing method to find one
  19578. partialRoute = partialRoute || findRoute(from, to, map, opt);
  19579. var leadPoint = _.first(partialRoute);
  19580. if (leadPoint && leadPoint.equals(tailPoint)) {
  19581. // remove the first point if the previous partial route had the same point as last
  19582. partialRoute.shift();
  19583. }
  19584. tailPoint = _.last(partialRoute) || tailPoint;
  19585. newVertices = newVertices.concat(partialRoute);
  19586. };
  19587. // we might have to reverse the result if we swapped source and target at the beginning
  19588. return reverseRouting ? newVertices.reverse() : newVertices;
  19589. };
  19590. // public function
  19591. return function(vertices, opt, linkView) {
  19592. return router.call(linkView, vertices, _.extend({}, config, opt));
  19593. };
  19594. })();
  19595. joint.routers.metro = (function() {
  19596. if (!_.isFunction(joint.routers.manhattan)) {
  19597. throw('Metro requires the manhattan router.');
  19598. }
  19599. var config = {
  19600. // cost of a diagonal step (calculated if not defined).
  19601. diagonalCost: null,
  19602. // an array of directions to find next points on the route
  19603. directions: function() {
  19604. var step = this.step;
  19605. var diagonalCost = this.diagonalCost || Math.ceil(Math.sqrt(step * step << 1));
  19606. return [
  19607. { offsetX: step , offsetY: 0 , cost: step },
  19608. { offsetX: step , offsetY: step , cost: diagonalCost },
  19609. { offsetX: 0 , offsetY: step , cost: step },
  19610. { offsetX: -step , offsetY: step , cost: diagonalCost },
  19611. { offsetX: -step , offsetY: 0 , cost: step },
  19612. { offsetX: -step , offsetY: -step , cost: diagonalCost },
  19613. { offsetX: 0 , offsetY: -step , cost: step },
  19614. { offsetX: step , offsetY: -step , cost: diagonalCost }
  19615. ];
  19616. },
  19617. // a simple route used in situations, when main routing method fails
  19618. // (exceed loops, inaccessible).
  19619. fallbackRoute: function(from, to, opts) {
  19620. // Find a route which breaks by 45 degrees ignoring all obstacles.
  19621. var theta = from.theta(to);
  19622. var a = { x: to.x, y: from.y };
  19623. var b = { x: from.x, y: to.y };
  19624. if (theta % 180 > 90) {
  19625. var t = a;
  19626. a = b;
  19627. b = t;
  19628. }
  19629. var p1 = (theta % 90) < 45 ? a : b;
  19630. var l1 = g.line(from, p1);
  19631. var alpha = 90 * Math.ceil(theta / 90);
  19632. var p2 = g.point.fromPolar(l1.squaredLength(), g.toRad(alpha + 135), p1);
  19633. var l2 = g.line(to, p2);
  19634. var point = l1.intersection(l2);
  19635. return point ? [point.round(), to] : [to];
  19636. }
  19637. };
  19638. // public function
  19639. return function(vertices, opts, linkView) {
  19640. return joint.routers.manhattan(vertices, _.extend({}, config, opts), linkView);
  19641. };
  19642. })();
  19643. joint.connectors.normal = function(sourcePoint, targetPoint, vertices) {
  19644. // Construct the `d` attribute of the `<path>` element.
  19645. var d = ['M', sourcePoint.x, sourcePoint.y];
  19646. _.each(vertices, function(vertex) {
  19647. d.push(vertex.x, vertex.y);
  19648. });
  19649. d.push(targetPoint.x, targetPoint.y);
  19650. return d.join(' ');
  19651. };
  19652. joint.connectors.rounded = function(sourcePoint, targetPoint, vertices, opts) {
  19653. var offset = opts.radius || 10;
  19654. var c1, c2, d1, d2, prev, next;
  19655. // Construct the `d` attribute of the `<path>` element.
  19656. var d = ['M', sourcePoint.x, sourcePoint.y];
  19657. _.each(vertices, function(vertex, index) {
  19658. // the closest vertices
  19659. prev = vertices[index-1] || sourcePoint;
  19660. next = vertices[index+1] || targetPoint;
  19661. // a half distance to the closest vertex
  19662. d1 = d2 || g.point(vertex).distance(prev) / 2;
  19663. d2 = g.point(vertex).distance(next) / 2;
  19664. // control points
  19665. c1 = g.point(vertex).move(prev, -Math.min(offset, d1)).round();
  19666. c2 = g.point(vertex).move(next, -Math.min(offset, d2)).round();
  19667. d.push(c1.x, c1.y, 'S', vertex.x, vertex.y, c2.x, c2.y, 'L');
  19668. });
  19669. d.push(targetPoint.x, targetPoint.y);
  19670. return d.join(' ');
  19671. };
  19672. joint.connectors.smooth = function(sourcePoint, targetPoint, vertices) {
  19673. var d;
  19674. if (vertices.length) {
  19675. d = g.bezier.curveThroughPoints([sourcePoint].concat(vertices).concat([targetPoint]));
  19676. } else {
  19677. // if we have no vertices use a default cubic bezier curve, cubic bezier requires
  19678. // two control points. The two control points are both defined with X as mid way
  19679. // between the source and target points. SourceControlPoint Y is equal to sourcePoint Y
  19680. // and targetControlPointY being equal to targetPointY. Handle situation were
  19681. // sourcePointX is greater or less then targetPointX.
  19682. var controlPointX = (sourcePoint.x < targetPoint.x)
  19683. ? targetPoint.x - ((targetPoint.x - sourcePoint.x) / 2)
  19684. : sourcePoint.x - ((sourcePoint.x - targetPoint.x) / 2);
  19685. d = [
  19686. 'M', sourcePoint.x, sourcePoint.y,
  19687. 'C', controlPointX, sourcePoint.y, controlPointX, targetPoint.y,
  19688. targetPoint.x, targetPoint.y
  19689. ];
  19690. }
  19691. return d.join(' ');
  19692. };